Миграция с iptables на nftables: пошаговый план без простоев
Меня зовут Семёнов Евгений Сергеевич, директор АйТи Фреш. За 15+ лет администрирования Linux-серверов я переписывал правила firewall сотни раз. Долго отбрыкивался от nftables, пока не убедился: правила читаются в разы лучше, производительность выше, а управление наборами IP-адресов через именованные sets упрощает жизнь так, что жалеешь о годах, потраченных на iptables. В этом гайде — как мигрировать сервер без простоя, сохранив все существующие правила.
Почему nftables — это серьёзно
iptables появился в Linux 2.4 в 2001 году. С тех пор ядро изменилось радикально, а iptables остался с прежней архитектурой: отдельные команды для IPv4, IPv6, arp, bridge; каждое правило — отдельный syscall; добавление 10 000 правил — минуты ожидания. nftables пришёл в 2014 году как единый современный framework и с 2019-го — стандарт в большинстве дистрибутивов.
Что даёт nftables на практике:
- Единый синтаксис для всех протоколов — одна таблица обрабатывает IPv4 и IPv6.
- Atomic rule replacement — весь набор правил обновляется одной транзакцией.
- Sets и maps — именованные коллекции IP/портов/интерфейсов с константным временем поиска.
- Concatenation — правило может сравнивать сразу несколько полей (tuples).
- Vmap/dictionaries — маршрутизация по ключу без цепочек if-then.
Подготовка к миграции
Первое правило: никогда не мигрируйте удалённо без out-of-band доступа. У нас на практике один инженер потерял доступ к серверу в Нидерландах из-за опечатки в правиле DROP для SSH. Пришлось ехать в дата-центр за 2000 километров. С тех пор я всегда настраиваю KVM-консоль или IPMI перед миграцией.
Сохраняем текущее состояние:
sudo iptables-save > /root/iptables-backup-$(date +%F).rules
sudo ip6tables-save > /root/ip6tables-backup-$(date +%F).rules
# Проверяем, какой backend сейчас используется
update-alternatives --display iptables
# Должно показать /usr/sbin/iptables-legacy или iptables-nft
В современных Ubuntu/Debian команда iptables — это обёртка над nftables (iptables-nft). Правила работают через nftables backend, но синтаксис остаётся старый. Настоящая миграция — это переписать правила на нативный синтаксис nftables.
Автоматическая конвертация
Для стартового скелета используем iptables-restore-translate:
sudo iptables-save > /tmp/iptables.rules
sudo iptables-restore-translate -f /tmp/iptables.rules > /tmp/nftables-draft.nft
cat /tmp/nftables-draft.nft
Важно: результат редко готов к использованию как есть. Утилита делает однозначную конвертацию, но не оптимизирует под новые возможности nftables. Я использую её как черновик, который потом переписываю с использованием sets, maps и вложенных цепочек.
Базовая структура nftables-конфига
Файл /etc/nftables.conf имеет вложенную структуру: таблицы → цепочки → правила.
#!/usr/sbin/nft -f
flush ruleset
table inet filter {
# Общие наборы адресов
set ssh_allowed {
type ipv4_addr
flags interval
elements = {
192.168.10.0/24,
10.10.0.0/16,
203.0.113.45
}
}
chain input {
type filter hook input priority filter; policy drop;
# Loopback
iif lo accept
ct state established,related accept
ct state invalid drop
# ICMP
ip protocol icmp accept
ip6 nexthdr icmpv6 accept
# SSH только с доверенных сетей
tcp dport 22 ip saddr @ssh_allowed accept
tcp dport 22 log prefix "SSH-drop: " drop
# Web
tcp dport {80, 443} accept
# Остальное — лог и drop
counter log prefix "INPUT-drop: " drop
}
chain forward {
type filter hook forward priority filter; policy drop;
}
chain output {
type filter hook output priority filter; policy accept;
}
}
Обратите внимание: одна таблица inet filter обрабатывает и IPv4, и IPv6 одновременно. В iptables для этого пришлось бы делать два параллельных набора правил.
NAT и port forwarding
Для прокси-серверов и NAT-роутеров нужна отдельная таблица с nat-цепочками:
table inet nat {
chain prerouting {
type nat hook prerouting priority dstnat; policy accept;
# Port forwarding: внешний 2222 -> внутренний 192.168.10.5:22
iif "eth0" tcp dport 2222 dnat ip to 192.168.10.5:22
}
chain postrouting {
type nat hook postrouting priority srcnat; policy accept;
# MASQUERADE для исходящего трафика локальной сети
oif "eth0" ip saddr 192.168.10.0/24 masquerade
}
}
Сравнение синтаксиса iptables vs nftables
| Задача | iptables | nftables |
|---|---|---|
| Разрешить SSH | -A INPUT -p tcp --dport 22 -j ACCEPT | tcp dport 22 accept |
| Множество портов | -m multiport --dports 80,443 | tcp dport {80, 443} accept |
| Лимит на соединения | -m limit --limit 10/min | limit rate 10/minute |
| Сохранение правил | iptables-save | nft list ruleset |
| Добавить IP в блэклист | ipset + iptables -m set | add element inet filter blacklist {1.2.3.4} |
| Логирование | -j LOG --log-prefix | log prefix "..." |
Продвинутые возможности: sets и maps
Sets — это именованные коллекции с возможностью атомарного обновления. Идеальны для динамического блэклиста:
table inet filter {
set blacklist_v4 {
type ipv4_addr
flags timeout
}
chain input {
type filter hook input priority filter; policy drop;
ip saddr @blacklist_v4 drop
# ... остальные правила
}
}
# Добавить IP в блэклист с таймаутом 1 час
nft add element inet filter blacklist_v4 { 198.51.100.42 timeout 1h }
# Посмотреть текущий блэклист
nft list set inet filter blacklist_v4
Maps идут дальше: можно делать маршрутизацию или DNAT по словарю:
map port_forward {
type inet_service : ipv4_addr . inet_service
elements = {
2222 : 192.168.10.5 . 22,
8080 : 192.168.10.6 . 80,
8443 : 192.168.10.7 . 443
}
}
chain prerouting {
type nat hook prerouting priority dstnat;
iif "eth0" tcp dport vmap @port_forward dnat ip to
}
Защита от DDoS и брутфорса
nftables упрощает популярные сценарии защиты. Пример: лимитируем SSH-попытки и баним IP при превышении:
table inet filter {
set ssh_banned {
type ipv4_addr
flags timeout
timeout 1h
}
chain input {
type filter hook input priority filter; policy drop;
# Забаненные — сразу drop
ip saddr @ssh_banned drop
# Больше 5 новых SSH-соединений в минуту — бан
tcp dport 22 ct state new \
add @ssh_banned { ip saddr limit rate over 5/minute } drop
tcp dport 22 accept
}
}
Кейс: миграция шлюза в офисе на 80 сотрудников
В феврале 2025 мы переводили Linux-шлюз клиента — дизайн-студия на 80 человек в Москве — с Debian 10 + iptables на Debian 12 + nftables. Сервер HP ProLiant DL360 Gen9 с Xeon E5-2620 v4, 32 ГБ RAM, в дата-центре МТС. На нём крутились: NAT для локальной сети 10.20.0.0/16, OpenVPN-сервер, ProxyChains, 14 правил port-forward для внутренних сервисов.
Старый конфиг — 340 строк iptables, никто не помнил, зачем половина правил. Сделали iptables-restore-translate, получили 290 строк черновика. За 6 часов переписали на нативный nftables с использованием sets для белых списков, map для port-forward, единой таблицей inet для IPv4+IPv6. Итог — 180 строк, всё задокументировано. Производительность NAT: с 1.8 Gbps до 2.4 Gbps на том же железе. Время применения правил с 2.3 секунд до 0.1 секунды. Миграция прошла без простоя — атомарно подменили ruleset в пятницу вечером. Стоимость работ: 35 000 руб.
Сохранение и автозагрузка
Правила сохраняются в /etc/nftables.conf, служба nftables.service загружает их при старте:
# Применить текущий набор в файл
sudo nft list ruleset > /etc/nftables.conf
# Включить автозагрузку
sudo systemctl enable --now nftables
# Проверка после ребута
sudo nft list ruleset
Грабли и типичные ошибки
- Забыли про IPv6. Если таблица только
ip, IPv6-трафик не фильтруется. Используйтеinetили добавьте таблицуip6. - Policy drop без established. Поставили policy drop на input/forward, забыли про ct state established,related — сервер перестал отвечать на собственные соединения.
- Конфликт с firewalld/ufw. Убедитесь, что высокоуровневые обёртки отключены:
systemctl disable firewalld ufw. - Docker пересобирает свои правила. После перезапуска Docker добавляет свои цепочки. Используйте DOCKER_USER для пользовательских правил.
- Нет счётчиков. Для отладки добавляйте
counterв правила — тогдаnft list rulesetпокажет, какие правила срабатывают и сколько раз.
Мигрируем ваш firewall на nftables без простоев
Перепишем правила iptables на nativный nftables с использованием sets, maps, логированием и счётчиками. Документация, откат-план, нагрузочное тестирование. Работаем с Debian, Ubuntu, Rocky, Alpine.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — частые вопросы о миграции
- Зачем переходить с iptables на nftables?
- Выше производительность, единый синтаксис для IPv4/IPv6, именованные объекты, атомарные обновления.
- Можно ли использовать iptables и nftables одновременно?
- Технически да, но лучше мигрировать полностью — отладка иначе превращается в кошмар.
- Как мигрировать существующие правила iptables?
- iptables-save | iptables-restore-translate -f - > nftables-draft.nft, потом ручная доработка.
- Поддерживают ли Docker и K8s nftables?
- Docker 24+ и K8s 1.29+ имеют nftables backend. По умолчанию многие используют iptables-nft обёртку.
- Как вернуться обратно на iptables при проблемах?
- Сохраните iptables-save в файл, остановите nftables, восстановите старые правила через iptables-restore.
