# Conntrack - память Linux о всех сетевых соединениях _Сеть: L4 и выше · LinuxLab Knowledge Base_ **TL;DR:** Подсистема ядра Linux, которая помнит каждое активное соединение. Без неё NAT не развернёт ответ на нужный приватный IP, а фаервол не отличит «новый коннект» от «уже установленного». Видна в `/proc/net/nf_conntrack`. ## Зачем нужна Когда твой роутер делает [[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**: сколько ещё жить если нет трафика Посмотреть в живую: ```bash $ 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, протокол №6 - `431999` - секунд до тайм-аута (≈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-серверах это реальная проблема - настраивают: ```bash sudo sysctl -w net.netfilter.nf_conntrack_max=1048576 ``` ## Когда conntrack - НЕ нужен - На маршрутизаторах с NAT - обязательно - На stateful-фаерволах - обязательно - На «тупом» роутере без NAT и без фаервола - можно отключить (`-j NOTRACK` правилами) для экономии CPU и памяти. На high-traffic edge-роутерах это серьёзный буст ## Команды ```bash sudo conntrack -L ``` Все активные tracked-соединения ```bash sudo conntrack -L -p tcp --dport 443 ``` Только HTTPS-соединения ```bash sudo conntrack -E ``` Realtime-events: создание/обновление/удаление записей ```bash sudo conntrack -F ``` Дропнуть всю таблицу - пересоздастся живыми пакетами ```bash cat /proc/sys/net/netfilter/nf_conntrack_count ``` Сколько записей сейчас ```bash cat /proc/sys/net/netfilter/nf_conntrack_max ``` Лимит. Если current приближается - пора тюнить ## См. также - [NAT и masquerade](/kb/nat.md) - [TCP three-way handshake](/kb/tcp-handshake.md) - [TCP states (LISTEN, ESTABLISHED, TIME_WAIT)](/kb/tcp-states.md) - [UDP - User Datagram Protocol](/kb/udp-basics.md) - [iptables - правила netfilter (legacy)](/kb/cmd-iptables.md)