Зачем нужна
Когда твой роутер делает [[nat|NAT]], он подменяет src IP/port исходящего пакета. Ответ от сервера прилетит на публичный IP роутера, и роутер должен развернуть его обратно на правильный приватный IP внутри лана.
Чтобы это работало, надо помнить каждое активное соединение: какой внутренний хост, какой внешний, какие порты, какой протокол. Эта память и есть conntrack (connection tracking).
Без conntrack:
- NAT работал бы только в одну сторону (исходящий - да, ответ - никак)
- stateful-фаервол был бы невозможен (нельзя отличить «новый SYN» от «уже установленное соединение»)
Что хранится в записи
Каждое отслеживаемое соединение = одна запись с полями:
- протокол: TCP/UDP/ICMP/...
- original direction: src IP+port, dst IP+port
- reply direction: то же самое для обратного пакета (после NAT'а)
- state: для TCP -
NEW/ESTABLISHED/RELATED/INVALID - timeout: сколько ещё жить если нет трафика
Посмотреть в живую:
$ sudo conntrack -L | head
tcp 6 431999 ESTABLISHED src=192.168.1.50 dst=8.8.8.8 \
sport=54321 dport=443 src=8.8.8.8 dst=80.10.20.30 \
sport=443 dport=54321 [ASSURED]
Расшифровка:
tcp 6- TCP, протокол №6431999- секунд до тайм-аута (≈5 дней для ESTABLISHED)ESTABLISHED- состояние из [[tcp-states|TCP-state machine]]src=192.168.1.50 ... dst=8.8.8.8- оригинальное направлениеsrc=8.8.8.8 ... dst=80.10.20.30- обратное (видишь как dst сменился на публичный IP - это след NAT'а)
Состояния
Для TCP:
| State | Значение |
|---|---|
NEW | Видели только первый пакет (SYN) |
ESTABLISHED | Двусторонний обмен подтверждён |
RELATED | Связано с другим соединением (FTP-data к FTP-control) |
INVALID | Аномальный пакет, не пришёл к месту |
Эти состояния - основа для правил iptables -m state /
nft ct state. Например, "разрешить только ESTABLISHED+RELATED" -
стандартное правило фаервола.
Тайм-ауты
Conntrack не хранит соединение вечно - есть тайм-ауты per-state:
/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established = 432000 # 5 дней
/proc/sys/net/netfilter/nf_conntrack_tcp_timeout_close_wait = 60 # 1 мин
/proc/sys/net/netfilter/nf_conntrack_udp_timeout = 30 # UDP
Если соединение закрылось «грязно» (без FIN) - оно ещё долго болтается в conntrack как зомби.
Лимит и переполнение
Conntrack-таблица ограничена (nf_conntrack_max, дефолт ~64K-256K).
Когда упирается:
- новые соединения дропаются (или работают без трекинга, зависит от версии)
- в
dmesgпишетсяnf_conntrack: table full, dropping packet
На high-traffic-серверах это реальная проблема - настраивают:
sudo sysctl -w net.netfilter.nf_conntrack_max=1048576
Когда conntrack - НЕ нужен
- На маршрутизаторах с NAT - обязательно
- На stateful-фаерволах - обязательно
- На «тупом» роутере без NAT и без фаервола - можно отключить
(
-j NOTRACKправилами) для экономии CPU и памяти. На high-traffic edge-роутерах это серьёзный буст