Два десятилетия сетевая фильтрация в 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.
