nftables
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 порте. Мы сперва ограничим доступ к нему, а затем откроем его вновь.
- Для начала, создадим таблицу:
# nft add table inet filter
Проверим что она появилась у нас:
# nft -a list ruleset
table inet filter { # handle 3
}
- Теперь добавим цепочку:
# 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;
}
}
- Добавим правило, которым ограничим доступ к 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
}
}
- Логично предположить, что для открытия порта нам нужно выполнить:
# 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 порту нашего сервера.
- Если мы хотим полной очистки, то выполняем:
# 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 как минимум облегчит.
NLUUG VJ16 - 21 - Pablo Neira Ayuso – Goodbye iptables, Hello nftables
По примерам конкретных правил для nft мы пройдём отдельно, в будущих заметках.