NAT, файрволы, STUN, TURN, ICE: как WebRTC реально добирается до телефона

Автор: Николай СапуновОбновлено: август 202622 мин чтения
Содержание статьи +

Опубликовано: 2026-05-20 · Время чтения: 22 мин · Автор: Николай Сапунов, CEO Фора Софт

Последняя сверка: 2026-05-20 со стандартами: IETF RFC 8489 (STUN, февраль 2020), RFC 8656 (TURN, февраль 2020), RFC 8445 (ICE, июль 2018), RFC 8838 (Trickle ICE, январь 2021), RFC 4787 (NAT Behavioral Requirements for Unicast UDP, январь 2007), RFC 5780 (NAT Behaviour Discovery Using STUN, май 2010), RFC 7675 (STUN Usage for Consent Freshness, октябрь 2015), RFC 8826 (Security Considerations for WebRTC, февраль 2021), W3C WebRTC 1.0 Recommendation (март 2023) и отчётами WebRTC-статистики Chrome / Firefox / Safari за Q1–Q2 2026.

TL;DR

WebRTC-звонок между двумя телефонами почти никогда не идёт напрямую – каждый телефон находится за домашним роутером, корпоративным файрволом или carrier-grade NAT мобильного оператора, которые скрывают реальный IP-адрес от открытого интернета. Четыре ключевых компонента, решающих эту задачу, – это NAT (устройство на каждом роутере, переписывающее сетевые адреса), STUN (простой протокол из RFC 8489, с помощью которого устройство узнаёт, как его адрес виден извне), TURN (релейный сервер из RFC 8656, пересылающий медиа, когда прямой путь недоступен) и ICE (алгоритм из RFC 8445, который одновременно проверяет все возможные маршруты и выбирает рабочий). В реальных условиях примерно 15–20 % потребительских WebRTC-сессий требуют TURN для установления соединения, а эта доля достигает 100 % в сценариях с ИИ-голосовыми агентами и большинством IoT-устройств – ведь у одной из сторон вообще нет публичного выхода в интернет. Если этот слой работает неправильно, продукт будет сломан именно в тех сетях, которые ваши клиенты используют чаще всего: корпоративные офисы, университетский Wi-Fi, мобильные данные за carrier-grade NAT и любые сети с симметричным NAT в середине.

Зачем это понимать

Если вы разрабатываете продукт на базе WebRTC – приложение для видеоконференций, телемедицинские консультации, браузерный просмотр видеонаблюдения, виджет поддержки в чате или ИИ-голосового агента – то NAT traversal остаётся самой частой причиной, по которой звонок не устанавливается. Сигнализация прошла, камеры включены, SDP-обмен завершён, пользователь видит «соединяемся…» – и дальше тишина. Почти каждый такой сбой связан с ICE, STUN или TURN. Продакт-менеджер или основатель, не разбирающийся в этом уровне, в итоге платит вендору вроде Twilio или Daily.co за задачу, для которой существуют open-source решения, или запускает TURN-кластер, который незаметно съедает шестизначные суммы в год на egress AWS, потому что трафик никто не перенаправил через дешёвый транзит. Эта статья объясняет, что делает каждый компонент, когда он нужен, сколько стоит и какие практические дефолты должен использовать стриминговый или real-time-продукт в 2026 году.

Что такое NAT, в одном абзаце

Network Address Translation – NAT – это способ, позволяющий всем устройствам в доме использовать один публичный IP-адрес. Ваш ноутбук, телефон, телевизор и термостат имеют приватные IP-адреса во внутренней сети (192.168.x.x или 10.x.x.x), а у роутера – один публичный адрес (203.0.113.45). Когда ноутбук отправляет пакет за пределы сети, роутер заменяет поле source с приватного адреса ноутбука на свой публичный адрес и сохраняет это соответствие в таблице. Когда приходит ответ, роутер по этой таблице возвращает поле destination обратно – с публичного на приватный адрес – и передаёт пакет ноутбуку. Этот механизм описан в RFC 4787 от IETF (январь 2007 года) и стал причиной того, что публичный интернет не исчерпал IPv4-адреса в 2008 году, как предсказывали все прогнозные модели. Платой за это стало то, что устройство за NAT становится недоступным извне, пока что-то изнутри не установит соединение наружу. Для исходящего HTTP-запроса в Google это не имеет значения. А вот для входящего WebRTC-звонка с чужого телефона – это и есть главная проблема.

Четыре сорта NAT и тот, который портит день

Разные NAT-устройства по-разному обрабатывают ситуацию, когда одно устройство отправляет пакеты наружу, а другое пытается ответить. Классическая классификация была предложена в RFC 3489 (март 2003) – первой спецификации STUN – и хотя её позже заменил RFC 8489, эти четыре типа до сих пор используются в индустрии для описания NAT в 2026 году.

Первый – Full-Cone NAT. Как только устройство за NAT отправляет пакет с внутренней пары (X, x) на любой внешний адрес, NAT создаёт маппинг на внешнюю пару (X', x'), и любой внешний хост в интернете может отправлять пакеты на (X', x') – они дойдут до (X, x). Самый разрешающий тип. Самый удобный для WebRTC.

Второй – Address-Restricted Cone NAT. Маппинг создаётся аналогично, но через него могут отвечать только те внешние хосты, которым устройство уже отправляло пакеты (по IP-адресу, без проверки порта). Большинство домашних роутеров работают именно так.

Третий – Port-Restricted Cone NAT. То же самое, но внешний хост должен совпадать и по IP-адресу, и по исходному порту, с которого устройство к нему обращалось. Для WebRTC проблема остаётся решаемой: STUN-обмен сообщает каждой стороне, что увидит другая, и они одновременно пробивают парные «дырки».

Четвёртый – Symmetric NAT. NAT назначает разный внешний порт для каждого уникального назначения. Маппинг, который увидел STUN-сервер, – (X', x'_stun) – не совпадает с тем, что нужен пиру, потому что пир находится по другому адресу и получает другой порт (X', x'_peer). STUN-кандидат в этом случае бесполезен. Два пира не могут установить соединение без посредника.

Современная более точная терминология из RFC 4787 делит поведение NAT на два независимых свойства: поведение маппинга (как NAT выбирает внешний порт – endpoint-Independent, address-Dependent, address-and-Port-Dependent) и поведение фильтрации (какие внешние хосты могут установить соединение через маппинг). NAT с endpoint-Independent mapping и endpoint-Independent filtering – это то, что обычно называют «Full-Cone»; NAT с address-and-Port-Dependent mapping – это «Symmetric». IETF предпочитает термины RFC 4787, потому что они точны; стриминговая индустрия по-прежнему использует традиционную четвёрку названий, потому что все понимают, о чём речь.

Плохая новость для WebRTC: значительная доля carrier-grade NAT (CGNAT) у мобильных операторов и заметная часть корпоративных NAT ведут себя как симметричные. Хорошая новость: у ICE есть запасной путь – TURN, который справляется с этой ситуацией. Вся архитектура ниже создана именно для того, чтобы симметричный NAT не прерывал звонок.

Рис. 1. Как NAT переписывает пакет при выходе и при возвращении, а также четыре классические разновидности NAT, определяющие, смогут ли два устройства за разными NAT установить прямое соединение между собой.

STUN – устройство определяет свой публичный адрес

STUN – Session Traversal Utilities for NAT – самый маленький из четырёх протоколов. Его задача проста: устройство спрашивает публичный STUN-сервер: «Как мой адрес выглядит снаружи?», а сервер отвечает публичным IP-адресом и портом, которые он увидел в запросе. Текущая спецификация – RFC 8489, опубликованная в феврале 2020 года, заменила RFC 5389 от 2008 года. На уровне передачи данных это 20-байтный фиксированный заголовок плюс пары «атрибут-значение», передаваемые поверх UDP (по умолчанию порт 3478), TCP (порт 3478) или TLS поверх TCP (порт 5349).

Обмен – один round trip. Клиент посылает Binding Request STUN-серверу. Сервер видит пакет, приходящий с переписанной NAT-ом пары (X', x'), и копирует её в атрибут XOR-MAPPED-ADDRESS в Binding Response. Клиент теперь знает свой публичный адрес – по крайней мере тот, который этот конкретный NAT даёт для этого конкретного destination. Это называется server-reflexive candidate, сокращённо srflx.

В этой формулировке важны две детали. Первая – server-reflexive: адрес – это отражение, которое увидел сервер, а не абсолютное свойство устройства. Симметричный NAT выдаст разные reflexive-адреса для каждого destination – именно поэтому STUN в одиночку не справляется с симметричным NAT. Вторая – candidate: адрес – один из нескольких возможных маршрутов для входящего пакета, и ICE будет ранжировать его среди других (host, relay) и использовать в порядке приоритета.

STUN-серверы по замыслу stateless и бесплатны. Google предоставляет stun.l.google.com:19302 как публичный бесплатный STUN-сервер, как и Cloudflare (stun.cloudflare.com:3478) с Mozilla. Собственный STUN-сервер обходится почти бесплатно – coturn на виртуальной машине за $5 справляется с десятками тысяч запросов в секунду – и большинство команд всё же устанавливают свой, чтобы не зависеть от доступности сторонних сервисов.

STUN не передаёт медиа. STUN не аутентифицирует пиров. STUN не работает при смене сети. Это однозапросно-одноответный зонд, чья единственная задача – сообщить устройству, как оно выглядит снаружи. Протоколы, выполняющие основную работу – TURN и ICE – построены на основе формата сообщений STUN.

TURN – релей-сервер для случаев, когда другие решения не работают

TURN – Traversal Using Relays around NAT – это резервный путь, когда прямая peer-to-peer-связь невозможна. Текущая спецификация – RFC 8656, вышедшая в феврале 2020 года, заменяет оригинальный RFC TURN (5766, апрель 2010) и его дополнение для IPv6 (RFC 6156, апрель 2011). TURN расширяет STUN: TURN-сервер представляет собой STUN-сервер с дополнительной возможностью выступать в роли реле для медиа.

Механика проста. WebRTC-клиент подключается к TURN-серверу и запрашивает выделение публичного адреса и порта – так называемого «allocation». TURN-сервер отвечает публичной парой (T, t), зарезервированной за этим клиентом. Всё, что поступает на (T, t) из интернета, пересылается по уже установленному соединению клиенту. Всё, что клиент хочет отправить пиру, он направляет через TURN-сервер, который пересылает данные с (T, t) на адрес пира. «Allocation» остаётся активным, пока клиент его обновляет (по умолчанию – 600 секунд; клиент обновляет его каждые 5 минут).

Из этой механики следуют два важных факта. Во-первых, каждый байт медиа проходит через TURN-сервер дважды: один раз от клиента A к TURN, второй – от TURN к клиенту B. Для звонка на 2 Мбит/с TURN-сервер обрабатывает 4 Мбит/с трафика. При 1000 одновременных релеируемых звонках это составляет 4 Гбит/с в каждом направлении. Поэтому трафик через TURN – главная статья расходов на инфраструктуру WebRTC. Во-вторых, задержка, вносимая TURN, равна удвоенному round-trip времени между клиентом и сервером: обычно 20–60 мс при хорошо расположенном кластере и более 100 мс, если сервер находится на другом континенте.

TURN-серверы требуют аутентификации. RFC 8656 описывает схему с короткоживущими учётками: application-сервер выдаёт клиенту username (обычно Unix-timestamp плюс идентификатор пользователя) и пароль (HMAC-SHA1 от username с shared secret, который известен только app-серверу и TURN-серверу). TURN-сервер проверяет HMAC по своему shared secret и принимает клиента, никогда не видя его user-id. Это даёт stateless TURN-кластер по части аккаунтов и защищает от злоупотреблений: утёкшая учётка истекает через минуты.

TURN слушает UDP/3478, TCP/348 и TLS поверх TCP на порту 5349. Большинство продакшн-инсталляций также открывают TLS на порту 443 – этот вариант URL помечается как «turns», поскольку 443 выглядит как HTTPS для корпоративных фаерволов, которые блокируют всё остальное. Итог: TURN поверх TLS на 443 – универсальный резервный вариант, который проходит через практически любую сеть. Цена – соединение идёт по TCP (что плохо для задержки), вместо UDP, но звонок с задержкой 200 мс лучше, чем звонок, который вообще не установился.

Продакшн-реальность TURN в 2026 году выглядит так. Coturn (open source, изначально написан Олегом Москаленко) – стандарт, к которому тянутся все. eturnal (от ProcessOne, той же команды, что и ejabberd) – более активно поддерживаемый форк, на который часть команд начала переходить. Pion TURN – чистая реализация на Go, популярная в Kubernetes-нативных развертываниях. Облачные провайдеры TURN – Twilio, Cloudflare Calls, Daily.co, Xirsys, Subspace – используют тот же протокол, берут плату за гигабайты переданного трафика и добавляют свой anycast-роутинг.

Рис. 2. TURN как медиа-релей. Каждый пакет между двумя пирами проходит через TURN-сервер дважды – именно поэтому трафик через TURN доминирует в бюджете WebRTC-инфраструктуры.

ICE – алгоритм, выбирающий путь

ICE – Interactive Connectivity Establishment – это алгоритм, объединяющий STUN и TURN. Текущая спецификация – RFC 8445, июль 2018 года, заменяет RFC 5245 от 2010 года. ICE выполняет три задачи: собирает все возможные адреса, по которым каждый пир может быть доступен, формирует пары из каждого локального адреса с каждым удалённым – так называемые кандидатные пары – и тестирует каждую пару, пока не найдёт рабочий маршрут. Суть ICE заключается не в том, чтобы жёстко задать одну стратегию обхода NAT как единственно правильную, а в том, чтобы параллельно проверять все правдоподобные пути и выбрать тот, что сработает.

Кандидат бывает четырёх видов. Host candidate – это реальный сетевой адрес устройства: интерфейс Wi-Fi, 5G или проводной Ethernet. Server-reflexive candidate – публичный адрес, полученный от STUN-сервера (тот самый srflx выше). Peer-reflexive candidate – публичный адрес, выявленный в ходе проверки соединения: STUN-зонд от пира показал устройству адрес, который оно ранее не встречало – такое происходит, когда NAT-маппинг создаётся непосредственно во время звонка. Relay candidate – это адрес транспорта, выделенный TURN-сервером.

Проверка соединения использует то же сообщение STUN Binding Request, но уже в режиме peer-to-peer, а не клиент-сервер. Каждая пара тестируется в порядке приоритета: формула ICE сначала учитывает host, затем server-reflexive, далее peer-reflexive и в последнюю очередь relay. Пара считается «валидной», когда одна сторона отправляет Binding Request другой и получает Binding Response с ожидаемого адреса. Первая валидная пара помещается в слот «selected pair», после чего соединение устанавливается; ICE продолжает в фоновом режиме тестировать остальные пары и может переключиться на более подходящую, если такая будет найдена.

После выбора пары тот же STUN-обмен используется для поддержания активности соединения. RFC 7675 описывает протокол consent freshness: каждые 15 секунд каждая сторона отправляет Binding Request по выбранной паре и ожидает ответ в течение 30 секунд. Если ответа не поступает, пара считается мёртвой, и ICE запускает рестарт. Именно этот механизм позволяет пережить смену сети – новый путь пересогласовывается прозрачно.

Trickle ICE – отдельная спецификация в RFC 8838 (январь 2021) – это оптимизация, которой по умолчанию пользуется почти любой современный WebRTC-стек. Вместо того чтобы ждать, пока соберутся все кандидаты, и только потом отправлять их пиру разом, каждая сторона передаёт кандидатов в сигнальный канал по мере их обнаружения. Обе стороны могут начать проверку соединения на ранних кандидатах, пока поздние ещё находятся в процессе сбора. Для большинства звонков это сокращает время до установления соединения с 2–3 секунд до менее чем 500 миллисекунд.

Рис. 3. Сбор ICE-кандидатов и connectivity check. Каждый пир параллельно собирает host-, server-reflexive и relay-кандидаты, отправляет их по сигнальному каналу через Trickle ICE сразу после получения, затем сопоставляет каждый локальный кандидат с каждым удалённым, сортирует пары по приоритету и отправляет STUN-запросы на проверку, пока не найдёт рабочий маршрут с наивысшим приоритетом.

Сценарий end-to-end – что происходит, когда вы нажимаете «войти»

Пользователь нажимает «войти» в браузере. Браузер открывает камеру, микрофон, создаёт RTCPeerConnection. Application-сервер заранее отдал браузеру список ICE-серверов – URL STUN и URL TURN с короткоживущими учётками. Браузер запускает ICE.

Параллельно браузер выполняет пять действий. Он перечисляет все сетевые интерфейсы – Wi-Fi, 5G, Ethernet – и для каждого создаёт кандидат-хост. Отправляет STUN-запрос на привязку (Binding Request) на STUN-сервер с каждого интерфейса и ожидает получения server-reflexive кандидата. Отправляет запрос на выделение ресурса (Allocate request) на TURN-сервер с каждого интерфейса и ждёт relay-кандидата. Генерирует SDP-офер, в котором перечислены все собранные на данный момент кандидаты. И передаёт этот офер через сигнальный канал приложения – например, WebSocket, HTTP long-poll или gRPC (транспорт сигнализации выходит за рамки ICE) – второму участнику соединения.

Другой пир выполняет симметричную операцию: принимает offer, формирует SDP answer со своим списком кандидатов и отправляет answer обратно. Обе стороны в процессе trickle-передачи постепенно передают дополнительные кандидаты по мере их обнаружения. Каждая сторона сопоставляет каждый локальный кандидат с каждым удалённым, вычисляет приоритет каждой пары по формуле из RFC 8445 §6.1.2.3 (по сути 2^32 × min(G,D) + 2 × max(G,D) + (G > D ? 1 : 0)), сортирует пары по убыванию приоритета и начинает отправлять STUN Binding Requests на каждую пару последовательно, с небольшим интервалом (Ta, по умолчанию 50 мс).

Пара срабатывает, когда Binding Request получает Binding Response с ожидаемым transaction ID и подтверждением аутентификации. Первая сработавшая пара становится selected pair, и начинается передача медиа – пользователь слышит собеседника. ICE ещё несколько секунд продолжает тестировать остальные пары; если появляется более качественная пара (например, host-host всегда предпочтительнее, чем host-relay), медиа переключается на неё без прерывания.

Суммарное время от «клика» до «первого принятого кадра» на типичном звонке «дом–дом» в 2026 году составляет около 300–600 мс. На звонке «дом–корпоративный файрвол», где используется только кандидат TURN через TLS-443, – около 800–1200 мс. Почти весь разброс обусловлен временем, необходимым для обнаружения, что более дешёвые кандидаты не работают.

Рабочий пример – расчёт TURN-трафика для продукта на 1000 мест

Основатель проектирует инфраструктуру для продукта видеовстреч с учётом 1000 одновременных звонков один-на-один в пиковую нагрузку. Средний битрейт одного звонка: 1,5 Мбит/с на видео и 50 кбит/с на аудио в одну сторону, то есть около 1,6 Мбит/с × 2 направления = 3,2 Мбит/с на соединение. По отраслевым данным, доля сессий, требующих TURN-ретрансляции в потребительском сегменте, составляет 15–20 %; возьмём консервативную оценку – 20 %.

Шаг 1: сколько звонков проходит через TURN? 1000 × 20 % = 200 релеящихся.

Шаг 2: TURN-трафик на один релеирующий звонок. Полный медиа-стрим проходит через TURN-сервер дважды – по одному разу в каждом направлении. Следовательно, трафик через TURN составляет 3,2 Мбит/с × 2 = 6,4 Мбит/с на звонок. (Некоторые источники учитывают только одно направление, ссылаясь на то, что TURN находится «посередине» – это ошибка. На самом деле TURN обрабатывает входящий трафик от одного участника и исходящий – к другому для каждого байта данных, поэтому оба направления должны учитываться.)

Шаг 3: суммарная пропускная способность TURN. 200 × 6,4 Мбит/с = 1280 Мбит/с = 1,28 Гбит/с в пиковом режиме sustained.

Шаг 4: месячный egress. 1,28 Гбит/с × 86 400 с/день × 30 дней × 12,5 % коэффициента busy-hour-to-average (эвристика для видеопродуктов) ≈ 410 ТБ/месяц egress.

Шаг 5: цена на гиперскейлере. Egress AWS EC2 в 2026 году – около $0,085 за ГБ на первые 10 ТБ, снижается до $0,05 за ГБ при объёме свыше 150 ТБ; средневзвешенная стоимость на 410 ТБ составляет примерно $0,054 за ГБ. 410 ТБ × $0,054/ГБ ≈ $22 000 в месяц только за TURN egress.

Шаг 6: где живёт экономия. Тот же TURN на колокейшен-кластере bare-metal с 95-перцентилем транзита по $0,50–$1,00 за Мбит/с в месяц и пиком 1,28 Гбит/с ≈ $700–$1400/месяц за транзит. 20-кратный разрыв между гиперскейлерным egress и колокейшен-транзитом – причина, по которой любой WebRTC-продукт значимого масштаба либо размещает свой TURN-кластер на bare-metal, либо договаривается с TURN-провайдером, чьё ценообразование соответствует экономике bare-metal (Cloudflare Calls, Daily.co, Subspace).

Если продукт – AI voice-агент или односторонний IoT-сценарий, где 100 % трафика обязано проходить через TURN (у одной из сторон принципиально нет публичного IP-адреса), та же арифметика даёт в 5 раз больше трафика и в 5 раз больше расходов. Именно такая модель развертывания в 2025–2026 годах превратила TURN-трафик в экзистенциальную статью расходов для AI voice-продуктов.

Типичные ошибки

Ошибка 1: полагаться на STUN-only на симметричном NAT. Многие демки используют только STUN. Они работают отлично – до того момента, как в звонок зайдёт первый пользователь с мобильного оператора (а большинство держат симметричный CGNAT), и связь молча сломается. Всегда включайте хотя бы один TURN-сервер в конфигурацию ICE. Fallback – это весь смысл архитектуры.

Ошибка 2: TURN только по UDP. Корпоративные файрволы часто блокируют UDP и перенаправляют весь трафик через TCP/443. TURN-кандидат turn:host:3478?transport=udp в такой сети становится бесполезным. Всегда настраивайте и turns:host:443?transport=tcp (TLS поверх TCP на 443). Браузер сам выберет наиболее эффективный рабочий вариант.

Ошибка 3: долгоживущие TURN-учётки. Некоторые туториалы вендоров до сих пор демонстрируют использование TURN-учётных данных, встроенных прямо в клиентский JavaScript. Любой, кто откроет devtools, сможет извлечь их и годами использовать ваш TURN-кластер как бесплатный egress. Всегда генерируйте короткоживущие учётные записи на стороне сервера, подписанные shared secret и привязанные к конкретному звонку. Формат HMAC-SHA1 описан в RFC 8656 §9.2.

Ошибка 4: один TURN-сервер на один континент. Задержка, которую добавляет TURN, равна удвоенному RTT между клиентом и TURN-сервером. Звонок между двумя пользователями в Сан-Паулу через TURN-сервер в Вирджинии добавляет 240 мс задержки на пустом месте. Деплойте TURN географически рядом с пользователями – хотя бы по одному кластеру на крупный континент, с anycast или geo-DNS впереди.

Ошибка 5: забыть про актуальность согласия (consent freshness). RFC 7675 требует поддерживать соединение с помощью STUN-запроса на привязку каждые 15 секунд. Некоторые самописные реализации этого не делают – всё работает нормально, пока NAT-маппинг не истечёт по таймауту (большинство домашних роутеров освобождают UDP-маппинги через 30–60 секунд бездействия), и звонок внезапно обрывается посреди разговора без какой-либо диагностики.

Где здесь Фора Софт

Фора Софт разрабатывает WebRTC- и конференц-решения с 2005 года: реализовано более 250 проектов в сфере видеоконференций, OTT, телемедицины, e-learning, видеонаблюдения и AR/VR. NAT traversal – это та часть WebRTC, которую большинство команд недооценивают: SDP offer/answer описан в каждом туториале, камеры и микрофоны хорошо работают в браузере, SFU-решения (mediasoup, Janus, LiveKit, Pion) понятны и доступны. Разница между продуктом, который работает в демо, и продуктом, который стабильно функционирует у бразильского клиента на корпоративном офисном Wi-Fi, – в TURN-кластере: его расположение, учёт пользователей, наблюдаемость и контроль затрат. Мы развертываем TURN-кластеры для клиентов на выделенном bare-metal и в гиперскейлерах, обеспечиваем атрибуцию стоимости на уровне каждого вызова и интегрируем их с мультирегиональными SFU-инсталляциями там, где это требует топология звонка.

Главное

  • NAT позволяет всем устройствам в домашней сети использовать один внешний IP-адрес; именно это делает прямой peer-to-peer-путь в WebRTC почти невозможным.
  • STUN (RFC 8489) помогает устройству определить свой публичный IP-адрес; решение дешёвое, stateless и бесплатное.
  • TURN (RFC 8656) пересылает медиапоток, когда прямой путь недоступен; дорогое, stateful-решение, составляющее основную статью расходов в WebRTC.
  • ICE (RFC 8445) собирает кандидатов для соединения, сопоставляет их и проводит STUN-проверки связности; побеждает пара с наивысшим приоритетом, которая успешно прошла проверку.
  • Всегда развертывайте TURN, всегда открывайте TLS поверх UDP и TLS поверх TCP на порту 443, всегда выдавайте учётные записи с коротким сроком действия.
  • Заложите 15–20 % трафика через TURN-релеи для потребительских продуктов и 100 % – для голосовых решений на основе ИИ и большинства IoT-устройств.

Что почитать дальше

Строите такую систему?

Подберём параметры кодирования под ваш контент и посчитаем стоимость доставки до старта разработки.