На уровне ядра предоставляется лишь общий интерфейс, не зависящий от конкретного протокола и предоставляющий базовые функции извлечения данных из пакетов, выполнения операций с данными и управления потоком. Непосредственно логика фильтрации и специфичные для протоколов обработчики компилируются в байткод в пространстве пользователя, после чего данный байткод загружается в ядро при помощи интерфейса Netlink и выполняется в специальной виртуальной машине, напоминающей BPF (Berkeley Packet Filters). Подобный подход позволяет значительно сократить размер кода фильтрации, работающего на уровне ядра и вынести все функции разбора правил и логики работы с протоколами в пространство пользователя.
Основные новшества:
- Поддержка диапазонов в присоединениях (concatenation, определённые связки адресов и портов, упрощающие сопоставление). Например, для набора «whitelist», элементы которого являются присоединением, указание флага «interval» будет указывать на то, что набор может включать диапазоны в присоединении (для присоединения «ipv4_addr . ipv4_addr . inet_service» раньше можно было перечислять точные совпадения вида «192.168.10.35 . 192.68.11.123 . 80», а теперь можно указывать группы адресов «192.168.10.35-192.168.10.40 . 192.68.11.123-192.168.11.125 . 80»):
table ip foo { set whitelist { type ipv4_addr . ipv4_addr . inet_service flags interval elements = { 192.168.10.35-192.168.10.40 . 192.68.11.123-192.168.11.125 . 80 } } chain bar { type filter hook prerouting priority filter; policy drop; ip saddr . ip daddr . tcp dport @whitelist accept } }
- В наборах и map-списках обеспечена возможность использования директивы «typeof», определяющей формат элемента при сопоставлении. Например:
table ip foo { set whitelist { typeof ip saddr elements = { 192.168.10.35, 192.168.10.101, 192.168.10.135 } } chain bar { type filter hook prerouting priority filter; policy drop; ip daddr @whitelist accept } } table ip foo { map addr2mark { typeof ip saddr : meta mark elements = { 192.168.10.35 : 0x00000001, 192.168.10.135 : 0x00000002 } } }
- Добавлена возможность использования присоединений в NAT-привязках, что позволяет указывать адрес и порт при определении NAT-преобразований на основе map-списков или именованных наборов:
nft add rule ip nat pre dnat ip addr . port to ip saddr map { 1.1.1.1 : 2.2.2.2 . 30 } nft add map ip nat destinations { type ipv4_addr . inet_service : ipv4_addr . inet_service \; } nft add rule ip nat pre dnat ip addr . port to ip saddr . tcp dport map @destinations
- Поддержка аппаратного ускорения с выносом некоторых операций фильтрации на плечи сетевой карты. Ускорение включается через утилиту ethtool («ethtool -K eth0 hw-tc-offload on»), после чего активируется в nftables для основной цепочки при помощи флага «offload». При использовании ядра Linux 5.6 поддерживается аппаратное ускорение для сопоставления полей заголовка и проверки входящего интерфейса в сочетании с приёмом, отбрасыванием, дублированием (dup) и перенаправлением (fwd) пакетов. В примере ниже операции отбрасывания пакетов, приходящих от адреса 192.168.30.20, выполняются на уровне сетевой карты, без передачи пакетов ядру:
# cat file.nft table netdev x { chain y { type filter hook ingress device eth0 priority 10; flags offload; ip saddr 192.168.30.20 drop } } # nft -f file.nft
- Улучшено информирование о месте ошибки в правилах.
# nft delete rule ip y z handle 7 Error: Could not process rule: No such file or directory delete rule ip y z handle 7 ^ # nft delete rule ip x x handle 7 Error: Could not process rule: No such file or directory delete rule ip x x handle 7 ^ # nft delete table twst Error: No such file or directory; did you mean table ‘test' in family ip? delete table twst ^^^^
В первом примере показано, что таблица «y» отсутствует в системе, во втором, что отсутствует обработчик «7», а в третьем, что выводится подсказка об опечатке при наборе имени таблицы.
- Добавлена поддержка проверки slave-интерфейса через указание «meta sdif» или «meta sdifname»:
... meta sdifname vrf1 ...
- Добавлена поддержка операции сдвига вправо или влево. Например, для сдвига существующей метки пакета влево на 1 бит и установки меньшего бита в 1:
... meta mark set meta mark lshift 1 or 0x1 ...
- Реализована опция «-V» для отображения расширенной информации о версии.
# nft -V nftables v0.9.4 (Jive at Five) cli: readline json: yes minigmp: no libxtables: yes
- Опции командной строки теперь обязательно должны указываться перед командами. Например, нужно указывать «nft -a list ruleset», а запуск «nft list ruleset -a» приведёт к выводу ошибки.
Источник: http://www.opennet.ru/opennews/art.shtml?num=52656