Сервис развивается: тестируем формат, собираем идеи, улучшаем сервис. Есть идеи? Написать
Дайджесты новостей
Изометрический вид высокопроизводительного сетевого шлюза Linux: визуализация пакетной фильтрации ядра Netfilter, светящиеся потоки пакетов IPv4 и IPv6 сходятся в единую матрицу Nftables со структурами поиска O(1)

Практическое руководство по переходу на Nftables: замена iptables в ядре Linux без сбоев и потери скорости

Два десятилетия сетевая фильтрация в Linux опиралась на стек Xtables: iptables для IPv4, ip6tables для IPv6, arptables для ARP и демон ipset для списков адресов. Разделение сетевого стека заставляло дублировать конфигурации: сервис, закрытый в таблицах IPv4, нередко оставался доступным извне по протоколу IPv6.

Подсистема nftables заменяет стек Xtables единой виртуальной машиной байткода Netfilter в ядре Linux под управлением утилиты nft. Новый инструмент объединяет обработку IPv4 и IPv6, заменяет линейный перебор правил структурами данных ядра и обеспечивает атомарное применение конфигураций.

Архитектура Nftables: таблицы, хуки и семейство inet

В отличие от iptables, где ядро создавало фиксированные таблицы filter и nat, в Nftables нет предустановленных структур: таблицы и цепочки создаются только при явном объявлении.

Иерархия объектов включает семейство протоколов, таблицу, цепочку и правило. Главное нововведение — семейство inet: созданная в нем таблица обрабатывает пакеты IPv4 и IPv6 общими правилами. Базовая цепочка (base chain) перехватывает трафик через хуки Netfilter: input для входящих пакетов хоста, forward для маршрутизации и output для локального трафика.

# Базовая структура таблицы inet с хуком входящего трафика
nft add table inet filter
nft add chain inet filter input '{ type filter hook input priority 0; }'

Параметр type filter определяет назначение цепочки, а priority 0 задает стандартный приоритет в ядре. Обычные цепочки без хука служат ветвлениями для инструкций jump или goto. Внутри семейства inet адресные выражения сохраняют протокольную специфику: для IPv4 используется ip saddr, а для IPv6 — ip6 saddr.

Подготовка сервера и сохранение удаленного доступа

Главный риск при миграции — потеря доступа по SSH. Ошибка в правиле способна заблокировать входящие пакеты и отрезать администратора от сервера.

Перед началом настройки выполните подготовительные действия:

  • Подготовьте резервный канал (out-of-band console): веб-консоль гипервизора, порт IPMI/KVM или серийный доступ.
  • Откройте две независимые сессии SSH: активные сеансы продолжат работу при смене правил, позволяя быстро исправить ошибку.
  • Проверьте утилиты командами iptables -V и ip6tables -V. Строка nf_tables указывает на слой совместимости iptables-nft, а legacy — на старые модули Xtables.
  • Сохраните резервные копии:
    sudo iptables-save > /root/iptables-backup.v4
    sudo ip6tables-save > /root/iptables-backup.v6
    sudo nft list ruleset > /root/nftables-backup.nft
    

Инструменты трансляции правил

Разработчики Netfilter создали официальные трансляторы. Утилита iptables-translate конвертирует единичные команды:

iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT

Команда выведет эквивалент для Nftables:

nft add rule ip filter INPUT tcp dport 22 ct state new counter accept

Пакетную конвертацию файла дампов выполняет iptables-restore-translate:

iptables-restore-translate -f /root/iptables-backup.v4 > /root/ruleset-migrated.nft

Вывод транслятора служит ориентиром, а не готовым решением: утилита сохраняет раздельные таблицы ip и ip6. Инженеру нужно объединить правила в структуру inet и оптимизировать списки адресов.

Пошаговый сценарий безопасного переключения

Миграция выполняется поэтапно, исключая случайную блокировку хоста.

1. Создание каркаса с политикой ACCEPT

Создайте файл /etc/nftables.conf.new с базовым набором правил, оставив политику по умолчанию в режиме accept:

table inet filter {
  chain input {
    type filter hook input priority 0; policy accept;
    iif lo accept
    ct state established,related accept
    tcp dport 22 ct state new accept
  }
}

Правило iif lo accept критично для локальных демонов и сокетов, а подсистема conntrack ct state established,related accept гарантирует прохождение ответов на исходящие запросы сервера.

2. Атомарная загрузка и проверка связности

В Nftables конфигурация загружается атомарно в рамках единой транзакции ядра:

sudo nft -f /etc/nftables.conf.new

При ошибке транзакция отклоняется целиком, а текущие правила ядра остаются неизменными. Проверить состояние позволяет sudo nft list ruleset.

Не закрывая открытых терминалов, проверьте новое SSH-подключение, разрешение DNS (host debian.org), доступность сервисов и связность по IPv6 (ping6 -c 2 2606:4700:4700::1111).

3. Переключение политики на DROP

После проверки доступности сервисов входящая цепочка переводится в режим сброса пакетов (policy drop). В командной строке bash требует экранирования точки с запятой:

sudo nft add chain inet filter input '{ type filter hook input priority 0; policy drop; }'

Безопаснее изменить строку на policy drop; в файле /etc/nftables.conf.new и повторно выполнить sudo nft -f /etc/nftables.conf.new. Сразу после применения проверьте новое SSH-соединение.

Структуры данных: Sets, Maps и вердиктные карты

Традиционный iptables проверял каждый пакет линейным перебором правил цепочки. Nftables переносит хранение адресов в оптимизированные структуры ядра.

Наборы (Sets) объявляются внутри таблицы и поддерживают строгую типизацию:

table inet filter {
  set blocked_ips {
    type ipv4_addr
    flags interval
    elements = { 192.0.2.1, 198.51.100.0/24 }
  }
  chain input {
    type filter hook input priority 0; policy drop;
    ip saddr @blocked_ips drop
  }
}

Флаг flags interval обязателен для подсетей и диапазонов адресов. Хотя наборы исключают линейный перебор тысяч правил, документация Netfilter не обещает строгого времени $O(1)$ для любых структур: единичные адреса хранятся в хэш-таблицах, а диапазоны используют деревья интервалов (rbtree) с логарифмическим поиском. Главный выигрыш — исполнение поиска в ядре без раздувания цепочек.

Вердиктные карты (vmap) сопоставляют ключ пакета с прямым действием (accept, drop, jump):

tcp dport vmap { 22 : accept, 80 : accept, 443 : accept }

Такая конструкция заменяет серию проверок портов единым выражением.

Управление правилами по дескрипторам Handle

В iptables правила удалялись по порядковым номерам строк: вставка строки сдвигала индексы в скриптах. Nftables адресует правила через handle — уникальный целочисленный номер, присваиваемый ядром при создании объекта.

Флаг -a (--handle) отображает дескрипторы:

sudo nft -a list chain inet filter input

Вывод покажет номер в комментарии (# handle 4). Зная дескриптор, администратор может точечно удалить правило:

sudo nft delete rule inet filter input handle 5

Или заменить его на месте:

sudo nft replace rule inet filter input handle 4 tcp dport 2222 ct state new accept

Дескриптор handle действителен только для текущего набора правил в памяти. При перезагрузке номера генерируются заново, поэтому автоматизация должна строиться на декларативных файлах.

Маршрутизация NAT и специфика контейнеров

Для серверов в роли шлюза трансляция сетевых адресов (masquerade) размещается в хуке postrouting:

table ip nat {
  chain postrouting {
    type nat hook postrouting priority 100; policy accept;
    oifname "eth0" masquerade
  }
}

В средах с Docker или Kubernetes демоны создают собственные цепочки через iptables-nft. Команда полной очистки nft flush ruleset уничтожит правила контейнеров и нарушит изоляцию приложений. Создавайте пользовательские фильтры в отдельной таблице inet custom_filter, не перезаписывая структуры контейнерных сред.

Персистентность и чеклист верификации

Для автоматической загрузки правил при старте ОС сохраните проверенную конфигурацию в системный файл:

sudo nft list ruleset > /etc/nftables.conf

Убедитесь, что в начале /etc/nftables.conf указана директива очистки старых правил:

#!/usr/sbin/nft -f
flush ruleset

Активируйте системную службу:

sudo systemctl enable --now nftables.service
sudo systemctl status nftables.service

Чеклист проверки перед завершением миграции:

  • Локальный трафик lo и сессии established,related безусловно разрешены.
  • Порт SSH открыт и проверен независимым подключением.
  • Наборы адресов со сложными диапазонами снабжены директивой flags interval.
  • В конфигурации отсутствуют конфликты с сетевыми цепочками Docker или Kubernetes.
  • Выполнена тестовая перезагрузка хоста с проверкой статуса systemctl is-active nftables.

Переход на Nftables устраняет фрагментацию сетевых политик между IPv4 и IPv6, защищает правила от коллизий индексов и переносит обслуживание списков адресов в оптимизированные структуры ядра Linux.