Вопрос или проблема
У меня проблема с настройкой nftables.
У меня есть две таблицы, каждая из которых содержит цепочку с одинаковым хуком, но с другим именем и приоритетом.
Таблицы находятся в разных файлах, которые загружаются с помощью аргумента include.
Из-за приоритета, я бы подумал, что цепочка VPN-POSTROUTING будет выполняться раньше, чем цепочка INTERNET. Но в моей настройке сначала выполняется цепочка INTERNET.
table ip nat {
chain INTERNET {
type nat hook postrouting priority srcnat + 1; policy accept;
oifname br2 masquerade
}
}
table ip vpn {
chain VPN-POSTROUTING {
type nat hook postrouting priority srcnat - 1; policy accept;
oifname br2 ip saddr 10.0.0.0/24 ip daddr 192.168.0.0/24 accept
}
}
Где моя ошибка?
Редактировать: Я изменил правила и объединил все цепочки в одну таблицу, но результат остался прежним.
На следующем шаге я последовал совету А.Б. и добавил счетчики и логи к правилам.
Порядок цепочек соответствует приоритету, но правило разрешения для VPN не срабатывает.
Когда я добавляю правило разрешения VPN в цепочку INTERNET, прямо перед правилом masquerade, это работает так, как ожидалось.
Хотя ответ А.Б. верен, я хотел бы немного дополнить его и уточнить объяснение.
Все нижеследующие утверждения относятся к ситуациям, когда цепочки, о которых идет речь, зарегистрированы в одной и той же семье и с одним и тем же хуком.
Во-первых, вы, возможно, неправильно поняли слово приоритет (и опыт подсказывает, что вы не единственный, если это так). Более низкое числовое значение приоритета означает более высокий приоритет, а более высокий приоритет означает, что соответствующая цепочка проходит ранее.
После того как цепочка была пройдена, может быть пройдена другая цепочка (см. ниже). Эта другая (поздняя) цепочка может на самом деле переопределить вердикт предыдущей. Учитывая это, говорить о приоритетах очень проблематично:
В обычной речи и по здравому смыслу цепочка с самым высоким приоритетом была бы цепочкой , которая фактически определяет окончательный вердикт, либо переопределяя вердикты других цепочек, либо блокируя выполнение последующих цепочек.
Однако в терминах nftables
самая приоритетная цепочка – это та, которая выполняется первой. Другими словами, на самом деле цепочка с самым низким приоритетом может определять окончательный вердикт. Эта интерпретация “приоритета” вызывает острую озабоченность, на мой взгляд; лучшим термином, возможно, было бы “порядок оценки”.
Во-вторых, если цепочка была пройдена, может быть удивительно, при каких обстоятельствах проходят дальнейшие цепочки. Вики nftables объясняет это:
ПРИМЕЧАНИЕ: Если пакет принят и существует другая цепочка с тем же типом хука и с более поздним приоритетом, тогда пакет в дальнейшем пройдет эту другую цепочку. Следовательно, вердикт разрешения – будь то правило или политика по умолчанию – не является окончательным. Однако это не относится к пакетам, подлежащим вердикту о сбросе. Вместо этого сбросы вступают в силу немедленно, без дальнейших правил или цепочек.
accept окончательным, но это не так в nftables
. Вместо этого, после вердикта accept
, прохождение текущей цепочки останавливается, но далее проходят цепочки (если они существуют, т.е. цепочки с более низким приоритетом) несмотря на предыдущий вердикт accept
.
Таким образом, ваша цепочка VPN-POSTROUTING
выполняется первой (из-за более низкого приоритета), но это заканчивается вердиктом о разрешении, и таким образом пакеты попадают в вашу цепочку INTERNET
после этого и, следовательно, обрабатываются.
Что касается решения: Существует много способов добиться желаемого. Предложение А.Б. безусловно, хорошее. Однако я обычно стараюсь не разбивать правила слишком сильно. Как вы сами заметили, легко заставить это работать, если вы помещаете свои правила в одну цепочку в правильном порядке.
Исторически существовала одна цепочка NAT в заданном хуке (prerouting, input, output и т.д.). Выполнение оператора nat или просто разрешение пакета, будучи терминальным для цепочки, с одной цепочкой также завершало обработку в пределах хука. Поскольку nftables позволяет использовать более чем одну цепочку в одном хуке, завершение цепочки просто продолжает к следующей цепочке. Поэтому, если первая цепочка ничего не делает (разрешая пакеты), следующая цепочка получает шанс сделать это вместо первой, что не является ожидаемым поведением.
Чтобы решить эту проблему, первая цепочка (или любая другая цепочка) может оставить сообщение, передаваемое каждой следующей цепочке, чтобы она могла на него реагировать: установить метку (произвольное значение) для следующей цепочки, чтобы изменить ее поведение.
Вместо accept
, который не имеет эффекта (оставляя цепочку VPN-POSTROUTING
пустой также выполняет политику по умолчанию: accept
), установите метку. Замените правило в VPN-POSTROUTING
на это:
nft add rule ip vpn VPN-POSTROUTING oifname br2 ip saddr 10.0.0.0/24 ip daddr 192.168.0.0/24 mark set 0xdeaf
Когда эта метка установлена, она может затем использоваться в другой цепочке для изменения поведения, не выполняя оставшиеся правила. Вставьте это правило сначала в ip nat INTERNET
:
nft insert rule ip nat INTERNET mark 0xdeaf accept
Ответ или решение
Вопрос, который вы подняли, касается сложностей с настроенной вами системой nftables, включающей две таблицы, каждая из которых имеет цепочку с одинаковым хуком, но различными приоритетами. Давайте углубимся в технические детали и разберемся, где может быть ошибка и как ее можно исправить.
Приоритет в nftables: Понимание
Прежде всего, важно правильно понять, что в терминах nftables означает "приоритет". В nftables цепочки, зарегистрированные в одной и той же категории и хуке, выполняются в порядке возрастания значения приоритета. Это значит, что цепочка с более низким числом приоритета будет выполняться раньше. Например, в вашем случае цепочка VPN-POSTROUTING
с приоритетом -1
выполняется раньше, чем INTERNET
, у которой приоритет +1
.
Однако, в nftables существует один важный нюанс: после того как цепочка пройдет (то есть в вашем случае выполнится правило accept
), управление может перейти к следующей цепочке (с большим числом приоритета). Это означает, что прием решения (т.е. accept
), возвращаемого одним правилом, не обязательно является финальным. Следовательно, в вашем случае, после выполнения VPN-POSTROUTING
, пакет продолжает проходить через цепочку INTERNET
.
Пример вашей настройки
Как вы указали, ваша конфигурация выглядит следующим образом:
table ip nat {
chain INTERNET {
type nat hook postrouting priority srcnat + 1; policy accept;
oifname br2 masquerade
}
}
table ip vpn {
chain VPN-POSTROUTING {
type nat hook postrouting priority srcnat - 1; policy accept;
oifname br2 ip saddr 10.0.0.0/24 ip daddr 192.168.0.0/24 accept
}
}
В данном случае, ваше предположение о том, что VPN-POSTROUTING
будет обрабатывать пакеты раньше, справедливо. Однако, поскольку она решает разрешить пакеты с помощью accept
, это дает зеленый свет для продолжающегося процесса в цепочке INTERNET
, что и объясняет наблюдаемое вами поведение.
Решение вашей проблемы
Вы можете попробовать следующее решение для контроля потока пакетов между цепочками:
- Вместо того, чтобы просто вызывать
accept
вVPN-POSTROUTING
, установите метку с помощью:
nft add rule ip vpn VPN-POSTROUTING oifname br2 ip saddr 10.0.0.0/24 ip daddr 192.168.0.0/24 mark set 0xdeaf
- В цепочке
INTERNET
добавьте проверку на метку в начале правила:
nft insert rule ip nat INTERNET mark 0xdeaf accept
Эти изменения позволят вам обрабатывать пакеты, которые были отмечены в VPN-POSTROUTING
, и избежать их случайного маскирования в INTERNET
, тем самым предотвращая нежелательные изменения в их маршруте.
Заключение
Таким образом, правильное понимание того, как работают приоритеты и вердикты в nftables, может существенно изменить ваше взаимодействие с правилами фильтрации пакетов. Надеюсь, предложенные рекомендации помогут вам наладить функционирование вашего сетевого окружения именно так, как вы того хотите.
Если возникнут дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь обращаться за поддержкой!