https://wiki.nftables.org/wiki-nftables/index.php/Quick_参考资料-表_在……里面_10_minutes#Meta
iifname (除了名称是string)和iif之间有什么不同,推荐的是什么?
发布于 2019-09-22 09:44:27
iif查找并比较接收到的数据包的接口索引,而iifname则使用接口名称进行字符串比较。两者都有其优点和缺点。
因此,iif正在使用较少的资源,因为接口索引是一个遍历网络堆栈和nftable的已存储在数据包中的简单数字,因此可以立即进行比较。但是它的缺点是,如果删除了接口(很可能是重新创建的,但索引值较新),那么nftable中的相应规则将不再匹配。在任何时候,惟一的garanteed接口索引都是环回接口(默认情况下名为lo ):它总是在命名空间中创建的第一个,不能被删除(也不能第二次添加),所以它的索引值总是1。
另一方面,iifname就像iptables的--in-interface一样,用当前接口的名称进行字符串比较。这使用了更多的资源,但允许预先为不存在的接口创建一个具有确定性名称的规则,这是iif不容易做到的。iifname也可以进行通配符匹配,就像在iifname "ppp*"中一样,当接口经常被创建和删除时,iif不能这样做,而且可以方便地使用,但是保留一个命名约定(比如以ppp作为PPP链接的开头)。
示例(使用nftable 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进行“稳定”接口,这些接口一旦创建就不会改变,就像在应用规则之前引导时可用的物理以太网接口一样(如果使用更新的物理接口稳定命名约定,如果枚举顺序发生变化,则不会更改),当然还有lo接口。示例中没有显示它,但是您仍然可以与iif匹配一个接口列表,比如iif { lo, dummy4 }。所以仍然可以有一个匹配多个接口的iif语句。
您应该将iifname用于在引导时不知道的动态接口(以及规则创建时),但希望稍后出现,或者在使用通配符匹配时将一组接口与命名约定相匹配。
不太清楚,为了进行优化,您可以为每个新创建的接口分配一个组,而不是使用通配符(例如使用ip link set dev interface group 99),然后将接口组与iifgroup而不是iifname +通配符匹配。但是这需要一些额外的机制来对新创建的接口进行分组。
您还可以使用接口命名集,从而保持使用iif和iifname的通用规则,并更改命名集的内容,而不是规则本身。请注意,前面的wiki链接并没有告诉您如何在集合中使用接口,但它并不是最新的。有关这方面的更多信息,在我的UL SE回答这个问题:如何在nftable中创建一组命名字符串(用于接口名称)?。
发布于 2020-12-11 17:29:36
这不是回答,只是对先前的回答的评论。(我的坏名声不让我评论。)
但是这需要一些额外的机制来对新创建的接口进行分组。
我使用systemd-networkd来执行^。它有一个[Link]部分,您可以在其中为每个接口设置接口组。(这是由[Link]从.network文件读取的systemd-networkd部分,而不是systemd-udevd从.link文件读取的[Link]部分。)
所以我会在/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成为可能。
https://serverfault.com/questions/985158
复制相似问题