Переход с iptables на nftables: миграция правил firewall

Почему nftables заменяет iptables

Nftables — это замена iptables, ip6tables, arptables и ebtables, разработанная той же командой (Netfilter project). Начиная с Debian 11, CentOS/RHEL 8 и Ubuntu 22.04, nftables является фреймворком по умолчанию. Iptables всё ещё работает через compatibility layer (iptables-nft), но это временное решение.

Ключевые преимущества nftables:

  • Единый фреймворк — одна утилита nft вместо четырёх (iptables, ip6tables, arptables, ebtables)
  • Атомарные обновления — все правила применяются одновременно, нет промежуточных состояний
  • Лучшая производительность — sets и maps вместо длинных цепочек правил
  • Чистый синтаксис — читаемые правила без загадочных флагов
  • Нативная поддержка sets — группировки IP, портов, интерфейсов в именованные множества
  • Трассировка — встроенная отладка правил без tcpdump

Если вы устанавливаете новый сервер — используйте nftables. Если мигрируете существующий — эта статья поможет перенести правила.

Ключевые различия в концепциях

Nftables использует другую модель организации правил.

Таблицы и цепочки

В iptables таблицы (filter, nat, mangle) и цепочки (INPUT, OUTPUT, FORWARD) предопределены. В nftables вы создаёте их сами:

# iptables — предопределённые таблицы и цепочки
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT

# nftables — сначала создаём таблицу и цепочку
nft add table inet my_filter
nft add chain inet my_filter input { type filter hook input priority 0 \; policy drop \; }
nft add rule inet my_filter input tcp dport 22 accept

Семейства таблиц в nftables:

  • inet — IPv4 + IPv6 (рекомендуется, заменяет iptables + ip6tables)
  • ip — только IPv4
  • ip6 — только IPv6
  • arp — ARP (замена arptables)
  • bridge — мост (замена ebtables)
  • netdev — очень ранняя фильтрация на уровне драйвера

Сравнение синтаксиса

Таблица соответствия часто используемых правил:

iptablesnftables
iptables -A INPUT -p tcp --dport 80 -j ACCEPTnft add rule inet filter input tcp dport 80 accept
iptables -A INPUT -s 10.0.0.0/24 -j ACCEPTnft add rule inet filter input ip saddr 10.0.0.0/24 accept
iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPTnft add rule inet filter input ct state established,related accept
iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADEnft add rule inet nat postrouting oifname "eth0" masquerade
iptables -A INPUT -p tcp -m multiport --dports 80,443,8080 -j ACCEPTnft add rule inet filter input tcp dport { 80, 443, 8080 } accept

Обратите внимание: в nftables фигурные скобки { } используются для множеств (sets) — аналог -m multiport и -m iprange из iptables, но значительно мощнее.

Автоматическая конвертация правил

Для миграции существующих правил iptables используйте утилиту iptables-translate.

Утилита iptables-translate

Конвертация отдельных правил:

# Конвертация одного правила
iptables-translate -A INPUT -p tcp --dport 22 -s 10.0.0.0/24 -j ACCEPT
# Вывод: nft add rule ip filter INPUT ip saddr 10.0.0.0/24 tcp dport 22 counter accept

# Конвертация правила NAT
iptables-translate -t nat -A POSTROUTING -s 192.168.1.0/24 -o eth0 -j MASQUERADE
# Вывод: nft add rule ip nat POSTROUTING ip saddr 192.168.1.0/24 oifname "eth0" counter masquerade

Конвертация всего набора правил:

# Экспортируйте текущие правила
iptables-save > /tmp/iptables-rules.txt

# Конвертируйте в формат nftables
iptables-restore-translate -f /tmp/iptables-rules.txt > /tmp/nftables-rules.nft

# Проверьте результат
cat /tmp/nftables-rules.nft

# Примените (после проверки!)
nft -f /tmp/nftables-rules.nft

Важно: автоматическая конвертация не всегда идеальна. Проверьте каждое правило, особенно сложные конструкции с -m string, -m recent и custom chains.

Базовая конфигурация nftables

Настроим полноценный firewall с нуля, используя конфигурационный файл.

Конфигурационный файл nftables

Основной конфиг — /etc/nftables.conf:

#!/usr/sbin/nft -f

# Очистка всех правил
flush ruleset

# === Таблица inet filter (IPv4 + IPv6) ===
table inet filter {

    # Доверенные IP
    set trusted_ips {
        type ipv4_addr
        elements = { 10.0.0.0/24, 192.168.1.0/24 }
    }

    # Разрешённые TCP-порты
    set allowed_tcp_ports {
        type inet_service
        elements = { 22, 80, 443 }
    }

    chain input {
        type filter hook input priority 0; policy drop;

        # Loopback
        iifname "lo" accept

        # Established/related
        ct state established,related accept

        # Отбрасываем invalid
        ct state invalid drop

        # ICMP (ping)
        ip protocol icmp accept
        ip6 nexthdr icmpv6 accept

        # Разрешённые порты
        tcp dport @allowed_tcp_ports accept

        # SSH только с доверенных IP
        ip saddr @trusted_ips tcp dport 22 accept

        # Логирование отброшенного трафика
        limit rate 5/minute log prefix "nft-drop: " level warn

        # Счётчик отброшенных пакетов
        counter drop
    }

    chain forward {
        type filter hook forward priority 0; policy drop;
    }

    chain output {
        type filter hook output priority 0; policy accept;
    }
}

Применение и проверка:

# Проверка синтаксиса (dry-run)
nft -c -f /etc/nftables.conf

# Применить
sudo nft -f /etc/nftables.conf

# Включить автозагрузку
sudo systemctl enable nftables

# Просмотреть текущие правила
nft list ruleset

Именованные множества (sets) и maps

Sets — одна из самых мощных возможностей nftables, недоступная в iptables.

Динамические sets

Создайте set, который можно обновлять без перезагрузки правил:

# Объявление в конфиге
table inet filter {
    set blacklist {
        type ipv4_addr
        flags timeout
        timeout 24h
    }

    chain input {
        type filter hook input priority 0; policy drop;
        ip saddr @blacklist drop
        # ... остальные правила
    }
}

Управление set через командную строку:

# Добавить IP в blacklist
nft add element inet filter blacklist { 203.0.113.50 }

# Добавить с таймаутом
nft add element inet filter blacklist { 198.51.100.10 timeout 1h }

# Удалить IP
nft delete element inet filter blacklist { 203.0.113.50 }

# Просмотреть содержимое
nft list set inet filter blacklist

Это идеально для интеграции с fail2ban или скриптами блокировки.

Verdict maps для маршрутизации решений

Maps позволяют задать разные действия для разных значений:

# Map: порт → действие
table inet filter {
    map port_policy {
        type inet_service : verdict
        elements = {
            22 : accept,
            80 : accept,
            443 : accept,
            3306 : drop,
            5432 : drop
        }
    }

    chain input {
        type filter hook input priority 0; policy drop;
        ct state established,related accept
        tcp dport vmap @port_policy
    }
}

Concatenated sets — фильтрация по комбинации полей:

# Разрешить конкретные IP на конкретные порты
set allowed_access {
    type ipv4_addr . inet_service
    elements = {
        10.0.0.5 . 22,
        10.0.0.10 . 3306,
        10.0.0.15 . 5432
    }
}

chain input {
    ip saddr . tcp dport @allowed_access accept
}

NAT в nftables

NAT в nftables настраивается в отдельной таблице (или цепочке с hook nat).

SNAT и MASQUERADE

Типичная настройка маршрутизатора с NAT:

table inet nat {
    chain prerouting {
        type nat hook prerouting priority dstnat; policy accept;

        # Port forwarding: внешний порт 8080 → внутренний 10.0.0.5:80
        tcp dport 8080 dnat ip to 10.0.0.5:80

        # Port forwarding: внешний 2222 → внутренний SSH
        tcp dport 2222 dnat ip to 10.0.0.10:22
    }

    chain postrouting {
        type nat hook postrouting priority srcnat; policy accept;

        # Masquerade для всей внутренней сети
        ip saddr 10.0.0.0/24 oifname "eth0" masquerade

        # Или SNAT с конкретным IP
        # ip saddr 10.0.0.0/24 oifname "eth0" snat to 203.0.113.1
    }
}

Не забудьте включить IP forwarding:

echo 'net.ipv4.ip_forward = 1' | sudo tee /etc/sysctl.d/99-forward.conf
sudo sysctl -p /etc/sysctl.d/99-forward.conf

И разрешить forward в таблице filter:

chain forward {
    type filter hook forward priority 0; policy drop;
    ct state established,related accept
    iifname "eth1" oifname "eth0" accept  # LAN → WAN
}

Трассировка и отладка правил

Nftables имеет встроенную трассировку — мощнейший инструмент отладки, которого не было в iptables.

Включение трассировки

Добавьте meta-правило для трассировки интересующего трафика:

# Трассировка SSH-трафика
nft add rule inet filter input tcp dport 22 meta nftrace set 1

# Включите мониторинг
nft monitor trace

Вывод покажет путь пакета через все цепочки и правила:

trace id a1b2c3 inet filter input packet: iif "eth0" ip saddr 10.0.0.5 ip daddr 10.0.0.1 tcp dport 22
trace id a1b2c3 inet filter input rule tcp dport 22 meta nftrace set 1 (verdict continue)
trace id a1b2c3 inet filter input rule tcp dport @allowed_tcp_ports accept (verdict accept)

Для отладки без трассировки используйте счётчики:

# Добавить счётчик к правилу
nft add rule inet filter input tcp dport 443 counter accept

# Просмотреть счётчики
nft list chain inet filter input
# Покажет: counter packets 1523 bytes 234567

Логирование с лимитом:

# Логировать не более 3 пакетов в минуту
nft add rule inet filter input tcp dport 22 ct state new limit rate 3/minute log prefix "SSH-new: " accept

Просмотр логов:

journalctl -k --grep 'nft-drop\|SSH-new' --since '10 min ago'

Интеграция с fail2ban

Fail2ban поддерживает nftables как бэкенд. Настройте его для использования nftables вместо iptables:

# /etc/fail2ban/jail.local
[DEFAULT]
banaction = nftables-multiport
banaction_allports = nftables-allports

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600

Fail2ban автоматически создаст таблицу и set для заблокированных IP. Проверьте:

# После бана
nft list table inet f2b-table
# Покажет set с заблокированными IP

Для использования вашего собственного set с fail2ban создайте кастомный action:

# /etc/fail2ban/action.d/nftables-set.local
[Definition]
actionban = nft add element inet filter blacklist { <ip> timeout <bantime>s }
actionunban = nft delete element inet filter blacklist { <ip> }

Часто задаваемые вопросы

Технически да — команды iptables работают через compatibility layer (iptables-nft), который транслирует правила в nftables. Но смешивать не рекомендуется: правила iptables-nft и нативные nftables могут конфликтовать. При миграции переведите все правила на nftables, затем удалите iptables-совместимые пакеты: apt remove iptables.

Правила загружаются из файла /etc/nftables.conf при старте сервиса: systemctl enable nftables. Для сохранения текущих правил в файл: nft list ruleset > /etc/nftables.conf. Убедитесь, что в начале файла есть строка flush ruleset, чтобы при загрузке старые правила очищались.

В /etc/fail2ban/jail.local замените banaction = iptables-multiport на banaction = nftables-multiport. Перезапустите fail2ban: systemctl restart fail2ban. Fail2ban автоматически создаст nftables-таблицу для блокировок. Проверьте: nft list tables | grep f2b.

Некоторые модули iptables не имеют прямого аналога в nftables. Например, -m string (поиск по содержимому пакета) в nftables реализован через @th и raw payload matching. Модуль -m recent заменяется динамическими sets с timeout и meters. Для сложных случаев ищите эквивалент в документации nftables wiki или используйте nft scripting для программной генерации правил.

Nftables обычно работает быстрее iptables, особенно при большом количестве правил. Iptables проверяет правила линейно (O(n)), nftables использует sets и maps с хеш-таблицами (O(1) для поиска). Для firewall с сотнями IP в блоклисте nftables с set будет на порядок быстрее, чем iptables с цепочкой из сотен правил DROP.

Нужна помощь с настройкой?

Специалисты АйТи Фреш помогут с внедрением и настройкой — 15+ лет опыта, обслуживание от 15 000 ₽/мес

📞 Связаться с нами
#nftables настройка#iptables миграция nftables#nftables правила#nftables linux firewall#nftables nat#nftables синтаксис#nftables таблицы цепочки#замена iptables
Комментарии 0

Оставить комментарий

загрузка...