NAT

Материал из llmdocs — справочник разработчика
NAT
Полное названиеNetwork Address Translation
СпецификацииRFC 1631 (1994), RFC 3022 (2001)
Основная формаNAPT — трансляция адресов и портов
ВидыSNAT (исходящий), DNAT (проброс портов), CGNAT (на стороне провайдера)
Причина появлениянехватка адресов IPv4
Обход NATSTUN, TURN, ICE, пробивка «дыр»
В Linuxiptables и nftables (MASQUERADE, DNAT)

NAT (англ. Network Address Translation — трансляция сетевых адресов) — механизм, при котором маршрутизатор подменяет IP-адреса (и обычно порты) в проходящих пакетах. Самый частый случай — домашний роутер: ноутбук, телефон и телевизор получают частные адреса вида 192.168.1.x, а в интернет выходят через один публичный адрес роутера. Роутер запоминает, какое внутреннее устройство открыло соединение, и возвращает ответы по назначению.

NAT появился как временная мера против нехватки адресов IPv4 (см. IP-адрес и подсети (CIDR)) и стал одной из самых распространённых технологий интернета. Окончательное решение проблемы адресов — IPv6, где NAT обычно не нужен.

Как работает

Наиболее распространённая форма — NAPT (трансляция адресов и портов, она же PAT или «маскарадинг»):[1]

  1. Ноутбук 192.168.1.10 отправляет пакет с порта 51000 на 93.184.215.14:443.
  2. Роутер заменяет адрес отправителя на свой публичный 203.0.113.5, а порт — на свободный, например 40001, и записывает соответствие в таблицу трансляций.
  3. Ответ приходит на 203.0.113.5:40001; роутер находит запись и отправляет пакет на 192.168.1.10:51000.

Благодаря портам за одним адресом могут работать тысячи устройств. Записи таблицы живут, пока соединение активно: для TCP — до закрытия соединения, для UDP — короткое время после последнего пакета.

Виды

Вид Что подменяется Пример
SNAT, маскарадинг адрес отправителя исходящих пакетов выход домашней сети в интернет
DNAT, проброс портов адрес получателя входящих пакетов порт 8080 роутера → сервер 192.168.1.20:80
Статический NAT 1:1 один внутренний адрес ↔ один внешний облачные «публичные IP» виртуальных машин
CGNAT NAT на стороне провайдера абоненты делят общий адрес; пространство 100.64.0.0/10[2]

При CGNAT абонент оказывается за двумя NAT — своим и провайдерским — и не может принимать входящие соединения, даже настроив проброс портов на домашнем роутере.

NAT в Linux и контейнерах

# nftables: выпускать подсеть 10.0.0.0/24 в интернет через eth0
nft add table ip nat
nft add chain ip nat postrouting '{ type nat hook postrouting priority 100; }'
nft add rule ip nat postrouting ip saddr 10.0.0.0/24 oif eth0 masquerade

# проброс порта 8080 на внутренний сервер
nft add chain ip nat prerouting '{ type nat hook prerouting priority -100; }'
nft add rule ip nat prerouting iif eth0 tcp dport 8080 dnat to 10.0.0.20:80

sysctl -w net.ipv4.ip_forward=1     # разрешить маршрутизацию

Правила NAT в Linux задаются через nftables или iptables.[5] Docker использует именно этот механизм: контейнеры получают адреса во внутренней сети, исходящий трафик маскируется, а -p 8080:80 создаёт правило DNAT. В Kubernetes kube-proxy трансляцией адресов направляет трафик сервисов на поды. Опасная деталь: правила Docker обходят многие настройки файрвола хоста, поэтому опубликованный порт может оказаться открытым всему интернету (см. Файрвол (iptables, nftables)).

Проблемы NAT

  • Входящие соединения невозможны без проброса портов: устройство за NAT нельзя «позвать» снаружи. Это ломает прямые соединения между пользователями — видеозвонки, игры, P2P.
  • Нарушение сквозной связности. Протоколы, передающие адреса внутри данных (FTP, SIP), требуют специальных помощников на роутере.
  • Таймауты. Простаивающие соединения выпадают из таблицы — долгоживущим соединениям нужны пакеты поддержки (keepalive).
  • Общий адрес. За одним адресом CGNAT — тысячи абонентов; блокировка адреса за злоупотребления одного задевает остальных, а журналы и расследования усложняются.

Обход NAT

Для прямых соединений между устройствами за NAT используют набор техник, стандартный для WebRTC:[4]

  • STUN — сервер сообщает клиенту его внешний адрес и порт.[3]
  • Пробивка «дыр» (hole punching) — обе стороны одновременно отправляют пакеты друг другу, создавая записи в своих NAT.
  • TURN — если прямое соединение невозможно, трафик идёт через ретранслятор.
  • ICE — перебирает кандидатов (локальные, внешние, ретранслируемые адреса) и выбирает работающий путь.

Успех зависит от поведения NAT: «полноконусные» устройства легко пропускают такие соединения, а симметричные NAT, выделяющие новый внешний порт для каждого адресата, — нет. Требования к поведению NAT для UDP описаны в RFC 4787.[6] На этих же техниках построены mesh-VPN вроде Tailscale.

NAT и безопасность

NAT часто воспринимают как защиту, потому что он не пропускает входящие соединения. Но это побочный эффект, а не функция безопасности: исходящие соединения и ответы проходят свободно, а защиту должен обеспечивать файрвол. В IPv6 без NAT ту же роль играет правило «запрещать входящие соединения, кроме разрешённых».

См. также

Источники

  1. RFC 3022 — Traditional IP Network Address Translator (Traditional NAT)
  2. RFC 6598 — IANA-Reserved IPv4 Prefix for Shared Address Space
  3. RFC 8489 — Session Traversal Utilities for NAT (STUN)
  4. RFC 8445 — Interactive Connectivity Establishment (ICE)
  5. nftables wiki — Performing Network Address Translation
  6. RFC 4787 — NAT Behavioral Requirements for Unicast UDP