# NAT и masquerade _Сеть: L4 и выше · LinuxLab Knowledge Base_ **TL;DR:** NAT - переписывание src/dst адресов пакета на роутере. Masquerade - частный случай: src-IP заменяется на свой исходящий, для исходящих из приватной сети в публичную. ## Зачем NAT Главная причина существования NAT - **дефицит IPv4-адресов**. Приватные диапазоны (10.x, 172.16-31.x, 192.168.x) не маршрутизируются в интернете (см. [ipv4-addressing](/kb/ipv4-addressing.md)). Чтобы хост из приватной сети попал в интернет, на границе сети (роутере) должен быть 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]]: ```bash 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 (всё ещё работает на многих системах): ```bash 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 не нужен ## Команды ```bash sudo sysctl -w net.ipv4.ip_forward=1 ``` Включить форвардинг - необходимо чтобы роутер вообще пересылал пакеты ```bash sudo nft add rule inet nat postrouting oifname eth0 masquerade ``` Базовое правило masquerade на исходящем интерфейсе ```bash cat /proc/net/nf_conntrack | head ``` Текущие записи conntrack (соединения которые NAT помнит) ```bash sudo conntrack -L 2>/dev/null | head ``` То же через CLI-инструмент `conntrack` ```bash sysctl net.netfilter.nf_conntrack_max ``` Максимум записей; на нагруженных роутерах часто увеличивают ## См. также - [IPv4-адресация и CIDR](/kb/ipv4-addressing.md) - [Conntrack - память Linux о всех сетевых соединениях](/kb/conntrack.md) - [Policy routing - rule-based маршрутизация](/kb/policy-routing.md) - [iptables - правила netfilter (legacy)](/kb/cmd-iptables.md) - [nft - современный файрвол (nftables)](/kb/cmd-nft.md) - [Kubernetes Service и Ingress - сетевая публикация подов](/kb/kubernetes-services-and-ingress.md)