Как стать автором
Обновить

Переход с iptables на nftables. Краткий справочник

Время на прочтение 18 мин
Количество просмотров 101K
Всего голосов 126: ↑126 и ↓0 +126
Комментарии 46

Комментарии 46

Хорошая инструкция, тоже заморочался два года назад, когда вышал убунта 18.04, где можно было использовать nft вместо iptables.

Два года парился, ломал пальцы и мозги (всё-таки вся эта борода ближе к тому как правила использует компьютер, чем человек), пока в итоге не дочитался до того, что nftables и iptables это проект одной и той же команды и конечно же они сделали iptables-nft, который имеет тот же самый один в один синтаксис что и iptables, но использует kernel интерфейс nft. то есть просто привычная утилита которая не враппер над nftables, а просто имплементирует работу с kernel nft другим синтаксисом (всем привычным).

iptables-nft являются частью iptables, и допустим в убунте их можно просто включить с помощью alternatives.

посмотреть что используется можно сделав iptables -v, например это выглядит так:

root@c2:~# iptables -v

iptables v1.8.4 (nf_tables): no command specified

и это значит что используется iptables-nft

Я реально два года пользовался nft но так и не смог к нему привыкнуть (а я сторонник всего нового) и через два года вернулся на iptables синтаксис, но безусловно пользуясь nft (потому что это крутой новый интефейс для фильтрации пакетов)

А как iptables-nft реализует сеты, словари, которых нет в классическом iptables?

А как с этим работет докер и его костыли?

извиняюсь что повторяюсь, но с iptables-nft докер прекрасно и без проблем работает (и kubernetes, вернее flannel и calico тоже).

fail2ban работает, да я думаю вообще всё работает. я перечислил только то, что я точно пробовал.

iptables-nft консольная утилита полностью повторяющая синтаксис iptables, но работающая с интерфейсом nft в ядре. то есть ей можно колбасить привычные правила и делать всё как обычно, под капотом это всё будет nftables (и даже отображаться в виде длиннющих правил если использовать утилиту nft)

а так в целом есть какие-то проекты типа использования nft вместо iptables для докера - но они в настолько зачаточном состоянии уже годы, что не стоит надеяться что ими можно будет пользоваться. мне кажется все кто хочет просто ставят iptables-nft и пользуются (я реально пытался запустить докер с поддержкой nft, и это где-то в 2020-м было даже хуже чем концепт)

Вот тут-то и проблема. Правила iptables-nft не видны через nftables и наоборот. В результате, та дичь, которую докер динамически добавляет через iptables-nft, не может нормально интрегрироваться в системе, где используется iptables-nft, и приходится всю систему переводить на "старый добрый" iptables в лице ipatables-nft.

Т.е. если у вас в системе есть несколько изолированных виртуальный сетевых интерфейсов, VPN'ы с различными правилами доступа к интерфейсам и серисам и т.п. Т.е. как раз тот случай, когда требуется сложное и гибкое конфигурирование фильтров и хочется использовать NFT, то наличие докера и его производных с их ублюдочными и кривым автоконфигурированием сетевых интерфейсов через iptables ломает абсолютно и всё.

звучит странно.

и nft и iptables-nft это интерфейсы к nftables в ядре. они обе редактируют одни и те же правила и очевидно взаимозаменяемы.

iptables -L -n -v

в моей системе показывает тоже самое что и

nft list table ip filter

я вообще в своём ядре забанил модули которые отвечали за "классический" iptables, и старый iptables невозможно использовать в принципе, ни через cli ни через api. и всё нормально работает.

А докер работает? Свои правила нормально добавляет/удаляет?

конечно.

вот кусок из iptables -L -n -v

Chain DOCKER (3 references)
 pkts bytes target     prot opt in     out     source               destination
 8193  452K ACCEPT     tcp  --  !docker_gwbridge docker_gwbridge  0.0.0.0/0            172.18.0.9           tcp dpt:443
18438  891K ACCEPT     tcp  --  !docker_gwbridge docker_gwbridge  0.0.0.0/0            172.18.0.9           tcp dpt:80
15691  854K ACCEPT     tcp  --  !docker_gwbridge docker_gwbridge  0.0.0.0/0            172.18.0.13          tcp dpt:51413
5327K  672M ACCEPT     udp  --  !docker_gwbridge docker_gwbridge  0.0.0.0/0            172.18.0.13          udp dpt:51413

Chain DOCKER-ISOLATION-STAGE-1 (1 references)
 pkts bytes target     prot opt in     out     source               destination
 6762  457K DOCKER-ISOLATION-STAGE-2  all  --  docker0 !docker0  0.0.0.0/0            0.0.0.0/0
    0     0 DOCKER-ISOLATION-STAGE-2  all  --  br-pvythdd8ctos !br-pvythdd8ctos  0.0.0.0/0            0.0.0.0/0
  19M   27G DOCKER-ISOLATION-STAGE-2  all  --  docker_gwbridge !docker_gwbridge  0.0.0.0/0            0.0.0.0/0
  40M   36G RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain DOCKER-USER (1 references)
 pkts bytes target     prot opt in     out     source               destination
 172M  133G RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain DOCKER-ISOLATION-STAGE-2 (3 references)
 pkts bytes target     prot opt in     out     source               destination
    2   386 DROP       all  --  *      docker0  0.0.0.0/0            0.0.0.0/0
    3   937 DROP       all  --  *      br-pvythdd8ctos  0.0.0.0/0            0.0.0.0/0
    0     0 DROP       all  --  *      docker_gwbridge  0.0.0.0/0            0.0.0.0/0
  19M   27G RETURN     all  --  *      *       0.0.0.0/0            0.0.0.0/0

вот кусок из nft list table ip filter

	chain DOCKER {
		iifname != "docker_gwbridge" oifname "docker_gwbridge" meta l4proto tcp ip daddr 172.18.0.9 tcp dport 443 counter packets 8193 bytes 452260 accept
		iifname != "docker_gwbridge" oifname "docker_gwbridge" meta l4proto tcp ip daddr 172.18.0.9 tcp dport 80 counter packets 18441 bytes 891064 accept
		iifname != "docker_gwbridge" oifname "docker_gwbridge" meta l4proto tcp ip daddr 172.18.0.13 tcp dport 51413 counter packets 15691 bytes 854236 accept
		iifname != "docker_gwbridge" oifname "docker_gwbridge" meta l4proto udp ip daddr 172.18.0.13 udp dport 51413 counter packets 5327475 bytes 672496088 accept
	}

	chain DOCKER-ISOLATION-STAGE-1 {
		iifname "docker0" oifname != "docker0" counter packets 6762 bytes 456593 jump DOCKER-ISOLATION-STAGE-2
		iifname "br-pvythdd8ctos" oifname != "br-pvythdd8ctos" counter packets 0 bytes 0 jump DOCKER-ISOLATION-STAGE-2
		iifname "docker_gwbridge" oifname != "docker_gwbridge" counter packets 19095322 bytes 26769977257 jump DOCKER-ISOLATION-STAGE-2
		counter packets 40298535 bytes 36112505838 return
	}

	chain DOCKER-USER {
		counter packets 171779895 bytes 133264417545 return
	}

	chain DOCKER-ISOLATION-STAGE-2 {
		oifname "docker0" counter packets 2 bytes 386 drop
		oifname "br-pvythdd8ctos" counter packets 3 bytes 937 drop
		oifname "docker_gwbridge" counter packets 0 bytes 0 drop
		counter packets 19102079 bytes 26770432527 return
	}

можно заметить что даже счётчики пакетов примерно совпадают (всё же там была секунда паузы между первой и второй командой). то есть это не дубликаты, это одни и те же правила в ядре, просто выведенные с помощью двух разных утилит

Можно попросить подсказать, как в ядре банили модули? Просто пересобрали, или? Перехожу как раз на nft и хочется не оставлять лазеек для пути назад :)

Да, я пересобирал на сервере где делал изначальные тестовые прогоны. Ну там вообще не только для этого ядро кастомное, так что было ок. Потом убедился что достаточно поменять iptables c iptables-legacy на iptables-nft через /etc/alternatives, и старые модули не подгружаются со временем от использования любого софта который у нас в продакшене, и дальше на серверах которые уже ставились с nft не парился. Я думаю можно в /etc/modprobe.d/blacklist.conf перечислить основные модули iptables-legacy:

bpfilter

iptable_filter

iptable_nat

iptable_mangle

и этого будет достаточно чтобы те кто попытаются дёрнуть за старый интерфейс обломились.

А у меня как раз такая ситуация - `iptables-save` - пустой, а `nft list rulest` показывает все правила

То есть теперь счётчики есть не для каждого правила, а только там где явно включено? И ещё, а есть ли в nft плагины? Совместимы ли плагины от iptables?

Да, счётчики опциональны.

Упоминания плагинов в документации не встречал.

Довольно похоже на pf.

Да... Много лет потребовалось, чтобы сделать что-то похожее на PF. Но вот с читабельностью так и не получилось.

Благодарю, осень полезно и подробно

firewalld достаточен для простых вещей, типа открыть порт для чего-то, но для ряда случаев этого очень мало и приходится копать глубже.

НЛО прилетело и опубликовало эту надпись здесь

А зачем, если есть настоящий iptables/nftables, в который эти правила всё равно транслируются?

НЛО прилетело и опубликовало эту надпись здесь

Тот неловкий момент, когда администраторы Facebook почитали данный мануал и пошли применять полученные знания на практике

Это точно для людей? Для человека удобнее именно табличный вид, а не парсить json Или у программеров это уже на уровне лимбической системы парстся?

А что сложного в чтении JSON? Вот таблички, у них внутри цепочки, условия проверяются сверху вниз

По сути базовые правила nft 1-в-1 как iptables, только по человечески сгруппированные и без мусорных дефисов

Вы сильно лукавите, что это просто. Это возможно, но отнюдь не просто, иначе зачем нужны бы были все эти плагины и оболочки над json? Элементарно, сравнить две строчки проще чем два "облака". Ну и странно пенять на мусорные дефисы при обилии скобок.

Особенно радует впихивание ; в командной строке с последующим его экранированием \;

Откройте для себя jq и у вас никогда не будет проблем с парсингом json

Ну и муть мутная!! Авторы этого интерфейса под веществами были скорее всего!

nftables и iptables это проект одной и той же команды

:)

Вообще это не дело - иметь такой зоопарк файрволлов. ip,nfttables, pf, firewalld, возможно что-то еще. Притом каждый файрволл абсолютно несовместим по синтаксу с другим. Из всех перечисленных, более менее по user-friendly (но ущербнее по функционалу) это firewalld, но эта зараза напрочь ломает правила iptables - в итоге ни тот ни другой вместе нормально не пашут. Поэтому логичнее всего надо было оставить только один - iptables. Давеча был сильно разочарован в iptables на CentOS - оказалось там нет такой элементарной возможности как сохранить правила после перезагрузки. Карл, 21 век! WTF? И мне нужно извращаться в target это прописывать, где собственно ничерта и не заработало. Благо хоть в крон получилось засунуть что-то вроде /sbin/iptables-restore < somerules и отрабатывать это каждые 5 минут. Костыль, но хоть как-то пашет. Притом что в дебиане и убунте есть штатная утилита сохранения правил без всяких таргетов, скриптов и кронов. Мало того что есть куча разношёрстных файрволов. Так еще один и тот-же файрвол на разных ОС - тоже отличается. Бардак!

В iptables на CentOS всё так-же работает service iptables save, оно-же /usr/libexec/iptables/iptables.init save. Правда нужно доставить пакет iptables-services. После этого появляется /etc/sysconfig/iptables-config c IPTABLES_SAVE_ON_STOP, IPTABLES_SAVE_ON_RESTART.

До боли знакомый ключик - не пашет, точно могу сказать. Возможно трабл в том, что я ставил openvpn из готового скрипта, а как он там настроен "из коробки" только писателям того скрипта известно. В любом случае такая мелочь как iptables-persistent в любом linux-дистре должен быть в коробке, а это утилитки охх как не хватает мне в моей конфе.

Сейчас в CentOS «из коробки» - firewalld, а всё остальное - по желанию :)

Я даже больше обрадую вас - уже так лет 7. Вроде как с Centos 7.

sudo yum remove -y firewalld

sudo yum install -y iptables-services

sudo systemctl daemon-reload

sudo systemctl enable iptables

В смысле напрочь ломает правила iptables? Если вы о тех, которые сами в обход firewalld настраивали — то да, хотя любой файрволл считает, что он тут один командует, и под себя создает все цепочки фильтров и тому подобные структуры уровня ядра. А так у него есть firewalld add rule с функционалом практически эквивалентным iptables, но в рамках firewalld'овских цепочек, т.е. пихается сильно ниже по ветвлению, чем правило iptables -A INPUT.

Ужас, то ли дело бсдёвый ipfw. Оно может хорошо и функционально на каких то защитных шлюзах, но на обычных серверах, тем более на рабочем десктопе, ну нафик.

Ну вот и зачем ломать то, что и так прекрасно работает? Иптейблс прекрасен, прост и понятен, а это треш какой-то

iptables, arptables, ebtables, ipset - делались каждый по отдельности. А тут собрали всё вместе, порефакторили и причесали.

Мне тоже лень переучиваться, но надо.

>но надо.

Нет, не надо. В этом нет смысла.

А я ни то, ни другое не учил, как теперь выбирать? :)

Ничего не знаешь — учи наиболее популярное из того, что не deprecated. Здесь nftables.

Учитывая, что nftables ещё долго и много где будут использоваться через эмуляцию iptables - пока что придётся выбирать оба.

А потом придёт bpfilter с синтаксисом iptables и надо будет всё вспоминать

История говорит, что будет другой ещё более замысловатый синтаксис с элементами того, другого и ещё чего-нибудь третьего.

Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.