NAT, CGNAT и ограниченные сети: где заканчивается прямая связность

Обложка

Цикл «Виды связности и SDN», часть 7. Предыдущая часть: «Топологии связности: hub-and-spoke, partial mesh и full mesh».

Ось: underlay с ограничениями (NAT, CGNAT, фильтрация).

Фраза «работает за NAT» звучит уверенно, но описывает слишком много разных ситуаций.

Если сервер имеет белый адрес, а клиент находится за домашним роутером, достаточно исходящего соединения клиента и сохранения NAT mapping. Если оба участника за CGNAT, ни к одному нельзя сделать обычный port forwarding. Если обе стороны находятся за symmetric NAT, внешний порт может зависеть от назначения, и простого обмена наблюдаемыми адресами недостаточно.

Отдельно проверяют hairpin NAT: два узла за одним и тем же маршрутизатором часто не могут достучаться друг до друга по внешнему адресу, пока устройство не умеет возвращать такой трафик внутрь.

Ещё одна ловушка адресации: диапазон 100.64.0.0/10 занят и операторским CGNAT (RFC 6598), и многими mesh — Tailscale и Headscale по умолчанию живут в нём же. Если адреса overlay пересекаются с underlay, маршруты ломаются неочевидно.

NAT mapping и keepalive

Stateful NAT запоминает исходящий поток и временно разрешает обратные пакеты. Когда трафика нет, запись удаляется.

WireGuard умеет отправлять PersistentKeepalive, чтобы mapping не исчезал. Но чистый WireGuard не содержит центрального механизма знакомства двух неизвестных участников, автоматического hole punching и relay. Как минимум одна сторона должна иметь известный достижимый endpoint либо нужен внешний координатор.

Если у узла сменился внешний адрес и он отправил пакет первым, пир WireGuard может обновить endpoint по входящему пакету. Это roaming, а не NAT traversal для двух неизвестных сторон.

STUN, ICE и hole punching

Полезно разделять mapping и filtering — так делает RFC 4787. Hole punching обычно ломается на address-and-port-dependent mapping: внешний порт зависит от назначения. Endpoint-independent mapping при более строгом filtering часто всё же пробивается взаимными проверками.

STUN помогает узлу узнать, какой внешний адрес и порт видит сервер в Интернете. Сам по себе STUN путь не строит. ICE добавляет взаимные проверки связности. Если прямой путь не получается, нужен ретранслятор: в IETF это TURN, в продуктах — DERP, NetBird Relay или отдельный TCP relay.

Controller или signal service обменивает наблюдаемые адреса между участниками. Затем оба почти одновременно отправляют UDP друг другу, создавая подходящие состояния NAT.

При обычном NAT это часто даёт прямое соединение. При address-and-port-dependent mapping — не всегда.

Relay

Если прямой путь не построен, оба участника устанавливают исходящие соединения к публичному relay. Он пересылает уже зашифрованные пакеты и не обязан знать их содержимое.

Relay повышает вероятность связности, но добавляет:

Поэтому важно резервировать relay и уметь видеть, какая пара работает напрямую, а какая через него.

UDP/443 не является HTTPS

Номер 443 не превращает произвольный протокол в веб-трафик.

WireGuard на UDP/443 остаётся WireGuard по UDP. Сеть, в которой разрешён только TCP/443, его не пропустит. Межсетевой экран с анализом протокола также не обязан доверять пакету только из-за номера порта.

Настоящий fallback через TCP/443 означает, что data plane умеет работать поверх разрешённого TCP-транспорта — например HTTPS, TLS или WebSocket. Это повышает совместимость с жёсткими egress-правилами, но не гарантирует работу при белых списках, блокировке домена, SNI или адреса сервиса.

Как ведут себя разные семейства решений

Tailscale пытается построить прямой WireGuard-путь по UDP, а при неудаче использует DERP через TCP/443.

Headscale применяет те же клиенты; можно использовать публичные DERP или собственный сервер. Сам Headscale остаётся control plane, а не обязательным транзитом данных и не содержит DERP внутри бинарника.

NetBird использует STUN/ICE для прямых соединений и собственный relay. Основной транспорт relay — QUIC, запасной — WebSocket при недоступном UDP.

Nebula умеет hole punching и UDP relay. Такой relay помогает при сложном NAT, но для его работы UDP всё равно должен проходить.

ZeroTier преимущественно строит P2P по UDP; публичные roots могут и обнаруживать, и ретранслировать. Для сетей без UDP отдельно разворачивают TCP relay через HTTPS — это другой компонент, не «тот же root на порту 443».

Netmaker автоматизирует WireGuard и умеет работать с gateway/relay, но UDP/443 в конфигурации остаётся UDP и не является универсальным TCP fallback.

OpenZiti использует другую модель: endpoints подключаются к публичным edge routers, а трафик проходит через fabric. Это не direct mesh, зато TCP/443 является штатным транспортом edge listener.

Почему нельзя поставить вечную галочку «проходит ТСПУ»

ТСПУ и белые списки применяются неодинаково у разных операторов и в разных регионах. Правила меняются. Могут ограничиваться:

Поэтому вместо рекламной галочки нужно фиксировать свойства:

  1. Нужен ли произвольный UDP?
  2. Может ли data plane перейти на TCP/443?
  3. Можно ли поднять собственные контроллер, STUN и relay?
  4. Что продолжает работать после потери контроллера?
  5. Какие адреса и домены обязательны?
  6. Когда, где и на каком операторе проводился тест?

Цель такой проверки — диагностика и обеспечение разрешённой корпоративной связности, а не обещание универсального обхода ограничений.

Наша лаборатория

Каждое решение нужно прогонять через одинаковые профили: оба узла за CGNAT, hairpin за одним NAT, symmetric NAT, полный запрет UDP, только TCP/80/443, отказ основного relay, потеря контроллера, смена внешнего адреса во время SSH-сеанса и PMTUD black hole. Полный список — в программе испытаний.

В итоговой таблице появятся не мнения, а наблюдаемые результаты: прямой путь или relay, время установления, failover, RTT, throughput и рабочий MTU.

Где это ломается

В следующей части разберём шифрование: от MACsec до WireGuard и mTLS, а также цену двойной инкапсуляции.

Предыдущая часть: «Топологии связности: hub-and-spoke, partial mesh и full mesh»

Оглавление цикла: «SDN без магии: карта видов связности»

Следующая часть: «Шифрование в SDN: MACsec, IPsec, WireGuard и mTLS»

Схема

#network #selfhosting