Файрвол: iptables, nftables и ufw

Файрвол решает, какие пакеты пускать, а какие резать. В Linux это три уровня одной системы: ядерный iptables/nftables и дружелюбная обёртка ufw.

Netfilter — подсистема фильтрации пакетов в ядре Linux. Управляют ею команды iptables (классика) и nftables (современная замена), а ufw — упрощённая надстройка над ними для типовых задач.

Зачем это на практике

Любой сервер в интернете — мишень для сканеров портов. Правильный файрвол открывает ровно те порты, что нужны (например, 22 для SSH и 443 для HTTPS), и закрывает всё остальное. Без этого база данных, случайно поднятая на 0.0.0.0, окажется доступна всему миру. Понимание цепочек и политик нужно даже если вы пользуетесь ufw: когда правило «не срабатывает», разбираться всё равно придётся на уровне таблиц.

Цепочки: INPUT, OUTPUT, FORWARD

Netfilter пропускает каждый пакет через цепочки правил в зависимости от направления:

  • INPUT — пакеты, адресованные самой машине (кто-то подключается к нашему серверу).
  • OUTPUT — пакеты, которые машина отправляет наружу.
  • FORWARD — транзитные пакеты, которые машина маршрутизирует между сетями (актуально для роутеров и контейнеров).

Для одиночного сервера 95% правил живут в INPUT: мы решаем, кого пускать к себе. У каждой цепочки есть политика по умолчанию — что делать с пакетом, не подошедшим ни под одно правило: ACCEPT (пустить) или DROP (молча выбросить).

iptables: смотрим и пишем правила

Посмотреть текущие правила с номерами строк:

sudo iptables -L -n -v --line-numbers   # все цепочки, без резолва имён
sudo iptables -L INPUT -n               # только INPUT

Классический безопасный набор «всё закрыто, кроме нужного». Порядок строк критичен — пакет идёт по правилам сверху вниз и останавливается на первом совпадении:

# разрешить уже установленные соединения и loopback
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT
sudo iptables -A INPUT -i lo -j ACCEPT
# открыть SSH и HTTPS
sudo iptables -A INPUT -p tcp --dport 22 -j ACCEPT
sudo iptables -A INPUT -p tcp --dport 443 -j ACCEPT
# политика по умолчанию для INPUT — резать всё остальное
sudo iptables -P INPUT DROP

Здесь -A INPUT добавляет правило в конец цепочки INPUT, -p tcp --dport 22 — для TCP-пакетов на порт 22, -j ACCEPT — действие «пустить», а -P INPUT DROP ставит политику по умолчанию. Правило про ESTABLISHED,RELATED обязательно: без него оборвутся ответы на ваши же исходящие запросы.

nftables: современная замена

nftables — новый бэкенд Netfilter, заменяющий iptables: один синтаксис вместо четырёх утилит (iptables/ip6tables/arptables/ebtables), атомарная загрузка правил, читаемый формат.

На свежих дистрибутивах iptables — это уже обёртка, которая под капотом транслируется в nftables. Прямой синтаксис nft выглядит так:

sudo nft list ruleset            # показать все правила
sudo nft add rule inet filter input tcp dport 22 accept   # открыть SSH

Файл правил /etc/nftables.conf описывает таблицы и цепочки декларативно, целиком — это удобнее, чем накапливать команды iptables по одной.

ufw: простая обёртка для типовых задач

Если не нужна тонкая настройка, ufw (Uncomplicated Firewall) закрывает 90% задач одной-двумя командами:

sudo ufw default deny incoming    # политика: входящее по умолчанию резать
sudo ufw default allow outgoing   # исходящее разрешить
sudo ufw allow 22/tcp             # открыть SSH
sudo ufw allow 443/tcp            # открыть HTTPS
sudo ufw allow from 10.0.0.0/24 to any port 5432   # БД только из подсети
sudo ufw enable                   # включить файрвол
sudo ufw status verbose           # текущее состояние

ufw сам генерирует правила iptables/nftables и сохраняет их между перезагрузками. Закрыть ранее открытый порт: sudo ufw delete allow 443/tcp.

Как это работает под капотом

Все три инструмента — это интерфейсы к одной подсистеме ядра Netfilter, которая встроена в сетевой стек в виде «хуков»: точек, где ядро останавливает пакет и прогоняет его через цепочку правил. Пакет проходит правила по порядку до первого -j ACCEPT/DROP; если совпадений нет — применяется политика цепочки. Состояние соединения (ESTABLISHED) отслеживает модуль conntrack, который помнит, на какие исходящие запросы ждать ответ. iptables исторически дёргал каждое правило отдельно, а nftables компилирует весь набор в байт-код и применяет атомарно — отсюда и переход дистрибутивов на него. ufw же просто транслирует свои простые команды в эти низкоуровневые правила.

Частые ошибки

  • Поставить iptables -P INPUT DROP до правила про SSH — и потерять доступ к удалённому серверу. Сначала открывайте порт 22, политику DROP — последней, и держите запасную консоль.
  • Забыть про ESTABLISHED,RELATED. Тогда сервер сможет отправить запрос наружу, но ответ на него цепочка INPUT зарежет — «интернет наполовину работает».
  • Не сохранить правила iptables и потерять их после перезагрузки. Чистый iptables не персистентен; нужен пакет iptables-persistent (или используйте ufw/nftables.conf, которые сохраняются сами).
  • Смешивать ufw и ручные iptables. Они правят один набор, но мешать их — путь к правилам, которые «непонятно откуда взялись». Выберите один инструмент.

Итоги

  • Пакеты проходят через цепочки INPUT (к нам), OUTPUT (от нас), FORWARD (транзит); у каждой есть политика по умолчанию ACCEPT/DROP.
  • Правила iptables читаются сверху вниз до первого совпадения; обязательно разрешайте ESTABLISHED,RELATED и lo.
  • nftables — современный бэкенд, iptables на новых системах транслируется в него; правила хранят в /etc/nftables.conf.
  • ufw — простая обёртка: ufw default deny incoming + ufw allow 22/tcp закрывают типовую задачу и сохраняются автоматически.
Проверьте себя
1. Какая цепочка обрабатывает пакеты, которые приходят на сам сервер (например, входящее SSH-соединение)?
AOUTPUT
BFORWARD
CINPUT
DROUTING
2. Почему правило 'iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT' важно при политике INPUT DROP?
AОно ускоряет интернет
BБез него ответы на исходящие запросы сервера попадут в INPUT и будут отброшены — связь оборвётся наполовину
CОно автоматически открывает все порты
DОно нужно только для FORWARD