6. Linux Networking
Сетевой стек (NIC/ядро/сокеты), инструменты (iproute2, ss, tcpdump, conntrack, ethtool) и firewall (iptables/nftables) + как пакет проходит INPUT/FORWARD/OUTPUT и почему «порт открыт», но соединения нет.
Сетевой стек Linux
NIC (сетевой интерфейс)
NIC (Network Interface Card) — физический или виртуальный интерфейс (eth0, bond0, veth, docker0). Драйвер в ядре принимает кадры с устройства, передаёт их в стек; исходящие пакеты из стека уходят в устройство. Состояние интерфейса (up/down), MTU, статистику смотрите через ip link и ethtool.
Kernel space vs user space
Обработка пакетов идёт в пространстве ядра: драйвер → IP → фильтры (netfilter/iptables) → маршрутизация → сокет (буфер, привязанный к приложению). Приложение в user space читает/пишет через сокет (системный вызов), не трогая пакеты напрямую. При проблемах важно понимать, на каком этапе «застревает» трафик: линк, маршрут, firewall или приложение не слушает/не принимает.
Socket (сокет)
Сокет — конечная точка обмена данными: адрес (IP + порт), протокол (TCP/UDP), состояние. Слушающий сокет (LISTEN) принимает входящие соединения; установленные соединения имеют состояния ESTABLISHED и т.д. Инструменты ss и netstat показывают сокеты и их состояния.
Инструменты
iproute2 (ip)
Современный набор для управления интерфейсами, адресами, маршрутами, соседями (ARP/NDP):
ip link show
ip addr show
ip route show
ip neigh show
Используется вместо устаревших ifconfig, route, arp.
ss
Показ сокетов (замена netstat), быстрее и информативнее:
ss -tlnp # слушающие TCP с процессами
ss -tunap # все TCP/UDP с процессами
ss -o state established
tcpdump
Захват пакетов на интерфейсе (L2–L4, при необходимости L7 с опциями). Фильтры по хосту, порту, протоколу:
tcpdump -i eth0
tcpdump -i eth0 port 443
tcpdump -i eth0 host 10.0.0.1
conntrack
conntrack (connection tracking) — подсистема ядра, которая запоминает соединения (и «полусессии» UDP/ICMP) для stateful firewall и NAT. Команда conntrack -L выводит таблицу соединений; при переполнении таблицы новые соединения могут сбрасываться. Важно при диагностике NAT и «почему не проходит ответ».
ethtool
Информация о физическом интерфейсе: скорость, дуплекс, ошибки, драйвер, поддержка offload:
ethtool eth0
ethtool -S eth0 # счётчики
ethtool -k eth0 # offload-опции
Firewall: iptables и nftables
Цепочки и таблицы
iptables и nftables — интерфейсы к подсистеме netfilter в ядре. Правила объединены в цепочки (chains); цепочки входят в таблицы (filter, nat, mangle и др.). Пакет последовательно проходит через цепочки в зависимости от направления и типа пакета.
Как пакет проходит INPUT / FORWARD / OUTPUT
- Пакет, предназначенный самому хосту (адрес назначения — IP хоста): после маршрутизации попадает в цепочку INPUT. Если правила разрешают — пакет доставляется сокету (приложению).
- Пакет, который хост пересылает (не для себя): после маршрутизации попадает в FORWARD. Разрешённый трафик уходит на исходящий интерфейс; там может применяться NAT и цепочка OUTPUT для трафика, сгенерированного самим хостом.
- Исходящий трафик с хоста: проходит цепочку OUTPUT, затем после маршрутизации — POSTROUTING (в таблице nat) и уходит в сеть.
Порядок для входящего: PREROUTING (nat) → маршрутизация → INPUT (filter) или FORWARD (filter) → для пересылаемых: POSTROUTING (nat). Понимание цепочек нужно, чтобы читать правила и понимать, на каком этапе трафик отбрасывается или изменяется (NAT).
Stateful vs stateless
- Stateless — правило смотрит только на один пакет (адрес, порт, флаги). Например, «разрешить TCP 443».
- Stateful — решение зависит от состояния соединения: пакет считается частью уже разрешённого соединения (запись в conntrack). Типичная политика: разрешить ESTABLISHED,RELATED для ответов на исходящие и входящие инициированные соединения; для новых входящих — явно разрешать только нужные порты.
conntrack хранит состояние (NEW, ESTABLISHED, RELATED и т.д.). Без conntrack stateful-правила не работают; при переполнении таблицы conntrack новые соединения могут не устанавливаться.
Почему порт открыт, но соединения нет
Слушающий сокет (ss показывает LISTEN на порту) означает, что приложение готово принимать. Но до сокета пакет должен:
- Дойти до хоста — линк, маршрут, нет DROP на пути.
- Пройти INPUT — правила firewall (iptables/nftables) должны разрешать трафик на этот порт для входящих пакетов.
- Не быть съеденным раньше — например, другой процесс или правило, перехватывающее трафик до целевого приложения.
Типичные причины «порт открыт, но не подключается»:
- Firewall — на этом же хосте или на пути (входной интерфейс) трафик отбрасывается в цепочке INPUT или FORWARD. Проверить: iptables -L INPUT -n -v, временно отключить firewall для теста (осторожно в production).
- Привязка к 127.0.0.1 — приложение слушает только localhost; с другого хоста порт «не открыт». Проверить: ss -tlnp — смотреть столбец Address.
- Маршрут — до хоста пакеты не доходят (сеть, другой путь). Проверить с клиента: traceroute, ping.
- Conntrack — при stateful правилах ответные пакеты могут не проходить, если запись в conntrack не создана или таблица переполнена.
!!! tip "Практика"
Последовательность: 1) ss -tlnp — кто и на каком адресе слушает; 2) с другого узла — telnet/nc на этот порт; 3) на целевом хосте — tcpdump на интерфейсе, есть ли пакеты; 4) iptables/nftables — нет ли DROP/REJECT для этого порта в INPUT.
VRRP и Keepalived
Резервирование шлюза или виртуального IP (VIP) на двух и более хостах: клиенты используют один общий адрес; при отказе одного узла другой подхватывает трафик. В Linux для этого часто используют протокол VRRP и демон Keepalived.
VRRP (Virtual Router Redundancy Protocol)
VRRP — протокол уровня 3 (RFC 5798): группа маршрутизаторов (или хостов) образует виртуальный маршрутизатор с общим Virtual IP (VIP) и Virtual Router ID (1–255). Один узел в группе — Master (владелец VIP), остальные — Backup. Участники обмениваются multicast-пакетами VRRP (протокол 112, группа 224.0.0.18); при отсутствии объявлений Master в течение таймаута Backup переводит себя в Master и поднимает VIP на своём интерфейсе. Приоритет (priority) задаёт, кто станет Master при равных условиях (выше — приоритетнее).
Клиенты в сети указывают шлюзом VIP; при падении текущего Master другой узел за несколько секунд начинает отвечать на ARP за этот VIP, и трафик переключается без смены конфигурации на клиентах.
Keepalived
Keepalived — демон в user space: реализует VRRP для Linux и дополняет его проверками здоровья (health checks). Если скрипт или проверка (например, HTTP, TCP, скрипт) на узле Master падает, Keepalived может понизить приоритет или перейти в состояние Backup, и другой узел станет Master. Так VIP «переезжает» на здоровый хост не только при полном падении машины, но и при отказе приложения.
Keepalived также умеет управлять LVS (Linux Virtual Server) для балансировки; для простого резервирования VIP достаточно конфигурации VRRP и опционально vrrp_script.
Пример настройки: два хоста, один VIP
Сценарий: два сервера (node1 и node2), общий VIP 192.168.1.100 для доступа к сервису. Интерфейс — eth0, подсеть 192.168.1.0/24.
Узел 1 (Master по умолчанию) — /etc/keepalived/keepalived.conf:
global_defs {
router_id LB1
}
vrrp_script check_nginx {
script "/usr/bin/killall -0 nginx" # проверка: процесс nginx существует
interval 2
weight -20 # при падении скрипта: priority - 20
}
vrrp_instance VI_1 {
state MASTER
interface eth0
virtual_router_id 51
priority 101
advert_int 1
authentication {
auth_type PASS
auth_pass secret123
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
check_nginx
}
}
Узел 2 (Backup) — /etc/keepalived/keepalived.conf:
global_defs {
router_id LB2
}
vrrp_script check_nginx {
script "/usr/bin/killall -0 nginx"
interval 2
weight -20
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass secret123
}
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
check_nginx
}
}
Важно: virtual_router_id и auth_pass должны совпадать в группе; priority на Master выше (например, 101 и 100). На обоих узлах interface и подсеть VIP одинаковые.
Запуск и проверка
# Установка (Debian/Ubuntu)
sudo apt install keepalived
# Запуск и автозагрузка
sudo systemctl enable --now keepalived
# Статус
sudo systemctl status keepalived
# На узле с VIP должен быть адрес 192.168.1.100 на eth0
ip addr show eth0
При остановке nginx на Master приоритет эффективно снижается, VRRP объявления от второго узла «выигрывают», и VIP переезжает на node2. Клиенты продолжают обращаться к 192.168.1.100.
Кратко по параметрам
| Параметр | Описание |
|---|---|
state |
MASTER или BACKUP — начальное состояние; дальше VRRP решает по приоритету и объявлениям. |
virtual_router_id |
Идентификатор группы (1–255), один на пару/кластер. |
priority |
1–254; выше — предпочтительный Master. |
advert_int |
Интервал объявлений VRRP (секунды). |
vrrp_script + track_script |
Проверка здоровья; при падении скрипта к priority применяется weight (отрицательный — снижение). |
authentication |
Один пароль в группе, чтобы чужие VRRP-пакеты не подменили группу. |
Для отладки: journalctl -u keepalived -f, просмотр VRRP-трафика: tcpdump -i eth0 proto 112.
Паттерны и антипаттерны
| Паттерн | Описание |
|---|---|
| Идти по пути пакета | Линк → маршрут → firewall (INPUT/FORWARD) → сокет; проверять по шагам. |
| Использовать ss и ip | Стандартный набор для сокетов и интерфейсов/маршрутов. |
| Смотреть conntrack при NAT | При «исходящее есть, ответ не приходит» проверять conntrack и правила NAT. |
| Антипаттерн | Почему плохо | Что делать |
|---|---|---|
| Думать «порт открыт = доступен снаружи» | Слушать можно на 127.0.0.1; firewall может резать. | Проверять привязку и правила INPUT. |
| Чистить iptables «всё подряд» | Можно сломать NAT и доступ к сервисам (в т.ч. Docker/Kubernetes). | Менять точечно, понимать цепочки и зависимость от conntrack. |