Обзор
Сетевой стек Linux — это одна из наиболее активно развивающихся частей ядра. За последние 15 лет он прошёл путь от ifconfig/iptables к iproute2/nftables, от плоской конфигурации к network namespaces, от iptables-цепочек к eBPF/XDP-программам, работающим на уровне драйвера. Эта статья покрывает уровни от L2/L3-конфигурации до firewall'а и traffic control, с фокусом на архитектурные решения и причины, по которым одни инструменты вытесняют другие.
В отличие от FreeBSD, где сетевая конфигурация унифицирована (ifconfig + rc.conf + PF), в Linux существует несколько конкурирующих стеков конфигурации: NetworkManager, systemd-networkd, ifupdown, netplan — выбор зависит от дистрибутива и use case. Ядерные механизмы (iproute2, netfilter) при этом универсальны, и именно на них стоит фокусироваться для глубокого понимания.
Архитектура: iproute2 как единый интерфейс
Почему ip победил ifconfig
ifconfig (пакет net-tools) использует ioctl() и /proc/net для взаимодействия с ядром. Эти интерфейсы не развивались с 2000-х годов и не поддерживают: множественные адреса на интерфейсе без костылей (eth0:0 — virtual subinterfaces), policy-based routing, network namespaces, tunnels (GRE, VXLAN, WireGuard), современные метаданные интерфейсов.
iproute2 (команда ip) использует Netlink — сокетный API ядра, специально спроектированный для сетевого управления. Netlink асинхронный, поддерживает multicast-нотификации (подписка на изменения), и масштабируется значительно лучше. На системе со 128 интерфейсами ip addr show отрабатывает за ~16ms, тогда как ifconfig -a — за ~1.5s (разница в ~100x из-за множества open()/read() по /proc).
На современных дистрибутивах net-tools часто не установлен по умолчанию. Команда ip — единственный штатный инструмент для L2/L3-конфигурации.
Структура команды ip
ip организован по объектам, каждый из которых соответствует подсистеме ядра:
ip link — L2: интерфейсы, MTU, состояние (up/down), MAC, создание виртуальных интерфейсов (veth, bridge, vlan, vxlan, wireguard). ip addr (или ip a) — L3: IP-адреса на интерфейсах. Один интерфейс может иметь множество адресов. ip route — таблицы маршрутизации. Linux поддерживает множество таблиц (main, local, custom), выбор между которыми определяется ip rule. ip rule — policy routing: выбор таблицы маршрутизации на основе source IP, fwmark, incoming interface. ip neigh — ARP/NDP-таблица (замена arp). ip netns — управление network namespaces. ip tunnel, ip link add type <tunnel> — туннели (GRE, IPIP, sit, VXLAN, WireGuard).
Все команды поддерживают -j (JSON-вывод, с iproute2 4.13+), что делает ip пригодным для программного разбора без хрупкого awk/grep.
# JSON вывод для скриптов
ip -j -p addr show dev eth0
# Мониторинг изменений в реальном времени (netlink multicast)
ip monitor route # следить за изменениями маршрутов
ip monitor neigh # следить за ARP-таблицей
Конфигурация сети: три модели
Linux не имеет единого механизма конфигурации сети. Выбор определяется дистрибутивом и сценарием использования.
NetworkManager
Дефолт на десктопах (Fedora, Ubuntu Desktop, RHEL с GUI). Разработан Red Hat. Ориентирован на динамические среды: Wi-Fi, VPN, смена сетей, hotplug. Использует D-Bus API, имеет GUI (nm-applet, GNOME Settings) и CLI (nmcli, nmtui). Хранит конфиги в /etc/NetworkManager/ (connection profiles в /etc/NetworkManager/system-connections/).
nmcli — мощный инструмент, часто недооцённый:
nmcli device status # список интерфейсов
nmcli connection show # все профили подключения
nmcli connection add type ethernet ifname eth0 \
con-name "static" ipv4.method manual \
ipv4.addresses "192.168.1.100/24" \
ipv4.gateway "192.168.1.1" \
ipv4.dns "1.1.1.1"
nmcli connection up "static"
systemd-networkd
Часть systemd. Ориентирован на серверы и контейнеры: статическая конфигурация, предсказуемость, минимальные зависимости. Конфигурация через .network, .netdev, .link файлы в /etc/systemd/network/ (с приоритетом) или /usr/lib/systemd/network/ (дефолты пакетов).
# /etc/systemd/network/20-wired.network
[Match]
Name=en*
[Network]
Address=192.168.1.100/24
Gateway=192.168.1.1
DNS=1.1.1.1
DNS=8.8.8.8
systemd-networkd хорошо интегрирован с systemd-resolved (DNS) и systemd-networkd-wait-online (определение готовности сети). Не имеет GUI. Управление: networkctl list, networkctl status.
ifupdown и Netplan
ifupdown (/etc/network/interfaces) — классический механизм Debian. Прост, но ограничен: нет D-Bus API, плохая поддержка динамических изменений, отсутствие Wi-Fi без дополнительных инструментов. В Debian 13 сменился его DHCP-клиент: набор isc-dhcp объявлен устаревшим вслед за upstream, и связке с ifupdown теперь предлагается dhcpcd-base (NetworkManager и systemd-networkd несут собственные реализации DHCP и в пакете isc-dhcp-client не нуждаются).
Netplan (Ubuntu 17.10+) — YAML-фронтенд, генерирующий конфигурацию для NetworkManager или systemd-networkd:
# /etc/netplan/01-config.yaml
network:
version: 2
renderer: networkd
ethernets:
enp0s3:
addresses: [192.168.1.100/24]
routes:
- to: default
via: 192.168.1.1
nameservers:
addresses: [1.1.1.1]
Когда что использовать
NetworkManager — десктопы, ноутбуки, среды с Wi-Fi и VPN, где нужна динамическая смена подключений. systemd-networkd — серверы, контейнеры, embedded, где конфигурация статическая и предсказуемая. ifupdown — базовый механизм Debian, который никуда не делся: на современной системе под systemd networking.service поднимает lo, а остальными интерфейсами на десктопной установке управляет NetworkManager, причём NM намеренно не трогает интерфейсы, перечисленные в /etc/network/interfaces. Netplan — Ubuntu; абстракция над двумя вышеперечисленными, в Debian доступна отдельным пакетом netplan.io.
NetworkManager и systemd-networkd могут конфликтовать. На одной системе должен быть активен один из них. Если оба установлены, NetworkManager обычно берёт управление интерфейсами, которые не описаны в конфигурации networkd.
systemd-resolved: DNS-резолвинг
systemd-resolved — stub-резолвер, работающий на 127.0.0.53:53. Обеспечивает: кеширование DNS, DNSSEC-валидацию, split DNS (разные DNS-серверы для разных доменов — критически важно для VPN), DNS-over-TLS.
resolved различает четыре режима интеграции с /etc/resolv.conf. stub — симлинк на /run/systemd/resolve/stub-resolv.conf, где указан stub-резолвер и поисковые домены; рекомендуемый вариант. uplink — симлинк на /run/systemd/resolve/resolv.conf с реальными апстрим-серверами в обход stub'а. static — симлинк на неизменный /usr/lib/systemd/resolv.conf, в котором единственным сервером записан 127.0.0.53, а поисковых доменов нет. foreign — файл ведёт кто-то другой, и resolved сам читает его как источник конфигурации.
resolvectl status # текущие DNS-серверы по интерфейсам
resolvectl query example.com # тестовый запрос с диагностикой
resolvectl dns eth0 1.1.1.1 8.8.8.8 # задать DNS для интерфейса
resolvectl domain eth0 ~corp.local # split DNS: *.corp.local → DNS eth0
Gotcha: многие приложения (особенно в контейнерах) не используют NSS/resolved и делают DNS-запросы напрямую по адресу из /etc/resolv.conf. Если resolved не активен или /etc/resolv.conf указывает на недоступный сервер, DNS ломается. При использовании Docker совместно с resolved необходимо убедиться, что контейнеры видят 127.0.0.53 или имеют альтернативный DNS. Ровно для таких клиентов, идущих мимо локальных DNS API, resolved держит второй stub на 127.0.0.54: он работает в режиме прокси — без DNSSEC-валидации и без LLMNR/mDNS.
Network namespaces и виртуальные интерфейсы
Network namespaces — фундамент сетевой изоляции в Linux, на котором построены контейнеры (Docker, Podman, LXC — см. статью 6). Каждый namespace — изолированный сетевой стек: свои интерфейсы, маршруты, firewall-правила, /proc/net.
# Создание namespace и пары veth-интерфейсов
ip netns add ns1
ip link add veth0 type veth peer name veth1
ip link set veth1 netns ns1
# Конфигурация внутри namespace
ip addr add 10.0.0.1/24 dev veth0
ip link set veth0 up
ip netns exec ns1 ip addr add 10.0.0.2/24 dev veth1
ip netns exec ns1 ip link set veth1 up
# Проверка изоляции
ip netns exec ns1 ip route # видит только свою таблицу маршрутизации
Виртуальные интерфейсы, создаваемые через ip link add:
veth (virtual ethernet pair) — пара связанных интерфейсов, пакет, вошедший в один конец, выходит из другого. Основа подключения контейнеров к host network. bridge — программный L2-коммутатор. Docker по умолчанию создаёт bridge docker0 и подключает контейнеры через veth-пары. macvlan — виртуальный интерфейс с собственным MAC-адресом на физическом интерфейсе. Контейнер получает «свой» адрес в физической сети без NAT. ipvlan — как macvlan, но разделяет MAC хоста. Полезно когда коммутатор ограничивает MAC per port. vxlan — L2-over-UDP туннели для overlay-сетей (Flannel, Calico в VXLAN-mode). wireguard — VPN-интерфейс (с ядра 5.6 — in-tree модуль).
Firewall: nftables
Эволюция: ipchains → iptables → nftables
Все три поколения firewall'а в Linux построены на Netfilter — подсистеме ядра, предоставляющей hooks (точки перехвата) в сетевом стеке. nftables (с ядра 3.13, 2014) заменяет iptables, ip6tables, arptables и ebtables единым framework'ом.
Ключевые архитектурные отличия nftables от iptables:
Нет предопределённых таблиц и цепочек. iptables создаёт filter/INPUT, filter/FORWARD, nat/PREROUTING и т.д. даже если они не нужны — каждая неиспользуемая цепочка всё равно обходится при обработке пакета. В nftables администратор создаёт только нужные таблицы и цепочки.
Единый синтаксис для IPv4/IPv6. Семейство inet позволяет писать одно правило для обоих протоколов. В iptables нужны два раздельных набора правил (iptables + ip6tables).
Множество действий в одном правиле. iptables: одно правило — один target (-j ACCEPT). nftables: правило может одновременно считать пакеты, ставить mark и выносить verdict.
Sets и maps. Встроенные структуры данных для эффективного matching по множеству адресов/портов (аналог ipset, но native). Maps позволяют делать lookup: «если source IP в этом множестве, перенаправь на такой-то vmap target».
VM вместо hardcoded matching. iptables использует фиксированные match-модули в ядре. nftables компилирует правила в байткод для лёгкой VM ядра — это позволяет атомарные обновления правил и лучшую производительность на больших ruleset'ах.
Hooks (точки перехвата)
┌──────────┐
│ local │
│ processes │
└────┬─┬────┘
│ ↑
output input
│ │
─→ [ingress] → prerouting → routing → forward → postrouting →
decision
ingress — самый ранний hook, привязан к конкретному интерфейсу (с ядра 4.2). Пакеты ещё не дефрагментированы. prerouting → input — для пакетов, адресованных локальной системе. prerouting → forward → postrouting — для транзитных пакетов (роутер). output → postrouting — для пакетов, генерируемых локально.
Практика: базовый server firewall
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
chain input {
type filter hook input priority 0; policy drop;
# conntrack: разрешить established и related
ct state established,related accept
# loopback
iif lo accept
# ICMP (ping и прочее)
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# SSH
tcp dport 22 accept
# HTTP/HTTPS
tcp dport { 80, 443 } accept
# логировать и дропнуть остальное
log prefix "nft-drop: " counter drop
}
chain forward {
type filter hook forward priority 0; policy drop;
}
chain output {
type filter hook output priority 0; policy accept;
}
}
nft list ruleset # показать текущие правила
nft -f /etc/nftables.conf # загрузить из файла (атомарно)
nft add rule inet filter input tcp dport 8080 accept # добавить правило
nft -a list chain inet filter input # показать с handle-номерами
nft delete rule inet filter input handle 7 # удалить по handle
Миграция с iptables
На практике существуют три пути: нативный nftables (рекомендуется), iptables-nft (старый синтаксис, backend nf_tables — транзитный вариант), iptables-legacy (старый backend — deprecated). Debian 10+ и Fedora 32+ по умолчанию используют iptables-nft: при вызове iptables правила транслируются в nftables backend. Для полного перехода: iptables-save > rules.txt && iptables-restore-translate -f rules.txt > ruleset.nft.
XDP и eBPF-based networking
XDP (eXpress Data Path) — framework для обработки пакетов на уровне драйвера сетевой карты, до выделения sk_buff. Пакет обрабатывается eBPF-программой, которая может вернуть один из verdicts: XDP_PASS (передать в стек), XDP_DROP (отбросить), XDP_TX (отправить обратно), XDP_REDIRECT (перенаправить на другой интерфейс).
XDP работает на порядок быстрее nftables для простых задач (DDoS-mitigation, L4 load balancing) — миллионы pps на одном ядре. Cilium (CNI для Kubernetes) использует eBPF/XDP вместо iptables для service routing, network policy и load balancing. Это активно вытесняет kube-proxy (iptables-based) в production Kubernetes.
Подробнее о eBPF — в статье 10 (Мониторинг и отладка).
Traffic control (tc)
tc — инструмент для управления очередями и шейпинг трафика. Архитектура: qdisc (queueing discipline) привязывается к интерфейсу, внутри qdisc — classes и filters.
# Ограничить исходящую полосу до 100 Mbit/s на eth0
tc qdisc add dev eth0 root tbf rate 100mbit burst 32kbit latency 400ms
# Показать текущие qdiscs
tc qdisc show dev eth0
# fq_codel — default qdisc в современных ядрах (умное управление очередями)
tc qdisc replace dev eth0 root fq_codel
tc — глубокая тема, на уровне «знать что существует и где копать». Для большинства серверных задач достаточно знать, что fq_codel хорошо справляется с bufferbloat без ручной настройки и в типичной системе уже назначен qdisc'ом по умолчанию — но назначает его не ядро: собственный встроенный дефолт ядра по-прежнему pfifo_fast, а fq_codel прописывает дистрибутив через net.core.default_qdisc (systemd делает это в /usr/lib/sysctl.d/50-default.conf).
Сетевые tunables (/proc/sys/net/)
Ядро предоставляет сотни параметров в /proc/sys/net/. Наиболее важные:
# Форвардинг пакетов (роутер, Docker-хост)
sysctl net.ipv4.ip_forward=1
sysctl net.ipv6.conf.all.forwarding=1
# Защита от spoofing (reverse path filtering)
sysctl net.ipv4.conf.all.rp_filter=1 # strict mode
# TCP tuning для high-bandwidth links
sysctl net.core.rmem_max=16777216
sysctl net.core.wmem_max=16777216
sysctl net.ipv4.tcp_rmem="4096 131072 16777216"
sysctl net.ipv4.tcp_wmem="4096 16384 16777216"
# Количество подключений в backlog
sysctl net.core.somaxconn=65535
sysctl net.ipv4.tcp_max_syn_backlog=65535
# BBR congestion control (Google, лучше чем CUBIC на lossy links)
sysctl net.ipv4.tcp_congestion_control=bbr
sysctl net.core.default_qdisc=fq
Постоянная конфигурация — через файлы в /etc/sysctl.d/*.conf (см. статью 1). Подробнее о sysctl — в статье 5 (Ядро).
Нюансы и trade-off'ы
NetworkManager vs systemd-networkd — не только «десктоп vs сервер». NetworkManager в последних версиях отлично работает на серверах через nmcli и keyfile-backend. systemd-networkd проще, но не поддерживает Wi-Fi (нужен wpa_supplicant/iwd отдельно) и не имеет VPN-плагинов. На RHEL/Fedora серверах NetworkManager — дефолт и рекомендуемый вариант, даже без GUI.
nftables: atomic ruleset replacement. Ключевое преимущество перед iptables: nft -f rules.nft загружает весь ruleset атомарно — нет окна, когда часть правил применена, а часть нет. В iptables iptables-restore тоже близок к атомарности, но при ручном iptables -A каждая команда — отдельная транзакция с возможным race condition.
iptables-nft как ловушка. На системах с iptables-nft (Debian, Fedora) команды iptables и nft работают с одним и тем же backend — но видят правила по-разному. Правила, созданные через iptables, видны через nft list ruleset, но правила из nft не видны через iptables -L. Смешивание двух инструментов на одной системе — источник трудноотлаживаемых проблем.
ss вместо netstat. ss (socket statistics, часть iproute2) — замена netstat (часть net-tools). ss получает данные через netlink-интерфейс sock_diag, а разбор /proc/net остался в нём лишь запасным путём — отсюда и заметный выигрыш на системах с тысячами сокетов. Основные вызовы: ss -tlnp (TCP listen + PID), ss -s (summary), ss -i (TCP internal info, включая congestion window).
DNS и split horizon. systemd-resolved решает реальную проблему: при подключении к VPN нужно отправлять DNS-запросы для корпоративных доменов через VPN-tunnel, а остальные — через обычный DNS. Без resolved это требует хаков с dnsmasq или ручного управления /etc/resolv.conf. С resolved: resolvectl domain tun0 ~corp.local — элегантное решение.
Сравнение с FreeBSD
Конфигурация интерфейсов: FreeBSD использует ifconfig для всего — от IP-адресов до VLAN и bridge. В Linux ifconfig deprecated, вместо него ip. Фундаментальное отличие: FreeBSD ifconfig — часть base system, развивается вместе с ядром. Linux net-tools — заброшенный userspace-пакет, который не может использовать возможности ядра (netlink). Поэтому замена была неизбежна.
Firewall: FreeBSD предлагает PF (портирован из OpenBSD) — мощный, с лаконичным конфигурационным файлом и встроенным state tracking. Аналог в Linux — nftables, но с другой философией: PF конфигурируется плоским файлом с правилами, nftables — через nft CLI или файл с программируемыми таблицами/цепочками/sets. PF имеет pf.conf как единую точку конфигурации; nftables более гибок, но менее предсказуем для новичка. IPFW (ещё один firewall FreeBSD) ближе к iptables по модели: линейные правила с номерами.
Netgraph (FreeBSD) — модульный graph-based framework для обработки пакетов: узлы графа выполняют трансформации, пакеты проходят по рёбрам. Аналога в Linux нет — вместо этого используется комбинация tc + nftables + eBPF/XDP, каждый на своём уровне стека. Netgraph элегантнее концептуально, но менее производителен на high-traffic и менее широко используется.
Network namespaces в Linux не имеют прямого аналога в FreeBSD. Ближайшее — VNET (виртуализированный сетевой стек в jail), который даёт каждому jail'у собственные интерфейсы, маршруты и firewall. Функциональность похожа, но реализация принципиально другая: VNET дублирует весь стек, Linux namespaces — более лёгкая абстракция на уровне структур данных.
Источники
- iproute2 task-centered user guide — отличный практический справочник (Daniil Baturin)
- ip(8) — man page команды ip
- nftables wiki — официальная документация nftables
- Netfilter hooks — диаграмма хуков и приоритетов
- Moving from iptables to nftables — руководство по миграции
- systemd-networkd — формат .network файлов
- systemd-resolved — DNS-резолвер
- NetworkManager — ArchWiki — практическое руководство
- XDP — The Linux Foundation — документация ядра
- Benchmarking nftables — Red Hat — сравнение производительности nftables/iptables/tc
- Using iptables-nft — Red Hat — гибридный подход
- FreeBSD Handbook: Firewalls (PF) — для сравнения
Связанные заметки
- Linux — безопасность: hardening, SELinux/AppArmor — фильтрация трафика в общей модели защиты
- Linux — контейнеризация — сетевые namespace, veth и bridge
- Linux — справочник команд: сетевой стек — диагностические команды по сети
- FreeBSD — сеть — PF и ifconfig, для сравнения с nftables и ip
- Linux — сводный cheatsheet — быстрая справка по сетевым командам
- Обратный прокси и TLS: nginx vs Caddy — что открывать в firewall при публикации сервисов
- OpenVPN против WireGuard — маршруты в обход туннеля и раздельная маршрутизация
- Самохостинг за NAT: VPS как точка входа — прикладной сценарий: DNAT, форвардинг, policy routing и MSS-клампинг в сборе
- SSH углублённо — туннели
-L/-R/-Dповерх этого стека
Из библиотеки института уносят только знания. Читателей здесь не считают: посещение не регистрируется, отметок в издании не остаётся, счётчиков нет ни у одного издания фонда.
Издание пополняется и пересверяется. Текст доступен на условиях CC BY-SA 4.0 — унесённое можно передавать дальше на тех же условиях.