Зачем NAT
Главная причина существования NAT - дефицит IPv4-адресов. Приватные диапазоны (10.x, 172.16-31.x, 192.168.x) не маршрутизируются в интернете (см. ipv4-addressing). Чтобы хост из приватной сети попал в интернет, на границе сети (роутере) должен быть NAT.
Виды
-
SNAT (source NAT) - переписать src-адрес исходящего пакета. Применяется на исходящих с границы; чаще всего как MASQUERADE (динамически берёт IP outgoing-интерфейса).
-
DNAT (destination NAT) - переписать dst-адрес/порт входящего пакета. Aka «port forwarding»:
публичный_IP:80 → 10.0.0.5:8080. Используется для публикации внутренних сервисов наружу. -
PAT/NAT44/NAPT - то же что masquerade, с переписыванием src-port тоже (один публичный IP скрывает много внутренних). Стандартное поведение домашнего роутера.
-
Hairpin NAT - клиент в приватной сети обращается к своему публичному IP - пакет приходит на роутер, должен пройти через NAT и вернуться в LAN. Поддержка не везде.
Как это работает
При установлении соединения через NAT:
Client 10.0.0.10:54321 ──→ Router (NAT) ──→ Server 1.2.3.4:443
│
│ переписывает src на 203.0.113.5:54321
│ запоминает в conntrack-таблице:
│ 10.0.0.10:54321 ↔ 203.0.113.5:54321
│
▼
Server видит коннект от 203.0.113.5:54321
Когда server отвечает, роутер находит запись в conntrack и переписывает обратно.
Conntrack-таблица (/proc/net/nf_conntrack) хранит state всех проходящих
соединений. Размер ограничен - nf_conntrack_max. Переполнение -
редкая но болезненная проблема high-traffic роутеров.
Где настраивается
Современный Linux - через [[#cmd-nft|nftables]]:
sudo nft add table inet nat
sudo nft 'add chain inet nat postrouting { type nat hook postrouting priority 100; }'sudo nft add rule inet nat postrouting ip saddr 10.0.0.0/24 oifname "eth1" masquerade
postrouting- последний этап перед отправкойoifname "eth1"- на каком интерфейсе применятьmasquerade- заменить src на IP eth1
Старый синтаксис через iptables (всё ещё работает на многих системах):
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth1 -j MASQUERADE
Также нужен net.ipv4.ip_forward=1 чтобы роутер вообще пересылал пакеты.
NAT и его проблемы
- Сломанный peer-to-peer - два хоста за NAT не могут открыть друг другу соединение напрямую. Решения: STUN, TURN, port forwarding, hole-punching
- Asymmetric routing - пакет ушёл через одного NAT'а, ответ через другого; conntrack не знает связь, дропает
- Conntrack-overflow - нагрузка на роутер растёт быстрее
nf_conntrack_max; пакеты дропаются - IPv6 + NAT - антипаттерн; в IPv6 каждое устройство имеет публичный IP, NAT не нужен