Имя цепочки — не хук: iptables против nftables
Цепочка — это контейнер; хук решает, обращается ли к ней ядро. Сравните встроенные цепочки iptables с базовыми цепочками nftables, прежде чем менять правила.
Оба межсетевых экрана могут фильтровать пересылаемый трафик VPN, и они прикрепляют правила к пути пакета по-разному. В iptables встроенные цепочки находятся внутри таблицы, поэтому FORWARD существует как именованная точка хука. nftables отделяет имя цепочки от её типа, хука и приоритета, а значит, обычная цепочка с именем FORWARD ничего не фильтрует. Сравнение двух моделей объясняет, почему запись, которая выглядит правильной в одном инструменте, не даёт эффекта в другом.
Цепочка — это контейнер. Обращается ли к ней ядро, зависит от реализации и от того, как набор правил её прикрепляет.
Две модели, два разных способа прикрепления
В iptables таблица filter поставляется с тремя встроенными цепочками, INPUT, FORWARD и OUTPUT, а -N создаёт цепочку, определённую пользователем, которая действует только при переходе на неё из одной из них. Руководство nftables вместо этого определяет базовые цепочки, которые объявляют свой тип, хук и приоритет, и обычные цепочки, которые этого не делают. Базовая цепочка может носить любое имя, а обычная цепочка с именем FORWARD не получает никаких свойств от своей метки. В этом вся разница, и она невидима в руководстве, которое показывает только текст правил.
Бэкенды совместимости добавляют вторую причину не выводить поведение из имени команды. Документация iptables отмечает операции, которые отличаются под iptables-nft, поэтому рассматривайте нативный nftables, iptables-nft и устаревший набор правил как три системы, а не как три написания одной.
Читайте ошибку в её реальном контексте
Отсутствующая таблица, отказ в разрешении, недоступная возможность ядра и отсутствующая именованная цепочка — это четыре разных вывода, и только один из них о цепочке. Запишите версию инструмента, запрошенное семейство адресов и таблицу, сетевое пространство имён и первую точную ошибку. Затем проверьте, какой компонент владеет набором правил: служба межсетевого экрана или шлюз, управляемый продуктом, может создавать собственные цепочки и порядок. Добавление нативной цепочки рядом с ними оставляет управляемую политику нетронутой, а инвентаризацию — более запутанной.
Пространство имён контейнера может содержать другой набор правил, чем хост, поэтому команда, выполненная в неверном контексте, не покажет, какая цепочка увидела пересылаемый пакет. Повышение привилегий из-за того, что ожидаемая цепочка не была видна, — не диагностика.
Счётчики доказывают достижение, а не вердикт
Счётчики правил сообщают, что правило было достигнуто. Они не сообщают, что более позднее правило разрешило операцию, и не доказывают, что каждый альтернативный путь был отклонён. Читайте их во время одного безвредного разрешённого потока, вместе с порядком правил и прикреплением цепочки, и рассматривайте как одно наблюдение, а не как вердикт. Ненулевой счётчик на правиле drop означает, что трафик его достиг; о трафике, который его не достиг, он ничего не говорит.
Пересылка IP в ядре — совершенно отдельная настройка. Наличие цепочки не включает пересылку, а отсутствие знакомой метки не значит, что пересылка остановилась.
Опишите поток, который вы хотите защитить
Запишите один клиентский запрос после декапсуляции: его источник, назначение, семейство адресов и то, завершается ли он на шлюзе или проходит через него. Вход локальной службы и пересылаемый трафик наблюдаются в разных точках, поэтому им нужны разные правила и разные проверки. Для VPN с мостом проверьте и путь моста, поскольку цепочка на уровне IP не контролирует кадры Ethernet автоматически.
Сохраните независимый доступ для восстановления, прежде чем менять удалённый шлюз. Затем подтвердите предполагаемый поток и требуемые отказы в рамках того же набора правил. Новая пустая цепочка со знакомым именем — не исправление.
Сравнение заканчивается одним вопросом: какой хук ядро на самом деле вызывает для этого пакета? Ответьте на него, и имя цепочки перестаёт иметь значение.