Вопрос или проблема
Я новичок в nftables, но уже довольно долго использую iptables. Играясь с nftables, я подумал: “Эй, это круто, я мог бы сделать что-то вроде таблицы управления, куда помещается все, что связано с управлением, и принимается, а потом я мог бы иметь что-то вроде таблиц для арендаторов, которые могут делать что угодно”. Поэтому я попытался это сделать и потерпел неудачу. Таблицы nftables следующие:
table inet management {
chain input {
type filter hook input priority -1000; policy drop;
iifname "lo" counter packets 16 bytes 996 accept
ct state established,related counter packets 22982 bytes 1739629 accept
tcp dport 22 counter packets 0 bytes 0 accept
log prefix "Dropped by management: "
}
}
table ip tenant1 {
set web {
type inet_service
elements = { 80, 443 }
}
chain input {
type filter hook input priority 1000; policy drop;
tcp dport @web accept
log prefix "Dropped by tenant1: "
}
}
Что я ожидал, так это то, что трафик на порту 22 будет допущен к этой машине (через таблицу управления, цепочку input, правило tcp dport 22) и также будет допущен трафик на портах 80 и 443 (через таблицу tenant1). На самом деле происходит следующее: трафик на порту 22 направляется в следующую таблицу для обработки (tenant1), в то время как все остальное отклоняется….?
Судя по тому, что я понимаю из документации и наблюдаю, оказывается, что принятый пакет не обязательно принимается, если есть другие таблицы/цепочки с тем же hook (в нашем случае input), которые в конечном итоге отклонят пакет.
Если мое предположение верно, возникает вопрос: как же тогда использовать таблицы в nftables? Потому что я ожидал, что это будет работать следующим образом: у нас есть две таблицы, если пакет принят в одной из них, то он принимается полностью. Если пакет отклоняется в одной из них, то он отклоняется полностью. Я думал, что трафик оценивается в КАЖДОЙ из таблиц, и первая таблица, которая примет решение о том, что делать с пакетом, имеет приоритет.
Любая помощь будет очень признательна, так как я немного потерян в том, как я мог бы использовать таблицы в nftables.
P.S. Я видел, что действие accept можно установить для маркировки пакетов, и последующие таблицы проверят эту метку, но это кажется “взломом”, а не решением.
Честно говоря, после игры с этим новым и улучшенным брандмауэром, по крайней мере для моих нужд (простые NAT/фильтрационные правила), это намного хуже. Я имею в виду, в iptables прием — это… ну, прием, а не возможно. Что, черт возьми, я упускаю??? И не заставляйте меня говорить о проблеме с приоритетом, где меньшее число означает больший приоритет :))
Ответ или решение
Как специалист в области информационных технологий, я понимаю, что у вас возникли вопросы по поводу работы с NFTables, особенно в отношении порядка следования таблиц, хуков и правил. Рассмотрим данную тему более подробно.
Теория
NFTables — это гибкий и мощный инструмент для фильтрации сетевого трафика, который пришел на смену iptables в ядре Linux. Главное отличие заключается в том, что nftables использует концепцию таблиц и цепочек, которые действуют в зависимости от определенных событий или "хуков" в сети. Четыре основные хука включают prerouting
, input
, forward
, output
и postrouting
. Эти хуки соответствуют точкам обработки пакетов в сетевой системе Linux.
Одним из ключевых аспектов nftables является использование приоритетов для определения порядка выполнения правил в цепочках. Чем меньше числовое значение приоритета, тем раньше оно будет выполнено. Это может вызвать некоторую путаницу у пользователей, привыкших к другому порядку в iptables.
Когда мы говорим об "accept", "drop" или других действиях в nftables, важно понимать, что различный приоритет цепочек означает, что пакеты могут проходить через несколько цепочек в рамках одного хука, прежде чем будет принято окончательное решение. Если пакет "принимается" в одной цепочке, но обработка продолжается, другая цепочка с более низким приоритетом может "выкинуть" этот пакет.
Пример
Расмотрим ваш пример конфигурации:
table inet management {
chain input {
type filter hook input priority -1000; policy drop;
iifname "lo" counter packets 16 bytes 996 accept
ct state established,related counter packets 22982 bytes 1739629 accept
tcp dport 22 counter packets 0 bytes 0 accept
log prefix "Dropped by management: "
}
}
table ip tenant1 {
set web {
type inet_service
elements = { 80, 443 }
}
chain input {
type filter hook input priority 1000; policy drop;
tcp dport @web accept
log prefix "Dropped by tenant1: "
}
}
В этой конфигурации у нас две таблицы с цепочками input
, но с разным приоритетом: цепочка в таблице management
имеет приоритет -1000, а в таблице tenant1
— приоритет 1000. Поскольку меньшее числовое значение приоритета выполняется первым, цепочка management
будет обрабатывать пакеты до цепочки tenant1
.
Применение и решение
Основная сложность вашей конфигурации заключается в ожиданиях от совместной работы таблиц. Приняли ли вы решение принимать пакеты, оно может быть отменено последующими цепочками с более низким приоритетом, и это может запутывать. Если вы хотите, чтобы после того, как пакет был "принят" в management
, он не обрабатывался дальше в других таблицах, стоит использовать флаги или маркировку пакетов.
-
Используйте маркировку пакетов: Как вы уже упомянули, можно пометить пакеты в одной таблице после принятия, и создать правило в другой таблице, которое бы игнорировало уже помеченные пакеты.
Например, вы можете добавить действие маркировки в цепочке
management
:tcp dport 22 counter packets 0 bytes 0 meta mark set 1 accept
И добавить условие в цепочку
tenant1
, чтобы проверять метку:meta mark 1 accept
-
Изучите структуру хуков: Если определённый трафик не должен проходить через все таблицы, вместо этого разными хуками управляйте путем трафика. Так, использование
prerouting
иpostrouting
позволит добавить фильтры до и после основного процесса обработки, что может изменить траекторию трафика, предоставляя больше контроля. -
Уточните приоритеты: Измените приоритеты так, чтобы
tenant1
обрабатывал пакеты раньше или позже в зависимости от вашей цели. Еслиtenant1
должен обрабатывать трафик до вашегоmanagement
, приоритет нужно уменьшить.
Заключение
NFTables может показаться сложным по сравнению с iptables из-за более сложной структуры, но его гибкость и возможности значительно шире. Если принять во внимание порядок выполнения цепочек и приоритеты, а также использовать возможности маркировки, это позволяет создавать более сложные и адаптируемые политики сетевой безопасности. Благодаря этим аспектам вы сможете настраивать фильтрацию трафика более точно, достигнув желаемых результатов.