04-02-04 NAT, STUN, TURN и ICE

Проблема двусторонней связи через NAT
Одной из ключевых инженерных задач при построении систем видеосвязи является обеспечение прямой двусторонней связи между участниками, находящимися за различными сетевыми брандмауэрами и маршрутизаторами. В отличие от одностороннего потокового видео (например, трансляции с камеры через RTSP или HLS), где клиент лишь получает данные от сервера, видеосвязь требует двустороннего обмена медиапотоками в режиме реального времени — каждый участник одновременно и отправляет, и принимает аудио и видео.
Однако в большинстве домашних и корпоративных сетей устройства подключены к интернету не напрямую, а через NAT (Network Address Translation — трансляция сетевых адресов). Это означает, что устройства используют приватные IP-адреса (например, 192.168.1.10), которые не видны из глобальной сети интернет. Внешний трафик проходит через маршрутизатор, который выполняет преобразование: он заменяет внутренний IP-адрес и порт на свой публичный IP-адрес и временный порт, чтобы направить ответ обратно нужному устройству.
Почему это мешает видеосвязи?
Проблема в том, что устройство за NAT не знает своего внешнего IP-адреса и порта, через которые его "видят" извне. Более того, маршрутизатор динамически сопоставляет внутренние и внешние порты, и это сопоставление действует только для исходящих соединений. Если попытаться установить входящее соединение — например, чтобы второй участник видеозвонка отправил видео напрямую первому — маршрутизатор просто отбросит такой пакет, так как не будет знать, куда его направить.
Таким образом, прямое P2P-соединение (peer-to-peer) между двумя устройствами за NAT невозможно без дополнительных механизмов.
STUN: как узнать свой внешний адрес
Для решения этой проблемы используется протокол STUN (Session Traversal Utilities for NAT).
Как работает STUN?
STUN позволяет устройству определить свой внешний IP-адрес и порт, через которые оно доступно из интернета. Для этого клиент отправляет запрос на публичный STUN-сервер, размещённый в глобальной сети. Сервер, получив пакет, смотрит на его источник — то есть на тот IP и порт, под которым клиент "предстал" извне — и отправляет эту информацию обратно.
Например:
- Устройство A с внутренним адресом
192.168.1.10:50000отправляет запрос наstun.example.com:3478. - Маршрутизатор транслирует адрес:
198.51.100.1:54321. - STUN-сервер отвечает: "Вы подключились с адреса
198.51.100.1:54321".
Теперь устройство A знает свой внешний адрес, который может передать собеседнику для установления прямого соединения.
Кандидаты в STUN: server-reflexive адрес
Полученный таким образом адрес называется server-reflexive candidate (отражённый сервером кандидат). Он — один из возможных способов, которым участник может быть достигнут.
Однако STUN не всегда работает. В случае так называемых symmetric NAT (симметричных NAT), маршрутизатор присваивает разные внешние порты для соединений с разными внешними серверами. То есть, если устройство A сначала общалось с stun.example.com, а потом попытается принять соединение от peer.example.com, маршрутизатор может выделить совершенно другой порт, и предыдущий внешний адрес станет недействительным.
В таких ситуациях прямое P2P-соединение невозможно — и здесь на помощь приходит TURN.
TURN: ретрансляция через сервер
TURN (Traversal Using Relays around NAT) — это протокол, который решает проблему, когда прямое соединение между участниками невозможно даже с помощью STUN.
Как работает TURN?
Вместо попыток установить прямое соединение, оба участника подключаются к публичному TURN-серверу и отправляют через него свой медиатрафик. Сервер выступает в роли ретранслятора (relay): он принимает пакеты от одного участника и пересылает их другому.
Например:
- Устройство A отправляет видео на TURN-сервер.
- TURN-сервер пересылает это видео устройству B.
- Устройство B отправляет видео на тот же сервер — и оно доставляется устройству A.
Таким образом, даже если оба участника находятся за строгими NAT, соединение всё равно устанавливается — но через посредника.
Плюсы и минусы TURN
| Преимущество | Описание |
|---|---|
| Гарантированное соединение | Работает при любых типах NAT и файрволах. |
| Надёжность | Не зависит от настроек локальной сети. |
| Недостаток | Описание |
|---|---|
| Увеличение задержки (latency) | Трафик проходит через дополнительный узел. |
| Нагрузка на сервер | TURN-сервер должен пропускать весь медиатрафик, что требует высокой пропускной способности и вычислительных ресурсов. |
| Стоимость | Обслуживание TURN-инфраструктуры может быть дорогим при большом числе пользователей. |
Из-за этих недостатков TURN используется только в крайнем случае, когда прямое соединение невозможно.
ICE: алгоритм выбора наилучшего пути
Для автоматического выбора наилучшего способа установления соединения применяется ICE (Interactive Connectivity Establishment) — это алгоритм, а не протокол. Он координирует работу STUN, TURN и локальных соединений, чтобы найти самый эффективный путь для обмена медиаданными.
Как работает ICE?
ICE проходит через несколько этапов:
-
Сбор кандидатов (candidates)
Каждое устройство собирает все возможные способы, которыми его можно достичь:- Host candidate — локальный IP и порт (например,
192.168.1.10:50000). - Server-reflexive candidate — внешний адрес, полученный через STUN (например,
198.51.100.1:54321). - Relay candidate — адрес на TURN-сервере, через который можно принимать трафик (например,
203.0.113.5:44567).
- Host candidate — локальный IP и порт (например,
-
Обмен кандидатами через сигналинг
Устройства обмениваются списками своих кандидатов с помощью сигнального канала (например, через WebSocket в WebRTC или в теле SIP-сообщений). -
Проверка соединений (connectivity checks)
ICE начинает последовательно проверять все возможные пары кандидатов: например, "может ли устройство A через свой host-адрес достичь устройства B через его server-reflexive адрес?" Для этого используются STUN-пакеты проверки связности. -
Выбор наилучшего пути
Как только находится работающее соединение, оно используется для передачи медиа. При этом ICE продолжает проверять другие пары, чтобы найти оптимальный маршрут — с наименьшей задержкой, достаточной пропускной способностью и минимальным числом промежуточных узлов.Предпочтение всегда отдаётся:
- Прямому P2P-соединению (host-to-host),
- Затем — через STUN (reflexive),
- И только в крайнем случае — через TURN (relay).
Пример работы ICE
Представим, что два пользователя запускают видеозвонок в браузере:
- Каждый браузер запускает ICE-агент.
- Агент определяет:
- Локальный адрес (host),
- Внешний адрес через STUN (reflexive),
- Адрес на TURN-сервере (relay).
- Через сигнальный сервер (например, WebSocket) они обмениваются SDP-описанием сессии и списками кандидатов.
- ICE начинает проверку: сначала пытается соединиться напрямую (host-to-host) — не работает (оба за NAT).
- Затем проверяет: host-to-reflexive — возможно, у одного из пользователей открытый IP.
- Если и это не работает — пробует соединение через TURN.
- Как только одно из соединений работает, медиапоток (аудио и видео) начинает передаваться по этому пути.
Почему ICE критически важен в WebRTC и SIP?
ICE — это фундаментальный механизм, без которого современные системы видеосвязи не могут работать в реальных сетях.
В WebRTC
WebRTC по умолчанию использует ICE для установления P2P-соединения. Браузер автоматически:
- Запускает сбор кандидатов,
- Обменивается ими через разработанный разработчиком сигнальный канал,
- Выполняет проверки и выбирает маршрут.
Если ICE не настроен правильно (например, не указаны STUN/TURN-серверы), вызов может успешно начаться, но медиапоток так и не появится — пользователь слышит гудки, но нет звука и изображения.
В SIP
Хотя SIP изначально разрабатывался для телефонии, в современных реализациях (особенно с мобильными клиентами и софтфонами) он также сталкивается с NAT. Для решения этой проблемы SIP-клиенты используют ICE в связке с SDP:
- В SDP-описании сессии передаются не только кодеки и порты, но и кандидаты ICE.
- Серверы и клиенты выполняют те же проверки, что и в WebRTC.
Это позволяет интегрировать SIP-устройства в сложные сетевые среды и обеспечивать надёжную доставку медиа.
Диагностика проблем: когда вызов есть, а звука — нет
Одна из самых частых проблем в видеосвязи — сигнальное соединение установлено, но медиапоток отсутствует. Это почти всегда связано с сбоями в работе ICE.
Возможные причины:
- Нет доступа к STUN/TURN-серверам — например, они заблокированы файрволом.
- Неправильная конфигурация TURN — сервер не принимает соединения или не авторизует клиента.
- Слишком строгий NAT или файрвол — блокирует UDP-трафик, необходимый для RTP и STUN.
- Отсутствие резервных кандидатов — если нет TURN, а STUN не сработал, соединение не устанавливается.
Что проверять?
- Логи сигнализации — есть ли в SDP-описании кандидаты ICE?
- Сетевой трафик (Wireshark) — идут ли STUN-запросы? Есть ли ответы?
- Использование TURN — если соединение работает только через ретранслятор, это указывает на сложную NAT-среду.
- Задержка и потери в RTP/RTCP — если медиа идёт, но с артефактами, возможно, канал перегружен, особенно при использовании TURN.
Заключение
Проблема прохождения через NAT и файрволы — одна из самых сложных в построении систем видеосвязи. Без механизмов STUN, TURN и ICE невозможно обеспечить стабильную и надёжную работу P2P-соединений в реальных условиях.
- STUN помогает узнать внешний адрес.
- TURN обеспечивает резервный путь через сервер.
- ICE координирует всё это, выбирая наилучший маршрут.
Понимание этих протоколов и алгоритмов критически важно для:
- проектирования систем видеосвязи,
- диагностики сбоев,
- интеграции с другими медиапротоколами (например, через шлюзы),
- настройки инфраструктуры (брандмауэры, QoS, серверы).