STUN

STUN (Session Traversal Utilities for NAT, RFC 8489) — простой протокол чтобы клиент за NAT узнал свой внешний IP+порт, каким его видит внешний мир. Основа для WebRTC и любых P2P-соединений через NAT.

Как работает

  1. Клиент отсылает UDP-пакет на STUN-сервер (обычно stun.l.google.com:19302).
  2. STUN-сервер видит: пакет пришёл с 85.140.10.50:54321 (это NAT-транслированный адрес).
  3. STUN-сервер отвечает: «твой внешний адрес — 85.140.10.50:54321».
  4. Клиент теперь знает свой публичный endpoint и может передать его другой стороне через сигналинг.

Пакет

Простой бинарный формат:

Публичные STUN

ПровайдерАдрес
Googlestun.l.google.com:19302 (и .1, .2, .3, .4)
Cloudflarestun.cloudflare.com:3478
Twilioglobal.stun.twilio.com:3478
Nextcloudstun.nextcloud.com:443

Проверить

# stunclient (пакет stuntman-client)
$ stunclient stun.l.google.com 19302
Binding test: success
Local address: 192.168.1.100:54321
Mapped address: 85.140.10.50:54321

Типы NAT (устаревшая классификация)

Старый RFC 3489 определял 4 типа NAT: full cone / restricted cone / port-restricted / symmetric. Сегодня они условны, но термины живут:

ТипЧто делаетSTUN достаточно?
Full coneЛюбой внешний хост может слать на внешний portДа
Restricted coneТолько те, кому клиент писал первыйДа (нужен hole-punch)
Port-restrictedТолько те endpoint'ы, кому клиент писалДа (сложнее)
SymmetricРазный внешний порт для каждого назначенияНет, нужен TURN

STUN + TCP

Обычно UDP, но есть и TCP-вариант — RFC 5389. Реже используется, потому что цель STUN — узнать endpoint именно для UDP-P2P (WebRTC).

STUN over TLS (STUN/TLS)

Порт 5349. Защищает от подмены STUN-ответов на пути (иначе можно заставить клиента думать что его внешний IP другой).

Где используется

Проблема — приватность

Через WebRTC браузер может узнать реальный локальный IP клиента (даже за VPN) и внешний IP. Атака WebRTC IP leak. Защита в браузере:

См. также