В чем разница между "iifname" и "iif" в nftables?
https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes
Есть ли разница между iifname
(вне названия есть строка) и iif
а что рекомендуется?
2 ответа
iif
ищет и сравнивает индекс интерфейса полученного пакета, а iifname
выполняет сравнение строк с именем интерфейса. Оба имеют свои преимущества и недостатки.
Так iif
использует меньше ресурсов, потому что индекс интерфейса - это простое число, уже сохраненное в пакете, проходящем через сетевой стек и nftables и, таким образом, сразу доступное для сравнения. Но его недостатком является то, что если интерфейс удален (и, скорее всего, воссоздан, но с более новым значением индекса), то соответствующее правило в nftables больше не будет совпадать. Единственный гарантированный интерфейсный указатель на все времена - это петлевой интерфейс lo
по умолчанию): он всегда создается первым в пространстве имен и не может быть удален (или добавлен второй раз), поэтому его значение индекса всегда 1
,
iifname
с другой стороны, так же, как iptables --in-interface
выполняет сравнение строк с именем текущего интерфейса. Это использует больше ресурсов, но позволяет заранее создать правило для несуществующего интерфейса с детерминированным именем, которое iif
не будет легко iifname
также можно сделать подстановочный знак, как в iifname "ppp*"
, который iif
не может и может быть полезен, когда интерфейсы создаются и удаляются часто, но соблюдая соглашение об именах (например, начиная с ppp
для PPP-ссылок).
Пример (с использованием nftables 0.9.2):
$ unshare -r -n
# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# nft add table ip filter
# nft add chain ip filter input '{ type filter hook input priority 0; policy accept; }'
# nft add rule ip filter input iif lo counter
# nft add rule ip filter input iif dummy0 counter
Error: Interface does not exist
add rule ip filter input iif dummy0 counter
^^^^^^
# nft add rule ip filter input iifname dummy0 counter
# ip link add name dummy0 type dummy
# ip link
1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
2: dummy0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
link/ether 4a:09:68:3a:34:91 brd ff:ff:ff:ff:ff:ff
# nft add rule ip filter input iif dummy0 counter
# nft list ruleset
table ip filter {
chain input {
type filter hook input priority filter; policy accept;
iif "lo" counter packets 0 bytes 0
iifname "dummy0" counter packets 0 bytes 0
iif "dummy0" counter packets 0 bytes 0
}
}
# ip link delete dev dummy0
# nft list ruleset
table ip filter {
chain input {
type filter hook input priority filter; policy accept;
iif "lo" counter packets 0 bytes 0
iifname "dummy0" counter packets 0 bytes 0
iif 2 counter packets 0 bytes 0
}
}
Интерфейс пропал, вместо него отображается его индексное значение. Аналогично, значение индекса может использоваться, даже заранее, при добавлении правила:
# nft add rule ip filter input iif 3 counter
# nft list ruleset
table ip filter {
chain input {
type filter hook input priority filter; policy accept;
iif "lo" counter packets 0 bytes 0
iifname "dummy0" counter packets 0 bytes 0
iif 2 counter packets 0 bytes 0
iif 3 counter packets 0 bytes 0
}
}
# ip link add name dummy4 type dummy
# ip link add name dummy0 type dummy
# nft list ruleset
table ip filter {
chain input {
type filter hook input priority filter; policy accept;
iif "lo" counter packets 0 bytes 0
iifname "dummy0" counter packets 0 bytes 0
iif 2 counter packets 0 bytes 0
iif "dummy4" counter packets 0 bytes 0
}
}
Поскольку значения индекса интерфейса не перерабатываются в пространстве имен, а только увеличиваются, правило для индекса 2 "теряется" (оно никогда не сможет больше соответствовать). Следующему созданному интерфейсу, dummy4, был присвоен индекс 3, который теперь разрешается в dummy4
в наборе правил. dummy0 получил значение индекса 4, на которое не ссылается ни один iif
правило, но все равно будет соответствовать iifname
править.
Что рекомендуется?
Мой совет:
Вы должны использовать iif
для "стабильных" интерфейсов, которые не изменятся после создания, например физических интерфейсов Ethernet, доступных при загрузке, до применения правила (если используется более новое соглашение о стабильном именовании физических интерфейсов, которое не изменится при изменении порядка перечисления), и конечно интерфейс lo. Это не было показано в примере, но вы все равно можете сопоставить список интерфейсов с iif
тоже вроде iif { lo, dummy4 }
, Таким образом, вы все еще можете иметь один iif
оператор, соответствующий нескольким интерфейсам.
Вы должны использовать iifname
для динамических интерфейсов, не известных при загрузке (и при создании правил), но ожидаемых, чтобы появиться позже, или для сопоставления группы интерфейсов с соглашением об именах при использовании подстановочного совпадения.
Не очень известно, что для оптимизации вместо использования подстановочных знаков можно назначить группу каждому вновь созданному интерфейсу (например, используя ip link set dev interface group 99
), а затем сопоставьте интерфейсную группу с iifgroup
скорее, чем iifname
+ подстановочный знак. Но это требует некоторого дополнительного механизма для группировки тегов вновь создаваемых интерфейсов.
Вы также можете использовать интерфейсные наборы имен, сохраняя при этом общие правила, используя iif
а также iifname
и изменение содержимого именованных наборов, а не самих правил. Обратите внимание, что предыдущая ссылка на вики не говорит об использовании интерфейсов в наборах, но она просто не актуальна. Больше информации об этом в моем UL SE ответ на этот вопрос: Как мне создать именованный набор строк в nftables (для имен интерфейсов)?,
Это не ответ, а просто комментарий к предыдущему ответу . (Моя плохая репутация не позволяет мне комментировать.)
Но для этого требуется некоторый дополнительный механизм для группировки тегов вновь созданных интерфейсов.
Я так делаю^^^. В нем есть раздел, где вы можете установить группу интерфейсов для каждого интерфейса. (Это раздел, прочитанный из.network
файлы поsystemd-networkd
, не[Link]
раздел читать из.link
файлы поsystemd-udevd
.)
Поэтому я бы установил что-то вроде этого в/etc/systemd/network/something.network
…
[Match]
MACAddress=my:in:te:rf:ac:e0
...
[Link]
Group=99
...
…а потомip link show group 99
может использоваться для проверки того, что интерфейсы (действительно) помечены правильно. (Те, у кого нет группы, находятся в группе0
.) (Такжеip link show
печатает номера групп.)
Это дает возможность использоватьiifgroup
иoifgroup
вnftables.conf
.