Nftables — подсистема Linux, отвечающая за обработку сетевых пакетов, фреймов и датаграмм. В RHEL 8 будет использоваться для работы по умолчанию, а значит самое время посмотреть на неё чуть более внимательно.
Администраторы, и пользователи интересующиеся, об nftables скорее всего ранее слышали уже не раз. Проект был анонсирован в 2008, затем была предварительная версия, чуть позже прослойка совместимости с iptables, и вот в начале 2014, nftables был включен в основную ветку ядра 3.13.
Так как с RHEL дистрибутивами и их производными я работаю чуть плотнее, чем с deb семейством, смотреть на nftables будем в Fedora. Там есть и nft, и транслятор правил, и свежее ядро — всё что нужно, что бы посмотреть на подсистему в работе. В принципе, для CentOS 8 в будущем, данная заметка так же будет актуальна, так как и dnf туда тоже пришёл.
Установка nftables.
Пока что, его нет по умолчанию в дистрибутиве, так что поставим. Вместе с этим, поставим и утилиту, которая позволит нам транслировать правила iptables в nftables:
# dnf install iptables-compat nftables
И запускаем в работу:
# systemctl restart nftables
Немного теории.
Совсем немного. Своеобразный конспект. Описывая правила для обработки пакетов мы можем управлять:
- Таблицами. Они определяют семейство протоколов, с которым ведётся работа. Каждая таблица может обозначить только одно семейство (есть допущение для inet, об этом чуть дальше). Т. е. мы не можем в рамках одной таблицы работать с ip, и arp, например. Для понимания — при работе с ip4 мы так же использовали iptables, а для arp — arptables отдельно. Предусмотрено пять семейств, которые можно использовать в таблицах — ip, ip6, inet (объединяет ip и ip6), arp, bridge.
- Цепочками. Они состоят из правил, в рамках которых обрабатываются пакеты. Доступно три типа цепочек — filter (для фильтрации), route (для роутинга) и nat (для ната соответственно). Здесь могут быть использованы хуки — prerouting, input, forward, output, postrouting.
- Правилами. Непосредственно то, с помощью чего мы описываем как будут обрабатываться пакеты.
- Инструкциями (Statements). Определяют что будет сделано с пакетом, который попал под определённое условие или правило. Здесь доступны accept, drop, reject, queue, return, jump, goto, continue.
Работа с nftables.
Рассмотрим базовый пример с открытием и закрытием порта с помощью nftables. Допустим, у нас есть сервис, который работает на 80 порте. Мы сперва ограничим доступ к нему, а затем откроем его вновь.
1. Для начала, создадим таблицу:
# nft add table inet filter
Проверим что она появилась у нас:
# nft -a list ruleset table inet filter { # handle 3 }
2. Теперь добавим цепочку:
# nft add chain ip filter input { type filter hook input priority 0 \; }
И посмотрим что изменилось:
# nft -a list ruleset table inet filter { # handle 3 chain input { # handle 1 type filter hook input priority 0; policy accept; } }
3. Добавим правило, которым ограничим доступ к 80 порту:
# nft add rule inet filter input tcp dport 80 drop
Опять посмотрим на изменения:
# nft -a list ruleset table inet filter { # handle 3 chain input { # handle 1 type filter hook input priority 0; policy accept; tcp dport http drop # handle 2 } }
4. Логично предположить, что для открытия порта нам нужно выполнить:
# nft add rule inet filter input tcp dport 80 accept
Но получить доступ к 80 порту после этого нам не удастся, и если мы заглянем в список правил, будет понятно почему:
# nft -a list ruleset table inet filter { # handle 3 chain input { # handle 1 type filter hook input priority 0; policy accept; tcp dport http drop # handle 2 tcp dport http accept # handle 3 } }
Нам нужно удалить правило с drop, для этого мы обращаем внимание на отметку handle 2 в выводе, и с её помощью удаляем запрещающее правило:
# nft delete rule inet filter input handle 2
Проверяем текущее состояние:
table inet filter { # handle 3 chain input { # handle 1 type filter hook input priority 0; policy accept; tcp dport http accept # handle 3 } }
И без проблем получаем доступ к 80 порту нашего сервера.
5. Если мы хотим полной очистки, то выполняем:
# nft delete table inet filter
После чего, вывод «nft -a list ruleset» будет пустым.
Транлсяция правил из iptables.
Для того, что бы быстро перевести имеющееся iptables правило в nft формат, можно воспользоваться утилитой iptables-translate. Работает она очень просто:
# iptables-translate -A INPUT -p tcp --dport 22 -m conntrack --ctstate NEW -j ACCEPT nft add rule ip filter INPUT tcp dport 22 ct state new counter accept
# iptables-translate -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE nft add rule ip nat POSTROUTING oifname eth0 ip saddr 10.8.0.0/24 counter masquerade
Т. е. мы просто вводим правило, и получаем его аналог, который можем использовать в nftables.
Nftables и firewalld.
Отдельно не могу не отметить вот какой момент — пользователи, привыкшие работать с firewalld могут продолжать работать с ним, и писать правила с его помощью. Начиная с версии 0.6, firewalld может использовать в качестве бекенда nftables вместо iptables. Так что не смотря на всю критичность перемен в RHEL 8, у нас остаётся уже знакомый нам инструмент, который переход на nftables как минимум облегчит.
По примерам конкретных правил для nft мы пройдём отдельно, в будущих заметках.