TURN

TURN (Traversal Using Relays around NAT, RFC 8656) — сервер-ретранслятор для случаев когда P2P не удаётся. Работает через STUN-протокол расширенный командами allocate/refresh/send. Все данные идут через TURN, поэтому он не P2P — это fallback.

Зачем нужен если есть STUN

STUN даёт клиенту его внешний адрес, но symmetric NAT и корпоративные фаерволы могут блокировать входящие UDP от неизвестных хостов даже с правильным адресом. Тогда прямое соединение не установить. TURN решает это тем что оба клиента открывают связь с TURN-сервером и он ретранслирует.

Как работает

  1. Клиент A шлёт Allocate к TURN-серверу. Сервер выделяет relayed transport address, например turn.example.com:49152.
  2. Клиент A передаёт этот адрес клиенту B через сигналинг.
  3. Клиент B тоже делает Allocate, получает свой relayed address.
  4. Оба обмениваются: клиент A шлёт TURN-серверу Send с payload и адресом B. TURN-сервер пересылает от своего имени B (на его relayed).
  5. Ретрансляция работает пока обе аллокации живы (обновление через Refresh).

Порты и протоколы

ТранспортПортКомментарий
UDP3478Обычный TURN
TCP3478Fallback если UDP заблокирован
TLS/TCP5349TURN over TLS (turns:)
DTLS/UDP5349Реже используется

TURN over TLS на порту 443 — обход корпоративных фаерволов, выглядит как обычный HTTPS-трафик.

Аутентификация

TURN требует credentials, потому что сервер расходует полосу и IP-ресурсы. Долгосрочные пользователи неудобны — обычно используется time-limited credentials:

username: 1700000000:alice     (timestamp:userid)
password: HMAC-SHA1(shared_secret, username)
      = 8f7d3b2a...

Клиент получает пару у сигнального сервера, TURN проверяет HMAC. Через час credentials истекают.

Реализации серверов

coturn базовый конфиг

# /etc/turnserver.conf
listening-port=3478
tls-listening-port=5349
external-ip=1.2.3.4
realm=example.com
lt-cred-mech
user=alice:secret
cert=/etc/letsencrypt/live/turn.example.com/fullchain.pem
pkey=/etc/letsencrypt/live/turn.example.com/privkey.pem
fingerprint
no-cli
min-port=49152
max-port=65535

Использование в WebRTC

const pc = new RTCPeerConnection({
  iceServers: [
    { urls: 'stun:stun.l.google.com:19302' },
    { urls: 'turn:turn.example.com:3478', username: 'alice', credential: 'secret' },
    { urls: 'turns:turn.example.com:5349', username: 'alice', credential: 'secret' }
  ]
});

ICE сам решит когда использовать STUN, когда TURN.

Стоимость

TURN ретранслирует весь медиа-трафик — включая видео 4K. Провайдеры платного TURN (Twilio, Cloudflare) берут $0.40-$1 за ГБ. Своё разворачивание: 1 Гбит/с VPS = ~$50/мес, покрывает тысячи одновременных звонков.

Статистика

См. также