https://wiki.nftables.org/wiki-nftables/index.php/Quick_reference-nftables_in_10_minutes#Meta
iifname
(外面的名字是字符串)和iif
推荐的有什么区别吗?
iif
查找并比较接收到的数据包的接口索引,同时iifname
与接口名称进行字符串比较。两者都有优点和缺点。
iif
使用更少的资源也是如此,因为接口索引是一个简单的数字,它已经存储在遍历网络堆栈和 nftables的数据包中,因此可以立即用于比较。但它的缺点是,如果接口被删除(并且很可能重新创建,但具有更新的索引值),那么 nftables 中的相应规则将不再匹配。始终唯一保证的接口索引是环回接口(lo
默认命名):它始终是命名空间中第一个创建的并且不能删除(也不能第二次添加),因此其索引值始终为1
。
iifname
另一方面,就像 iptables'--in-interface
与当前接口的名称进行字符串比较一样。这会使用更多资源,但允许预先为不存在的接口创建规则,并使用确定性名称,这iif
并不容易。iifname
也可以做通配符匹配,比如 in 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
}
}
Run Code Online (Sandbox Code Playgroud)
界面消失了,而是显示其索引值。同样,在添加规则时,甚至可以提前使用索引值:
# 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
}
}
Run Code Online (Sandbox Code Playgroud)
因为接口索引值不会在命名空间内回收而只会增加,所以关于索引 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 对以下问题的回答:如何在 nftables 中创建命名的字符串集(用于接口名称)?.
归档时间: |
|
查看次数: |
4948 次 |
最近记录: |