Після року розробки
На рівні ядра надається лише загальний інтерфейс, який залежить від конкретного протоколу і надає базові функції вилучення даних із пакетів, виконання операцій із даними та управління потоком.
Безпосередньо логіка фільтрації та специфічні для протоколів обробники компілюються в байткод у просторі користувача, після чого даний байткод завантажується в ядро за допомогою інтерфейсу Netlink та виконується у спеціальній віртуальній машині, що нагадує BPF (Berkeley Packet Filters). Подібний підхід дозволяє значно скоротити розмір коду фільтрації, що працює на рівні ядра і винести всі функції аналізу правил і логіки роботи з протоколами в простір користувача.
Основні нововведення:
- Підтримка IPsec, що дозволяє виконувати зіставлення адрес тунелів у прив'язці до пакета, ідентифікатору запиту IPsec і тегу SPI (Security Parameter Index). Наприклад,
… ipsec in ip saddr 192.168.1.0/24
… ipsec in spi 1-65536Також можлива перевірка проходження маршруту через тунель IPsec. Наприклад, для блокування трафіку не через IPSec:
… filter output rt ipsec missing drop
- Підтримка протоколу Internet Group Management Protocol (IGMP). Наприклад, для відкидання вхідних IGMP-запитів приналежності до групи можна використовувати правило
nft add rule netdev foo bar igmp type membership-query counter drop
- Можливість використання змінних для визначення ланцюжків переходу (jump/goto). Наприклад:
define dest = ber
add rule ip foo bar jump $dest - Підтримка масок для ідентифікації операційних систем (OS Fingerprint) на основі значень TTL у заголовку. Наприклад, для позначення пакетів залежно від ОС відправника можна використовувати команду:
… meta mark set osf ttl skip name map { "Linux": 0x1,
"Windows" : 0x2,
"MacOS" : 0x3,
"unknown" : 0x0 }
… osf ttl skip version «Linux:4.20» - Можливість зіставлення ARP-адреси відправника та IPv4-адреси цільової системи. Наприклад, для збільшення лічильника ARP-пакетів, надісланих з адреси 192.168.2.1, можна використовувати правило:
table arp x {
chain y {
type filter hook input priority filter; policy accept;
arp saddr ip 192.168.2.1 counter packets 1 bytes 46
}
} - Підтримка прозорого прокидання запитів через проксі (tproxy). Наприклад, для перенаправлення звернень до порту 80 на порт проксі 8080:
table ip x {
chain y {
type filter hook prerouting priority -150; policy accept;
tcp dport 80 tproxy to :8080
}
} - Підтримка позначки сокетів з можливістю подальшого отримання встановленої мітки через setsockopt() у режимі SO_MARK. Наприклад:
table inet x {
chain y {
type filter hook prerouting priority -150; policy accept;
tcp dport 8080 mark set socket mark
}
} - Підтримка вказівки текстових найменувань пріоритетів для ланцюжків. Наприклад:
nft add chain ip x raw { type filter hook prerouting priority raw; }
nft add chain ip x filter { type filter hook prerouting priority filter; }
nft add chain ip x filter_later { type filter hook prerouting priority filter + 10; } - Підтримка тегів SELinux (Secmark). Наприклад, для визначення мітки «sshtag» у прив'язці до контексту SELinux можна запустити:
nft add secmark inet filter sshtag "system_u:object_r:ssh_server_packet_t:s0"
А потім використовувати цю мітку в правилах:
nft add rule inet filtr input tcp dport 22 meta secmark set "sshtag"
nft add map inet filter secmapping {type inet_service: secmark; }
nft add element inet filter secmapping { 22 : sshtag }
nft add rule inet filtr input meta secmark set tcp dport map @secmapping - Можливість вказівки закріплених за протоколами портів у текстовому вигляді, як визначено у файлі /etc/services. Наприклад:
nft add rule xy tcp dport "ssh"
nft list ruleset -l
table x {
chain y {
...
tcp dport «ssh»
}
} - Можливість перевірки типу мережного інтерфейсу. Наприклад:
add rule inet raw prerouting meta iifkind "vrf" accept
- Покращено підтримку динамічного оновлення вмісту наборів (sets) через явну вказівку прапора «dynamic». Наприклад, для оновлення набору «s» з додаванням вихідної адреси та скиданням запису у разі відсутності пакетів протягом 30 секунд:
add table x
add set xs {type ipv4_addr; size 128; timeout 30s; flags dynamic; }
add chain xy { type filter hook input priority 0; }
add rule xy update @s { ip saddr } - Можливість завдання окремої умови настання таймууту. Наприклад, для перевизначення таймууту за замовчуванням для пактів, що прийшли на порт 8888, можна вказати:
table ip filter {
ct timeout agressive-tcp {
протокол tcp;
l3proto ip;
policy = {established: 100, close_wait: 4, close: 4}
}
ланцюговий вихід {
...
tcp dport 8888 ct timeout set «agressive-tcp»
}
} - Підтримка NAT для сімейства inet:
таблиця inet nat {
...
ip6 daddr dead::2::1 dnat to dead:2::99
} - Покращені засоби виведення інформації про помилки через помилки:
nft add chain filtre test
Error: No such file or directory; did you mean table «filter» in family ip?
add chain filtre test
^^^^^^ - Можливість вказівки імен інтерфейсів у наборах (sets):
set sc {
type inet_service. ifname
elements = {«ssh». "eth0" }
} - Оновлено синтаксис правил flowtable:
nft add table x
nft add flowtable x ft { hook ingress priority 0; devices = {eth0, wlan0}; }
...
nft add rule x forward ip protocol {tcp, udp} flow add @ft - Поліпшено підтримку JSON.
Джерело: opennet.ru