Частные сети и NAT
TL;DR: Частные (private) адреса (
10.0.0.0/8,172.16.0.0/12,192.168.0.0/16) не маршрутизируются в интернете — они для внутренних сетей. NAT (Network Address Translation) подменяет частные адреса на публичный при выходе в интернет. В Linux NAT реализуется через netfilter (iptables/nftables) и называется «маскарадинг» — все внутренние хосты выходят в интернет через один публичный IP.
Проблема: IPv4-адресов не хватает
IPv4 имеет ~4.3 миллиарда адресов (32 бита). Устройств в мире — десятки миллиардов. Решение — разделить адреса на публичные (маршрутизируемые в интернете) и частные (для внутренних сетей), а между ними поставить NAT.
Частные адреса (RFC 1918)
Три диапазона зарезервированы для частных сетей. Маршрутизаторы в интернете не передают пакеты с такими адресами — они существуют только внутри локальных сетей.
| Диапазон | CIDR | Кол-во адресов | Типичное применение |
|---|---|---|---|
10.0.0.0 – 10.255.255.255 | 10.0.0.0/8 | 16 777 216 | Облачные VPC (AWS, GCP), корпоративные сети |
172.16.0.0 – 172.31.255.255 | 172.16.0.0/12 | 1 048 576 | Docker (172.17.0.0/16), Kubernetes Pod CIDR |
192.168.0.0 – 192.168.255.255 | 192.168.0.0/16 | 65 536 | Домашние и офисные сети |
Один и тот же частный адрес 192.168.1.100 может использоваться в миллионах разных сетей одновременно — они изолированы и не знают друг о друге.
Другие специальные диапазоны
| Диапазон | Назначение |
|---|---|
127.0.0.0/8 | Loopback (localhost) |
169.254.0.0/16 | Link-local (APIPA — автоназначение, когда DHCP недоступен) |
100.64.0.0/10 | Carrier-Grade NAT (ISP-уровень) |
Что такое NAT
NAT (Network Address Translation) — подмена адресов в заголовках пакетов при прохождении через маршрутизатор. Позволяет множеству хостов с частными адресами выходить в интернет через один публичный IP.
Как работает NAT (SNAT/Masquerade)
Внутренняя сеть NAT-маршрутизатор Интернет
192.168.1.0/24 192.168.1.1 (внутр.)
203.0.113.5 (публ.)
Хост A (192.168.1.100)
│
│ Пакет: src=192.168.1.100:49832 dst=93.184.216.34:443
│
▼
NAT-маршрутизатор:
1. Запоминает: {192.168.1.100:49832 ↔ 203.0.113.5:61234}
2. Подменяет src: 192.168.1.100:49832 → 203.0.113.5:61234
│
│ Пакет: src=203.0.113.5:61234 dst=93.184.216.34:443
│
▼
Сервер (93.184.216.34) отвечает:
│
│ Пакет: src=93.184.216.34:443 dst=203.0.113.5:61234
│
▼
NAT-маршрутизатор:
3. Находит запись: {203.0.113.5:61234 ↔ 192.168.1.100:49832}
4. Подменяет dst: 203.0.113.5:61234 → 192.168.1.100:49832
│
│ Пакет: src=93.184.216.34:443 dst=192.168.1.100:49832
│
▼
Хост A получает ответ
NAT-маршрутизатор ведёт таблицу трансляций (connection tracking) — для каждого активного соединения помнит соответствие внутренний:порт ↔ внешний:порт.
Типы NAT
| Тип | Направление | Что подменяется | Применение |
|---|---|---|---|
| SNAT (Source NAT) | Изнутри → наружу | Source IP | Выход в интернет |
| Masquerade | Изнутри → наружу | Source IP (автоматически берёт IP интерфейса) | Выход в интернет (динамический IP) |
| DNAT (Destination NAT) | Снаружи → внутрь | Destination IP + порт | Port forwarding, проброс портов |
SNAT и Masquerade делают одно и то же — подменяют source IP. Разница: SNAT требует явно указать публичный IP (--to-source 203.0.113.5), Masquerade автоматически берёт текущий IP выходного интерфейса. Masquerade чуть медленнее (смотрит IP каждый раз), но работает при динамическом IP (DHCP от провайдера).
Port Forwarding (DNAT)
Обратная задача: сделать внутренний сервер доступным извне.
Интернет → 203.0.113.5:8080 → NAT(DNAT) → 192.168.1.50:80
Запрос из интернета на публичный IP:8080 перенаправляется
на внутренний веб-сервер 192.168.1.50:80
NAT в Linux (netfilter)
Linux реализует NAT через подсистему ядра netfilter. Утилиты: iptables (legacy) или nftables (современный).
Masquerade (выход в интернет)
# Включить forwarding (пропуск пакетов между интерфейсами)
sudo sysctl -w net.ipv4.ip_forward=1
# iptables: маскарадинг для всех из 192.168.1.0/24
sudo iptables -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
# nftables: эквивалент
sudo nft add table nat
sudo nft add chain nat postrouting { type nat hook postrouting priority 100 \; }
sudo nft add rule nat postrouting oifname "eth0" ip saddr 192.168.1.0/24 masqueradePort Forwarding (DNAT)
# iptables: входящий трафик на :8080 → внутренний сервер 192.168.1.50:80
sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.50:80
sudo iptables -A FORWARD -p tcp -d 192.168.1.50 --dport 80 -j ACCEPT
# nftables: эквивалент
sudo nft add chain nat prerouting { type nat hook prerouting priority -100 \; }
sudo nft add rule nat prerouting iifname "eth0" tcp dport 8080 dnat to 192.168.1.50:80Connection Tracking
Ядро отслеживает состояние NAT-соединений:
# Текущие NAT-трансляции
sudo conntrack -L
# tcp 6 117 TIME_WAIT src=192.168.1.100 dst=93.184.216.34 sport=49832 dport=443
# src=93.184.216.34 dst=203.0.113.5 sport=443 dport=61234 [ASSURED]
# Количество отслеживаемых соединений
cat /proc/sys/net/netfilter/nf_conntrack_count
cat /proc/sys/net/netfilter/nf_conntrack_maxNAT в Docker и Kubernetes
Docker и Kubernetes активно используют NAT:
Docker: контейнер получает IP из 172.17.0.0/16. При выходе в интернет — masquerade через хост. При -p 8080:80 — DNAT с хоста в контейнер.
# Docker добавляет правила автоматически
sudo iptables -t nat -L -n | grep DOCKER
# MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
# DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80Kubernetes: Service типа ClusterIP использует DNAT (через kube-proxy / iptables) для маршрутизации к Pod-ам. NodePort — DNAT с внешнего порта ноды на Pod.
Недостатки NAT
| Недостаток | Описание |
|---|---|
| Нарушает end-to-end | Внешний хост не может инициировать соединение к внутреннему (без port forwarding) |
| Усложняет протоколы | FTP, SIP, IPsec требуют специальной обработки (ALG) |
| Состояние | NAT-маршрутизатор хранит таблицу трансляций — это ресурсы и точка отказа |
| Маскирует проблемы | Отладка сетевых проблем сложнее — адреса подменены |
IPv6 спроектирован так, чтобы NAT был не нужен — адресов хватает на каждое устройство. На практике NAT для IPv4 будет жить ещё долго.
Подводные камни
| Проблема | Симптом | Решение |
|---|---|---|
| Нет интернета за NAT | ping 8.8.8.8 с внутреннего хоста не работает | Проверить: ip_forward=1? MASQUERADE-правило есть? iptables -t nat -L |
| Port forwarding не работает | Внешний клиент не достучится | Проверить DNAT-правило + FORWARD-правило (оба нужны) |
| conntrack table full | nf_conntrack: table full, dropping packet в dmesg | Увеличить nf_conntrack_max или уменьшить таймауты |
| Docker-контейнер не доступен извне | Порт не проброшен | -p 8080:80 при запуске, или docker-compose ports: |
| Hairpin NAT не работает | Внутренний хост не может обратиться к port forwarding по внешнему IP | Добавить DNAT для трафика из внутренней сети + MASQUERADE/SNAT |
Связанные материалы
- networking — стек TCP/IP, IP-адреса, подсети, маршрутизация
- dhcp — автоматическое назначение IP в локальной сети
- linux-router — настройка Linux как маршрутизатора
- configure-firewall — ufw, iptables/nftables