LinuxRuLinux без лишней теории
Сеть и безопасность

Nftables: понятный firewall для домашнего компьютера и сервера

Редакция LinuxRu8 мин чтенияИнструкции

Nftables в Linux настраивается одним файлом /etc/nftables.conf: таблица inet, цепочка input с политикой drop и явные разрешения для нужных портов. Ниже готовые конфиги для домашнего ПК и сервера, способ применить их с автоматическим откатом и разбор конфликтов с Docker и firewalld.

Nftables: понятный firewall для домашнего компьютера и сервера
Фото: MSDN.WhiteKnight, CC0, Wikimedia Commons
Содержание
  1. Зачем nftables
  2. Что уже стоит
  3. Как устроено
  4. Домашний ПК
  5. Сервер
  6. Применение
  7. Правила на лету
  8. Docker и другие
  9. Диагностика
  10. Частые вопросы

Что такое nftables и почему iptables уже в прошлом

nftables это подсистема фильтрации пакетов в ядре Linux и утилита nft для управления ею. Она пришла на смену iptables, ip6tables, arptables и ebtables: вместо четырёх инструментов с разным синтаксисом одна команда и один формат правил.

Что это даёт на практике:

  • Семейство inet обрабатывает IPv4 и IPv6 одной таблицей, правила не нужно дублировать.
  • Множества и словари: список портов или адресов в фигурных скобках вместо десятка одинаковых правил.
  • Атомарная загрузка: файл конфигурации применяется целиком или не применяется вовсе, полуприменённого состояния не бывает.
  • Читаемый конфиг, который удобно держать в git.

Даже если вы пользуетесь ufw или firewalld, под капотом у них в современных дистрибутивах уже nftables. Команда iptables в Debian 13, Ubuntu 26.04 и Fedora 44 тоже чаще всего вариант iptables-nft, который переводит старый синтаксис в правила nftables.

Какой firewall уже работает в вашем дистрибутиве

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

ДистрибутивПо умолчаниюФайл для nftablesЧто сделать перед переходом
Debian 13пакет nftables стоит, служба выключена/etc/nftables.confничего, просто включить службу
Ubuntu 26.04ufw установлен, но неактивен/etc/nftables.confубедиться, что ufw status показывает inactive
Fedora 44firewalld активен/etc/sysconfig/nftables.confвыключить firewalld
Arch Linuxничего не настроено/etc/nftables.confпоставить пакет nftables
# текущие правила ядра
sudo nft list ruleset

# кто управляет firewall
systemctl is-active firewalld ufw nftables

# установка, если пакета нет
sudo apt install nftables     # Debian, Ubuntu
sudo dnf install nftables     # Fedora
sudo pacman -S nftables       # Arch

В Fedora firewalld удобен для ноутбука, который ходит между сетями: зоны переключаются вместе с подключением. Если хотите свой конфиг, выключите его командой sudo systemctl disable --now firewalld, иначе он перетрёт ваши таблицы при следующем запуске.

Как устроены правила: таблицы, цепочки и политика

Таблица

Контейнер для цепочек. У таблицы есть семейство: ip, ip6, inet (оба протокола), arp, bridge, netdev. Для обычного компьютера и сервера почти всегда хватает одной таблицы inet.

Базовая цепочка и хук

Цепочка с типом и хуком подключается к определённой точке прохождения пакета: input для входящего на сам компьютер, output для исходящего, forward для транзитного (маршрутизатор, контейнеры, виртуальные машины). Приоритет определяет порядок, если на одном хуке висит несколько цепочек.

Политика и порядок правил

Правила проверяются сверху вниз до первого окончательного решения accept или drop. Если ни одно не сработало, применяется политика цепочки. Классическая схема для входящего трафика: политика drop и явный список разрешений.

Готовый конфиг для домашнего компьютера

Задача: никаких входящих подключений, кроме ответов на свои запросы. Исходящий трафик не ограничиваем.

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

table inet filter {
    chain input {
        type filter hook input priority filter; policy drop;

        ct state established,related accept
        ct state invalid drop
        iif "lo" accept

        # ping и служебный ICMPv6, без него ломается IPv6
        meta l4proto { icmp, ipv6-icmp } accept

        # обнаружение принтеров и общих папок в локальной сети
        udp dport 5353 ip saddr 192.168.0.0/16 accept
    }

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

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

Строка flush ruleset в начале очищает всё, что было загружено раньше, поэтому файл можно применять повторно. Правило для порта 5353 (mDNS) нужно, если вы печатаете на сетевой принтер или ищете устройства в сети, иначе удалите его. Если вы пользуетесь KDE Connect или GSConnect, добавьте tcp dport 1714-1764 accept и udp dport 1714-1764 accept.

Правила для сервера: SSH, веб и белые списки

Для VPS или домашнего сервера добавляем открытые службы, ограничение частоты новых SSH-подключений и множество доверенных адресов.

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

table inet filter {
    set admin_nets {
        type ipv4_addr
        flags interval
        elements = { 192.168.1.0/24, 203.0.113.10 }
    }

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

        ct state established,related accept
        ct state invalid drop
        iif "lo" accept
        meta l4proto { icmp, ipv6-icmp } accept

        # SSH: из доверенных сетей без ограничений
        ip saddr @admin_nets tcp dport 22 accept
        # остальным не больше 10 новых попыток в минуту
        tcp dport 22 ct state new limit rate 10/minute accept

        # веб-сервер
        tcp dport { 80, 443 } accept

        # WireGuard
        udp dport 51820 accept

        # записать в журнал отброшенное, не чаще 5 строк в минуту
        limit rate 5/minute log prefix "nft drop: "
    }

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

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

Адреса в admin_nets замените на свои. Ограничение частоты защищает от перебора паролей лишь частично, основная защита в ключах и запрете входа по паролю, это разобрано в статье о защите SSH-сервера. Если сервер работает как VPN-шлюз, цепочку forward придётся открыть для туннеля, пример есть в инструкции по WireGuard.

Как применить правила и не потерять доступ по SSH

Самая частая авария: политика drop применена раньше, чем разрешение для SSH, и сервер больше не отвечает. Действуйте в таком порядке.

  1. Проверьте синтаксис без применения: sudo nft -c -f /etc/nftables.conf. Ошибка будет показана с номером строки.
  2. Сохраните текущий рабочий набор правил в файл отката.
  3. Запланируйте автоматический откат через две минуты.
  4. Примените новый файл и проверьте подключение из второго окна терминала.
  5. Если всё работает, отмените откат.
# 2. сохранить текущее состояние
echo 'flush ruleset' | sudo tee /root/nft-rollback.conf
sudo nft list ruleset | sudo tee -a /root/nft-rollback.conf

# 3. откат через 120 секунд, если ничего не отменить
sudo systemd-run --on-active=120 --unit=nft-rollback nft -f /root/nft-rollback.conf

# 4. применить новые правила
sudo nft -f /etc/nftables.conf

# 5. доступ есть, отменяем откат
sudo systemctl stop nft-rollback.timer

# включить загрузку правил при старте системы
sudo systemctl enable --now nftables

В Fedora служба nftables читает /etc/sysconfig/nftables.conf, а не /etc/nftables.conf. Работу со службами и их журналами подробнее описывает статья про systemctl.

Перед первым включением политики drop на удалённой машине откройте веб-консоль хостинга или убедитесь, что у вас есть физический доступ. Таймер отката спасает от ошибки в правилах, но не от опечатки в самом таймере.

Добавить, вставить и удалить правило без правки файла

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

# добавить в конец цепочки
sudo nft add rule inet filter input tcp dport 8080 accept

# вставить в начало цепочки
sudo nft insert rule inet filter input ip saddr 198.51.100.7 drop

# показать правила с номерами handle
sudo nft -a list chain inet filter input

# удалить правило по номеру handle
sudo nft delete rule inet filter input handle 12

# добавить адрес в множество
sudo nft add element inet filter admin_nets { 10.8.0.0/24 }

Сохранить текущее состояние в файл можно так: sudo nft list ruleset с перенаправлением в конфиг, но не забудьте вернуть строку flush ruleset первой. Старые правила iptables переводятся командой iptables-translate, например iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT.

Docker, libvirt и firewalld: где ждать конфликтов

  • Docker создаёт свои таблицы для NAT и публикации портов. Строка flush ruleset их удалит, после перезагрузки правил выполните sudo systemctl restart docker. Опубликованные порты контейнеров идут через цепочку forward, а не input, поэтому правило drop в input их не закроет. Слушайте сервис на 127.0.0.1 или публикуйте порт как 127.0.0.1:8080:80. В Docker 29 появился экспериментальный режим "firewall-backend": "nftables" в daemon.json, но таблицы Docker в любом случае лучше не править руками. Вариант без root описан в статье про Docker Rootless.
  • libvirt и Podman также добавляют собственные таблицы для сетей виртуальных машин и контейнеров. Вместо глобального flush ruleset можно очищать только свою таблицу: flush table inet filter и затем описание таблицы.
  • firewalld и ufw не используйте одновременно с собственным конфигом. Выберите один инструмент.

Диагностика: счётчики, журнал и трассировка пакета

Если что-то не проходит, добавьте к подозрительному правилу слово counter и посмотрите, растут ли цифры:

sudo nft add rule inet filter input tcp dport 443 counter accept
sudo nft list chain inet filter input

# отброшенные пакеты, попавшие в log
sudo journalctl -k --grep 'nft drop'

# трассировка: пометить пакеты и смотреть их путь по правилам
sudo nft insert rule inet filter input tcp dport 443 meta nftrace set 1
sudo nft monitor trace

Трассировка показывает каждую цепочку и правило, через которое прошёл пакет, и итоговое решение. После отладки удалите правило с nftrace, иначе журнал будет расти. Подробная справка по синтаксису и всем выражениям есть в официальной вики nftables и в man nft. Как вписать firewall в общую схему домашнего сервера, рассказано в материале про домашний сервер на Linux.

Частые вопросы

Нужно ли удалять iptables, чтобы пользоваться nftables?

Нет. В Debian 13, Ubuntu 26.04 и Fedora 44 команда iptables обычно уже работает как iptables-nft поверх nftables. Главное не смешивать правила из разных инструментов.

Как проверить конфиг nftables без применения?

Командой sudo nft -c -f /etc/nftables.conf. Она проверит синтаксис и покажет ошибку с номером строки, ничего не меняя в ядре.

Почему правила пропали после перезагрузки?

Правила, добавленные командой nft add rule, живут только в памяти. Перенесите их в /etc/nftables.conf (в Fedora /etc/sysconfig/nftables.conf) и включите службу nftables.

Закрывает ли nftables порты Docker-контейнеров?

Правила в цепочке input на опубликованные порты контейнеров не действуют, трафик идёт через forward и NAT Docker. Публикуйте порт на 127.0.0.1 или фильтруйте в соответствующих цепочках.

Что выбрать: ufw, firewalld или чистый nftables?

Для десктопа Ubuntu проще ufw, для ноутбука в Fedora firewalld с зонами. Чистый nftables удобен на серверах, где нужен прозрачный конфиг под контролем версий.

Документация и источники

Читайте также

Команды проверены на актуальных версиях дистрибутивов на момент обновления. Перед изменением системных настроек сделайте резервную копию.