Настройка файрвола в Linux: сравнение iptables, nftables и ufw с примерами правил | AdminWiki

Настройка файрвола в Linux: сравнение iptables, nftables и ufw с примерами правил

17 сентября 2026 16 мин. чтения
Содержание статьи

В Debian 10, Ubuntu 20.04 и более новых выпусках команда iptables по умолчанию указывает на iptables-nft: ядро получает правила через API nftables. Практический вывод простой: вопрос «iptables или nftables» часто уже решён за администратора дистрибутивом, и первый шаг - определить, какой бэкенд работает на конкретном хосте.

Короткий ответ по выбору инструмента. Типовой Ubuntu-сервер с SSH и веб-сервисами закрывается через ufw за пять команд. Сложные политики, IPv6, большие списки адресов, NAT и DNAT удобнее строить в nftables. iptables оставляйте там, где он прописан в существующих скриптах, Ansible-ролях и рабочей документации. На RHEL, CentOS Stream и Fedora штатный инструмент - firewalld с зонами, и ломать его ручными правилами nftables без необходимости не стоит.

Бэкенд проверяется одной командой:

iptables --version

Ответ вида iptables v1.8.10 (nf_tables) означает трансляцию правил в nftables, ответ с пометкой (legacy) - работу через старый API. Смешивать оба бэкенда на одном хосте нельзя: правила, добавленные через iptables-legacy, не появятся в выводе nft list ruleset, и наоборот. Симптом такой путаницы выглядит так: правило добавлено, ошибок нет, трафик всё равно проходит.

Как выбрать файрвол в Linux: iptables, nftables или ufw

Инструментов три, а подсистема под ними одна: netfilter с хуками prerouting, input, forward, output и postrouting. Разница в уровне абстракции и в том, насколько легко поддерживать конфигурацию через полгода после настройки.

iptables: legacy-интерфейс, который всё ещё жив

iptables управляет netfilter через таблицы filter, nat, mangle и raw и цепочки INPUT, FORWARD, OUTPUT. Правила проверяются линейно, поэтому список из тысяч строк нагружает CPU на каждом пакете. Наборов адресов внутри утилиты нет, для них подключают отдельный модуль ipset. IPv4 и IPv6 обслуживают разные бинарники: iptables и ip6tables, что удваивает конфигурацию.

Где iptables уместен в 2026 году: скрипты и роли, которые уже работают и протестированы; инструменты вроде fail2ban, которые умеют писать и в iptables, и в nftables; образы контейнеров с iptables внутри; стенды, повторяющие продакшен на старых дистрибутивах. Docker также создаёт собственные цепочки (DOCKER, DOCKER-USER) в таблицах filter и nat, и на хосте с iptables-nft они видны в выводе nft list ruleset.

Типичная ошибка: на Ubuntu 22.04 администратор ставит пакет iptables-legacy поверх iptables-nft, добавляет правила через legacy-утилиту и удивляется, что фильтрация не меняется. Проверяйте бэкенд до первой команды.

nftables: современная замена с единым синтаксисом

nftables появился в ядре Linux 3.13 в 2014 году, а в дистрибутивах закрепился позже: Debian 10, Ubuntu 20.04, RHEL 8 и далее используют его по умолчанию. Ключевые отличия от iptables: одна утилита nft вместо четырёх, семейство inet покрывает IPv4 и IPv6 одним набором правил, правила загружаются атомарно целым файлом, поддерживаются встроенные наборы (set), карты (map) и интервалы CIDR без ipset.

Базовая структура: таблица, цепочки с хуком и приоритетом, правила. Минимальный рабочий пример для входного трафика:

nft add table inet filter
nft add chain inet filter input { type filter hook input priority 0 ; policy drop ; }
nft add rule inet filter input iif lo accept
nft add rule inet filter input ct state established,related accept
nft add rule inet filter input tcp dport { 22, 80, 443 } accept

Приоритеты хуков стандартные: prerouting -100, input 0, forward 0, output 0, postrouting 100. Чем ниже число, тем раньше обрабатывается пакет. Для постоянной работы конфигурацию держат в файле /etc/nftables.conf и применяют целиком:

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

table inet filter {
    set blacklist {
        type ipv4_addr
        flags interval
    }

    chain input {
        type filter hook input priority 0; policy drop;
        iif lo accept
        ct state established,related accept
        tcp dport { 22, 80, 443 } accept
        ip saddr @blacklist drop
        log prefix "NFT DROP: " level warn limit rate 5/minute
    }
}

ufw: простой интерфейс для повседневных задач

ufw (Uncomplicated Firewall) скрывает цепочки и превращает задачу в одну строку: ufw allow OpenSSH, ufw allow 443/tcp. Пакет входит в стандартную установку Ubuntu и ставится из репозитория в Debian. Профили приложений лежат в /etc/ufw/applications.d, список доступных имён показывает команда ufw app list: OpenSSH, Nginx Full, Nginx HTTP, Postgresql.

Внутри ufw создаёт собственные цепочки: ufw-before-input, ufw-user-input, ufw-after-input и другие. Их видно в выводе ufw status verbose, а также в nft list ruleset или iptables -L -n. Практический нюанс: если ufw включён и вы вручную выполняете iptables -F, цепочки ufw разваливаются, и правило-политики перестают работать предсказуемо. Для сброса используйте ufw reset.

Что ufw не умеет: наборы адресов, сложные match-условия, точное управление NAT, тонкие правила по меткам conntrack и интерфейсам. Для сервера с SSH, Nginx и PostgreSQL этого достаточно. Полезная команда для публичных сервисов: ufw limit ssh ограничивает шесть новых подключений с одного IP за 30 секунд, что срезает часть брутфорса без fail2ban.

Критерийiptablesnftablesufw
Статус в дистрибутивахLegacy-интерфейс, в Debian 10+, Ubuntu 20.04+, RHEL 9 работает как iptables-nftОсновной инструмент в Debian 10+, RHEL 8+, Ubuntu 20.04+Надстройка, по умолчанию в Ubuntu
СинтаксисЦепочки и правила, отдельные утилиты для IPv4 и IPv6Одна утилита nft, семейство inet для IPv4 и IPv6Профили и порты: ufw allow 443/tcp
Применение правилПо одному правилу, промежуточные состояния видны трафикуАтомарно целым файлом через nft -fТранзакции внутри утилиты
Наборы адресовЧерез отдельный модуль ipsetВстроенные set и map с интерваламиНет, только отдельные адреса и подсети
Типовые сценарииСтарые скрипты, образы с iptables, часть CINAT, DNAT, маршрутизация, сложная фильтрацияВеб-сервер, SSH, БД на одном хосте

Безопасная настройка файрвола на удалённом сервере: как не потерять доступ

Потеря SSH после включения политики DROP - самая частая авария при настройке фильтрации. Лечится она не осторожностью, а процедурой: сначала разрешающее правило для порта SSH, потом смена политики, плюс автоматический откат на случай ошибки.

Рабочий чек-лист перед правкой правил на удалённом хосте:

  1. Узнайте фактический порт SSH: ss -tulpn | grep sshd и параметр Port в /etc/ssh/sshd_config. На нестандартном порту подставляйте своё значение вместо 22.
  2. Добавьте разрешающие правила для loopback и уже установленных соединений: без них вы обрываете собственную сессию.
  3. Запланируйте автоматический откат через at или cron с задержкой 5-10 минут.
  4. Применяйте правила с таймаутом подтверждения.
  5. Держите открытой консоль провайдера (KVM/IPMI или веб-консоль), а не только SSH.
  6. Работайте в tmux или screen, чтобы обрыв связи не убил сессию на середине команды.

Использование at и cron для отката правил

Планировщик at снимает блокировку автоматически, если вы потеряли доступ. Для iptables:

echo 'iptables -F; iptables -P INPUT ACCEPT; iptables -P FORWARD ACCEPT' | at now + 5 minutes

Для nftables откат проще, потому что сбрасывается всё дерево правил:

echo 'nft flush ruleset' | at now + 5 minutes

Требования: установлен пакет at и запущен демон atd (systemctl status atd). Если at недоступен, тот же трюк делается через cron с одноразовой задачей и последующим удалением строки из crontab. После успешной проверки правило-откат удаляется: atrm с номером задачи или правка crontab. Оставленный «страховочный» сброс правил ночью снимает всю защиту хоста, поэтому чистка обязательна.

Если сервер только для практики, берите площадку со снапшотами и веб-консолью: снапшот возвращает машину к рабочему состоянию за минуту даже при полностью потерянном доступе. Такой набор даёт, например, Timeweb Cloud: VDS с консолью, снимками и гибким изменением ресурсов.

Проверка правил перед применением

Три инструмента проверки, по одному на каждый файрвол:

ufw --dry-run enable
nft -c -f /etc/nftables.conf
iptables-apply -t 30 /etc/iptables/rules.v4

ufw --dry-run показывает, какие правила будут добавлены, и ничего не применяет. nft -c проверяет синтаксис файла без загрузки в ядро. iptables-apply применяет набор правил и ждёт подтверждения: если за 30 секунд вы не подтвердите работу (по умолчанию 10 секунд), правила откатятся к предыдущим. Для ufw порядок действий такой: ufw allow OpenSSH, затем ufw enable, затем проверка ufw status verbose из второго терминала.

Базовые правила файрвола: разрешаем SSH, HTTP и HTTPS

Схема одинакова для всех трёх инструментов: разрешить loopback и установленные соединения, открыть нужные TCP-порты, после этого поставить политику DROP на входящий трафик. Порядок важен, потому что правила читаются сверху вниз, а первое совпадение завершает обработку.

Разрешение SSH в iptables, nftables и ufw

iptables -A INPUT -p tcp --dport 22 -j ACCEPT
nft add rule inet filter input tcp dport 22 accept
ufw allow OpenSSH

Варианты записи: ufw allow 22/tcp делает то же самое, но по номеру порта, а утилита nft принимает и числовой порт, и имя сервиса из /etc/services. При нестандартном порту, например 2222, замените значение в команде. Проверить открытые порты до правки помогает ss -tulpn: список слушающих сокетов покажет, что реально надо разрешить, а что можно закрыть.

Разрешение HTTP и HTTPS

iptables -A INPUT -p tcp --dport 80 -j ACCEPT
iptables -A INPUT -p tcp --dport 443 -j ACCEPT
nft add rule inet filter input tcp dport { 80, 443 } accept
ufw allow 80/tcp
ufw allow 443/tcp

Для ufw есть профили приложений: ufw allow 'Nginx Full' открывает сразу 80 и 443, ufw allow 'Nginx HTTP' только 80. Политики по умолчанию выставляются так:

iptables -P INPUT DROP
iptables -P FORWARD DROP
iptables -P OUTPUT ACCEPT
nft add chain inet filter input { type filter hook input priority 0 ; policy drop ; }
ufw default deny incoming
ufw default allow outgoing

Для iptables перед политикой DROP нужны две строки, иначе вы отрежете себе сессию и локальные сервисы:

iptables -A INPUT -i lo -j ACCEPT
iptables -A INPUT -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT

В nftables аналогичные правила выглядят как iif lo accept и ct state established,related accept. В ufw эти проверки уже встроены в цепочки ufw-before-input, поэтому отдельные строки не нужны. Политику FORWARD держите в DROP на хостах без маршрутизации: это отсекает лишний транзитный трафик.

Блокировка IP-адресов и диапазонов

Блокировка отдельного адреса и подсети в CIDR-нотации отличается одной командой и работает одинаково во всех трёх инструментах:

iptables -A INPUT -s 192.168.1.100 -j DROP
iptables -A INPUT -s 10.0.0.0/8 -j DROP
nft add rule inet filter input ip saddr 192.168.1.100 drop
nft add rule inet filter input ip saddr 10.0.0.0/8 drop
ufw deny from 192.168.1.100
ufw deny from 10.0.0.0/8

Порядок правил в ufw решается по-разному: ufw deny from добавляет правило в конец списка, а ufw insert 1 deny from 192.168.1.100 ставит его первым, до разрешающих. Если правило блокировки оказалось после accept, оно не сработает никогда. Больше сценариев с автоблокировкой и ограничением частоты запросов собрано в материале про блокировку IP-адресов и автоматизацию защиты.

DROP vs REJECT: что выбрать

DROP молча отбрасывает пакет: клиент видит таймаут и повторяет попытки по расписанию TCP, что даёт сканеру меньше информации. REJECT отвечает ICMP port unreachable (для TCP можно указать tcp-reset) и сообщает отправителю об отказе сразу.

iptables -A INPUT -s 203.0.113.10 -j REJECT --reject-with icmp-port-unreachable
nft add rule inet filter input ip saddr 203.0.113.10 reject with icmp type port-unreachable
ufw reject from 203.0.113.10

Практическое правило: внешние адреса и агрессивные сканеры блокируйте через DROP, внутренние подсети и своих пользователей через REJECT, чтобы они получали внятную ошибку подключения и не ждали таймаут. Учтите, что ufw по умолчанию использует DROP, а вариант reject нужно указывать явно.

Использование ipset и nft set для больших списков

Тысячи отдельных правил iptables замедляют обработку. Набор адресов решает задачу: правило одно, адресов внутри сколько угодно.

ipset create blacklist hash:ip
ipset add blacklist 1.2.3.4
ipset add blacklist 203.0.113.0/24
iptables -A INPUT -m set --match-set blacklist src -j DROP
nft add set inet filter blacklist { type ipv4_addr ; flags interval ; }
nft add element inet filter blacklist { 1.2.3.4, 203.0.113.0/24 }
nft add rule inet filter input ip saddr @blacklist drop

В nftables флаг interval разрешает добавлять подсети целиком, а не только одиночные адреса. Список ipset не сохраняется сам по себе: после перезагрузки набор нужно пересоздать, поэтому его включают в скрипт инициализации или в правила netfilter-persistent.

Логирование отброшенных пакетов

Без логов диагностика фильтрации превращается в гадание: непонятно, отброшен пакет правилом или не дошёл до сервера. Логирование включают перед финальным DROP.

Настройка логирования в iptables и nftables

iptables -A INPUT -m limit --limit 5/min -j LOG --log-prefix "IPT DROP: " --log-level 4
iptables -A INPUT -j DROP
nft add rule inet filter input log prefix "NFT DROP: " level warn limit rate 5/minute
nft add rule inet filter input drop

Целевое действие LOG в iptables не завершает обработку правила: пакет идёт дальше, поэтому за строкой логирования обязательно ставится DROP или REJECT. Модуль limit и параметр limit rate в nftables ограничивают частоту записей, иначе при атаке журнал съест диск за минуты. Префикс нужен для быстрого поиска через grep. Альтернатива в iptables - цель NFLOG с записью через ulogd, она удобна для централизованного сбора логов.

Для ufw логирование включается парой команд: ufw logging on и ufw logging medium. Уровень low пишет только заблокированные пакеты, medium добавляет новые разрешённые соединения, high фиксирует всё и заметно нагружает диск.

Где искать логи файрвола

Расположение зависит от дистрибутива и системы логирования:

  • Debian и Ubuntu: /var/log/syslog или /var/log/kern.log, ядро пишет туда через rsyslog;
  • системы с systemd-journald: journalctl -k | grep "IPT DROP:" и dmesg -T | grep "NFT DROP:";
  • RHEL, CentOS Stream, Fedora: /var/log/messages;
  • ufw: отдельный файл /var/log/ufw.log, при уровне medium и выше он растёт быстрее остальных.

Строка лога показывает много полезного. Пример записи: IN=eth0 OUT= MAC=52:54:00:... SRC=198.51.100.23 DST=203.0.113.5 LEN=60 TPROTO=TCP SPT=44312 DPT=22 WINDOW=64240 SYN. Читается так: пакет пришёл на интерфейс eth0 с адреса 198.51.100.23 на порт 22, то есть кто-то пытался подключиться по SSH. Настройте ротацию для /var/log/ufw.log и kern.log, иначе место на диске закончится раньше, чем вы заметите.

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

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

iptables: сохранение правил после перезагрузки

iptables -L -v -n --line-numbers
iptables-save > /etc/iptables/rules.v4
ip6tables-save > /etc/iptables/rules.v6
apt install iptables-persistent
systemctl enable --now netfilter-persistent

Флаг -v показывает счётчики пакетов и байт по каждому правилу: ненулевой счётчик на строке DROP означает, что правило реально работает. Флаг -n отключает обратный DNS, без него вывод может виснуть на минуты. Пакет iptables-persistent в Debian и Ubuntu подхватывает файлы /etc/iptables/rules.v4 и rules.v6 при старте. На RHEL-подобных системах правила хранят в /etc/sysconfig/iptables с сервисом iptables-services.

nftables: сохранение конфигурации

nft list ruleset
nft list ruleset > /etc/nftables.conf
nft -c -f /etc/nftables.conf
systemctl enable --now nftables
systemctl status nftables

Файл /etc/nftables.conf штатно читается сервисом nftables при загрузке. Перед сохранением стоит очистить лишние счётчики: nft list ruleset включает строки counters и limits, которые не мешают, но раздувают файл. На RHEL и CentOS путь к конфигурации тот же, дополнительный файл /etc/sysconfig/nftables.conf подключает его через include.

ufw: проверка статуса и автозагрузка

ufw status verbose
ufw status numbered
ufw enable
ufw reload

Правила ufw сохраняются автоматически в /etc/ufw/user.rules и применяются сервисом при загрузке, отдельная команда сохранения не нужна. Вывод ufw status verbose показывает политики по умолчанию, состояние логирования и список активных правил с пометкой v6 для IPv6-версий. Нумерация из ufw status numbered пригодится для удаления: ufw delete 3 удаляет правило с номером 3. После правки файлов вручную применяйте ufw reload, а не ufw enable повторно.

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

Миграция с iptables на nftables и совместимость

iptables и nftables на одном хосте могут работать одновременно, и это главный источник путаницы: правила из разных баз не видны друг другу, а поведение зависит от того, какой бэкенд вызывается командой iptables. В Debian и Ubuntu переключение делается через update-alternatives, в RHEL и CentOS путь к nftables остаётся основным, а iptables-nft идёт как слой совместимости.

iptables-nft vs iptables-legacy

update-alternatives --config iptables
update-alternatives --display iptables

Команда показывает доступные варианты и текущий выбор. iptables-nft транслирует правила в nftables и работает с современными ядрами, iptables-legacy использует старый API. Выбирайте nftables-версию, если нет внешней зависимости от legacy-модулей ядра. Проверка после переключения: iptables --version и nft list ruleset, в выводе должны появиться цепочки, созданные через iptables.

Использование iptables-translate

iptables-translate -A INPUT -p tcp --dport 22 -j ACCEPT
ip6tables-translate -A INPUT -p tcp --dport 443 -j ACCEPT

Утилита выдаёт эквивалент nft: nft add rule ip filter INPUT tcp dport 22 counter accept. Она входит в пакет iptables и переводит по одному правилу, что удобно для точечной миграции. Ограничения: наборы ipset, модуль comment и часть match-модулей не конвертируются автоматически, результат обязательно проверяется вручную и через nft -c. Если правил сотни и в скрипте смешаны ipset, NAT и метки, быстрее прогнать конфигурацию через языковую модель и затем вычитать результат: единый API к GPT, Gemini и Claude с оплатой в рублях и без VPN даёт AiTunnel.

Отдельное предупреждение для тех, кто использует надстройки. ufw и firewalld управляют своими цепочками и могут писать и в iptables, и в nftables в зависимости от версии и настроек. Ручные правила nftables в собственной таблице рядом с ufw обычно работают, но диагностика усложняется: два уровня конфигурации, два места для поиска ошибки. Выбирайте один инструмент на хост. Если нужны NAT, DNAT, SNAT и маршрутизация между интерфейсами, смотрите отдельный разбор политик маршрутизации в iptables, nftables и firewalld: правила FORWARD и nat требуют другого порядка строк, чем фильтрация входящего трафика.

Сводная таблица команд и рекомендации

Таблица для быстрого копирования: одна задача, три синтаксиса.

Задачаiptablesnftablesufw
Разрешить SSHiptables -A INPUT -p tcp --dport 22 -j ACCEPTnft add rule inet filter input tcp dport 22 acceptufw allow OpenSSH
Разрешить HTTP и HTTPSiptables -A INPUT -p tcp --dport 80 -j ACCEPT; iptables -A INPUT -p tcp --dport 443 -j ACCEPTnft add rule inet filter input tcp dport { 80, 443 } acceptufw allow 80/tcp; ufw allow 443/tcp
Политика по умолчаниюiptables -P INPUT DROPpolicy drop в цепочке inputufw default deny incoming
Блокировать IPiptables -A INPUT -s 192.168.1.100 -j DROPnft add rule inet filter input ip saddr 192.168.1.100 dropufw deny from 192.168.1.100
Блокировать подсетьiptables -A INPUT -s 10.0.0.0/8 -j DROPnft add rule inet filter input ip saddr 10.0.0.0/8 dropufw deny from 10.0.0.0/8
Большой список адресовipset + -m set --match-setset с флагом intervalне поддерживается
Логирование сброса-j LOG --log-prefix "IPT DROP: "log prefix "NFT DROP: " level warnufw logging medium
Показать правилаiptables -L -v -n --line-numbersnft list rulesetufw status verbose
Сохранитьiptables-save > /etc/iptables/rules.v4nft list ruleset > /etc/nftables.confавтоматически в /etc/ufw/user.rules

Итоговые рекомендации по выбору. Ubuntu-сервер с SSH, Nginx и базой данных закрывается через ufw: пять команд, автоподхват правил после перезагрузки, читаемый ufw status numbered. Сложные политики, IPv6 без дублирования правил, NAT, наборы адресов и метки conntrack требуют nftables с конфигурацией в /etc/nftables.conf. iptables держите там, где он уже встроен в скрипты и роли, и помните, что в современных дистрибутивах он всё равно транслируется в nftables. На RHEL, CentOS Stream и Fedora работайте через firewalld, если нет причин уходить на ручные правила.

Что сделать прямо сейчас, если вы настраиваете удалённый хост: проверьте фактический порт SSH, поставьте задачу отката через at now + 5 minutes, добавьте разрешающие правила для loopback и портов 22, 80, 443, только потом меняйте политику на DROP. После проверки сохраните правила и удалите страховочный откат, иначе ночью файрвол откроется полностью. Дополнительный контекст по усилению доступа, SSH и SELinux есть в руководстве про политику безопасности Linux-сервера.

Поделиться:
Сохранить гайд? В закладки браузера