---
tags: [linux, network]
verified: 2026-09-02
---

# Linux — сеть: стек, конфигурация, firewall

## Обзор

Сетевой стек 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.

```bash
# 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 — мощный инструмент, часто недооцённый:

```bash
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/ (дефолты пакетов).

```ini
# /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:

```yaml
# /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 сам читает его как источник конфигурации.

```bash
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.

```bash
# Создание 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 (точки перехвата)

```text
                                    ┌──────────┐
                                    │  local    │
                                    │ processes │
                                    └────┬─┬────┘
                                         │ ↑
                                    output input
                                         │ │
─→ [ingress] → prerouting → routing → forward → postrouting →
                  decision
```

ingress — самый ранний hook, привязан к конкретному интерфейсу (с ядра 4.2). Пакеты ещё не дефрагментированы. prerouting → input — для пакетов, адресованных локальной системе. prerouting → forward → postrouting — для транзитных пакетов (роутер). output → postrouting — для пакетов, генерируемых локально.

### Практика: базовый server firewall

```bash
#!/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;
    }
}
```

```bash
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.

```bash
# Ограничить исходящую полосу до 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/. Наиболее важные:

```bash
# Форвардинг пакетов (роутер, 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](https://baturin.org/docs/iproute2/) — отличный практический справочник (Daniil Baturin)
- [ip(8)](https://man7.org/linux/man-pages/man8/ip.8.html) — man page команды ip
- [nftables wiki](https://wiki.nftables.org/) — официальная документация nftables
- [Netfilter hooks](https://wiki.nftables.org/wiki-nftables/index.php/Netfilter_hooks) — диаграмма хуков и приоритетов
- [Moving from iptables to nftables](https://wiki.nftables.org/wiki-nftables/index.php/Moving_from_iptables_to_nftables) — руководство по миграции
- [systemd-networkd](https://www.freedesktop.org/software/systemd/man/latest/systemd.network.html) — формат .network файлов
- [systemd-resolved](https://www.freedesktop.org/software/systemd/man/latest/systemd-resolved.service.html) — DNS-резолвер
- [NetworkManager — ArchWiki](https://wiki.archlinux.org/title/NetworkManager) — практическое руководство
- [XDP — The Linux Foundation](https://www.kernel.org/doc/html/latest/networking/af_xdp.html) — документация ядра
- [Benchmarking nftables — Red Hat](https://developers.redhat.com/blog/2017/04/11/benchmarking-nftables) — сравнение производительности nftables/iptables/tc
- [Using iptables-nft — Red Hat](https://www.redhat.com/en/blog/using-iptables-nft-hybrid-linux-firewall) — гибридный подход
- FreeBSD Handbook: [Firewalls (PF)](https://docs.freebsd.org/en/books/handbook/firewalls/) — для сравнения

---

## Связанные заметки

- [Linux — безопасность: hardening, SELinux/AppArmor](./linux-security-hardening.md) — фильтрация трафика в общей модели защиты
- [Linux — контейнеризация](./linux-containerization.md) — сетевые namespace, veth и bridge
- [Linux — справочник команд: сетевой стек](./linux-tldr-network.md) — диагностические команды по сети
- [FreeBSD — сеть](./freebsd-networking.md) — PF и ifconfig, для сравнения с nftables и ip
- [Linux — сводный cheatsheet](./linux-map-cheatsheet.md) — быстрая справка по сетевым командам
- [Обратный прокси и TLS: nginx vs Caddy](./reverse-proxy-tls.md) — что открывать в firewall при публикации сервисов
- [OpenVPN против WireGuard](./openvpn-vs-wireguard.md) — маршруты в обход туннеля и раздельная маршрутизация
- [Самохостинг за NAT: VPS как точка входа](./selfhosting-behind-nat.md) — прикладной сценарий: DNAT, форвардинг, policy routing и MSS-клампинг в сборе
- [SSH углублённо](./ssh-advanced.md) — туннели `-L`/`-R`/`-D` поверх этого стека
