NFTables — новая реализация файрвола в ядре Linux, которая призвана заменить iptables. Как и многие другие радикальные изменения, этот инструмент до сих пор вызывает у пользователей противоречивые чувства. И главный вопрос, конечно же, — какие преимущества можно получить от перехода на него?
В статье «Настройка Nftables» я рассмотрел основы настройки nftables и миграции с iptables. Набор правил после миграции стал короче благодаря новым фичам nftables вроде переменных и встроенной поддержки групп объектов. Тем не менее по функциональности он идентичен старому, и у некоторых читателей возникли сомнения, что мигрировать вообще целесообразно.
РЕКОМЕНДУЕМ:
Как защититься от руткитов в Linux
Преимущества NFTables
В этот раз мы рассмотрим ряд функций nftables, которые в iptables отсутствуют, и убедимся, что переделать файрвол в Linux авторы задумали не просто от скуки.
Трассировка правил
Наверняка бывало так, что нужный трафик ошибочно блокируется каким-то правилом, но ты не можешь понять, каким именно. У nftables для таких случаев есть встроенный механизм трассировки правил.
Рассмотрим его на очевидном примере. Пусть у тебя правило блокирует весь трафик сети 192.0.2.0/24.
1 |
$ sudo nft insert rule inet filter input ip saddr 192.0.2.0/24 drop |
Предположим, ты о нем забыл и в упор не видишь его в настройках, а пользователи жалуются, что не проходит трафик с хоста 192.0.2.1. Не беда — мы можем включить трассировку для всех пакетов с адресом источника 192.0.2.1. Это делается опцией nftrace set 1.
1 |
$ sudo nft insert rule inet filter input ip saddr 192.0.2.1 meta nftrace set 1 |
Теперь в выводе команды nft monitor trace мы можем увидеть весь путь этого пакета через наш набор правил.
1 2 3 4 |
$ sudo nft monitor trace trace id 66fdb23e inet filter input packet: iif "eth0" ether saddr ... ether daddr ... ip saddr 192.0.2.1 ip daddr 203.0.113.1 ip dscp cs0 ip ecn not-ect ip ttl 64 ip id 0 ip protocol icmp ip length 84 icmp type echo-request icmp code net-unreachable icmp id 50986 icmp sequence 1 @th,64,96 14560823784192396447041847296 trace id 66fdb23e inet filter input rule ip saddr 192.0.2.1 meta nftrace set 1 (verdict continue) trace id 66fdb23e inet filter input rule ip saddr 192.0.2.0/24 drop (verdict drop) |
Теперь мы сможем найти нужное правило поиском по ip saddr 192.0.2.0/24. Это, конечно, тривиальный пример, и правило могло быть куда менее простым и очевидным, но в выводе трассировки ты всегда увидишь именно правило, которое отбросило пакет.
Как и с tcpdump/Wireshark, выбор критерия для трассировки — залог удачной отладки. Трассировка работает только для пакетов, которые попали под правило с nftrace set 1. Если условие недостаточно специфично, пакет в нее не попадает. Сделай условие слишком общим, вроде protocol tcp, и ты не сможешь найти нужное в огромном объеме вывода.
Тем не менее само наличие этого механизма открывает прежде недоступные возможности для отладки правил.
Удаление ненужных правил
В прошлой статье мы почти не затрагивали ручное управление правилами, а вместо этого сфокусировались на файлах конфигурации.
Сейчас мы добавили отладочное правило, и после завершения сеанса отладки его хорошо бы удалить. Как это сделать? В iptables требовалось указать каждое условие правила. В nftables немного иначе.
Сначала нужно получить номер правила в таблице. Его можно увидеть в выводе команды nft -a list ruleset (опция -a важна).
1 2 3 4 5 6 7 |
$ sudo nft -a list ruleset table inet filter { # handle 7 ... chain input { # handle 1 type filter hook input priority filter; policy accept; ip saddr 192.0.2.0/24 meta nftrace set 1 # handle 25 ... |
Здесь handle 25 — это и есть номер правила. Теперь мы можем удалить его командой sudo nft delete rule inet filter input handle 25.
В отличие от iptables удаление правил по полному набору опций в nftables не поддерживается. Несколько неудобно, что нельзя больше скопировать правило и поменять -A/-I на -D, но зато и команда для удаления правил стала короче.
Ассоциативные массивы
Старый инструмент IP set позволял создавать разные типы групп объектов, но не умел ассоциировать объекты с разрешениями — нельзя было в одном правиле разрешить один объект, но запретить другой.
В правилах nftables можно ссылаться не на отдельный критерий и решение, а на ассоциативные массивы из них. Синтаксис таких ассоциативных массивов: vmap { объект : разрешение, ...}. Здесь vmap — это опция, которая указывает, что последует именно массив из объектов и разрешений, а { ключ : значение, ...} — общий синтаксис ассоциативных массивов.
Например, в одном правиле мы можем разрешить зашифрованные варианты SMTP (SMTPS и SMTP/STARTTLS), но запретить обычный на порте 25.
1 |
ct state new tcp dport vmap { 465 : accept, 587 : accept, 25 : drop } comment "Secure SMTP only" |
Мы также можем определить именованный ассоциативный массив (например, banlist) и сослаться на него в правиле с помощью опции vmap @banlist. Именованный массив может быть и пустым, с расчетом на динамическое редактирование.
1 2 3 4 5 6 7 8 9 10 |
table inet filter { map banlist { type ipv4_addr : verdict } chain input { type filter hook input priority filter; policy accept; ip saddr vmap @banlist drop } } |
Это очень упрощает работу скриптов вроде fail2ban, поскольку массив можно динамически редактировать средствами nftables.
1 2 |
$ sudo nft add element inet filter banlist { 203.0.113.80 : drop} $ sudo nft delete element inet filter banlist { 192.0.2.98 : drop} |
В IP set был встроенный набор типов, но не было возможности создать свои, поэтому разработчики добавили многочисленные варианты вроде hash:ip,port, пытаясь покрыть все возможные случаи. В nftables больше нет такой проблемы — элементы ассоциативных массивов могут быть произвольных типов.
Например, мы можем одним правилом NAT прокинуть порт 80 на адрес 10.0.0.10, а порт 25 — на адрес 10.0.0.20.
1 |
$ sudo nft add rule ip nat prerouting dnat tcp dport map { 80 : 10.0.0.10, 25 : 10.0.0.20 } |
Даже если синтаксис nftables кажется тебе менее читаемым, в качестве компенсации он позволяет обойтись меньшим числом правил.
Stateless NAT
В давние времена в ядре Linux был простой NAT, состояние соединений не отслеживалось. Механизм их отслеживания (conntrack) сделал жизнь сетевых администраторов куда лучше. Сложные протоколы более чем с одним соединением перестали быть неразрешимой проблемой. Кроме того, обработка пакетов стала быстрее, поскольку большинство из них достаточно сопоставить с таблицей соединений (опция --state в iptables), и уже не нужно прогонять через весь набор правил.
Тем не менее иногда stateless NAT — действительно лучшее решение. Например, провайдеры хостинга VPS вроде Amazon широко применяют 1:1 NAT, чтобы упростить управление сетью, — у самой виртуалки «серый» адрес, что позволяет развязать внешнюю и внутреннюю маршрутизацию. Отслеживать потоки трафика в этом случае не имеет смысла, поскольку решение для всех пакетов с одним адресом всегда одинаковое.
В iptables это было возможно только при трансляции сетей IPv6 (NPTv6). В nftables снова появилась «тупая» (а значит, очень быстрая) трансляция адресов.
Например, транслируем внешний адрес 192.0.2.1 во внутренний 10.0.0.1.
1 2 3 4 5 6 |
table ip raw { chain prerouting { type filter hook prerouting priority raw; policy accept; ip daddr 192.0.2.5 ip daddr set 10.0.0.1 notrack } } |
Множественные действия
В iptables у каждого правила может быть только одно действие (оно определяется опцией -j). Применить к одному пакету несколько разных действий можно только несколькими правилами.
В nftables у одного правила может быть несколько действий. Например, мы можем логировать пакеты из сети 192.0.2.0/24 и сразу блокировать их.
1 |
$ sudo nft insert rule inet filter input ip saddr 192.0.2.0/24 log level err prefix martian-source drop |
Таблицы netdev
В прошлой статье мы уже рассматривали новый тип таблиц inet, который позволяет хранить правила и для IPv4, и для IPv6 в одной таблице. С его помощью мы смогли избавиться от дублирующихся наборов правил для разных протоколов.
РЕКОМЕНДУЕМ:
Настройка безопасности MikroTik
Это не единственный новый тип таблиц. Кроме него, есть еще таблицы типа netdev. Правила в таких таблицах видят весь трафик, когда он входит из драйвера сетевой карты в сетевой стек ядра, включая кадры ARP. Это позволяет блокировать пакеты еще до того, как ядро начнет их обрабатывать. Авторы советуют применять эти таблицы для правил защиты от DDoS и подобного.
Заключение
Удалять iptables из ядра в ближайшее время никто не собирается, так что мигрировать на nftables или нет — решать тебе. Надеюсь, этот обзор поможет тебе принять информированное и осознанное решение.