从手册中我无法清楚了解这些命令的功能是否相同:
meta skuid == "root" counter accept
skuid 0 counter accept
还
ct state == { established, related } counter accept
ct state established,related counter accept
我关于语法的问题是:
- 我可以跳过单词吗
meta
(似乎在中使用项目时必须跳过log flags
)? - 我可以在任何匹配某些内容的命令中添加 == 符号吗(为了便于阅读)?
- 我可以将列表(项目集)写为
item1,item2
和不可以吗{ item1, item2 }
,或者它仅适用于ct
命令?
答案1
要验证两个规则是否相同,甚至不仅仅是显示相同(在涉及多个协议层的极少数情况下,规则可能显示相同,功能相同,但在字节码级别不完全相同,这几乎是一个可重复性错误),请使用该选项,--debug=netlink
该选项还将显示发送到内核的字节码。如果字节码相同,则规则相同。
这是一个交互式示例(使用 nftables 1.0.9。结果可能根据版本的不同而略有不同):
$ unshare -Urnm
# nft -V
nftables v1.0.9 (Old Doc Yak #3)
cli: editline
json: yes
minigmp: no
libxtables: yes
# nft add table t
# nft add chain t c
# nft --debug=netlink add rule t c 'meta skuid == "root" counter accept'
ip t c
[ meta load skuid => reg 1 ]
[ cmp eq reg 1 0x00000000 ]
[ counter pkts 0 bytes 0 ]
[ immediate reg 0 accept ]
# nft --debug=netlink add rule t c 'skuid 0 counter accept'
ip t c
[ meta load skuid => reg 1 ]
[ cmp eq reg 1 0x00000000 ]
[ counter pkts 0 bytes 0 ]
[ immediate reg 0 accept ]
# nft --debug=netlink add rule t c 'ct state == { established, related } counter accept'
__set%d t 3 size 2
__set%d t 0
element 00000002 : 0 [end] element 00000004 : 0 [end]
ip t c
[ ct load state => reg 1 ]
[ lookup reg 1 set __set%d ]
[ counter pkts 0 bytes 0 ]
[ immediate reg 0 accept ]
# nft --debug=netlink add rule t c 'ct state established,related counter accept'
ip t c
[ ct load state => reg 1 ]
[ bitwise reg 1 = ( reg 1 & 0x00000006 ) ^ 0x00000000 ]
[ cmp neq reg 1 0x00000000 ]
[ counter pkts 0 bytes 0 ]
[ immediate reg 0 accept ]
可以看出,前 2 条规则是相同的。Indeed"root"
照常由用户空间解析为 uid 0,并且meta
关键字是可选的(至少对于此处的版本而言)。
最后两条规则,即使功能相同,也不完全相同。On case 使用一组匿名的两个值。但这两个值应该以按位方式组合(即:所有可能的符号都有不同的 2 指数作为值),这就是最后一条规则的作用,其中 扮演了,
不同的角色。乍一看,我会说第二条ct
规则比第一条更优化:不需要涉及集合查找。
第一种情况仍然存在:当使用vmap
(判定图而不是简单集合)根据以下情况调用不同的判定时连接跟踪单一规则中的规定。
无论你选择什么,对于给定的nftables版本,它将始终以一种方式显示回来:
# nft -s list ruleset
table ip t {
chain c {
meta skuid 0 counter accept
meta skuid 0 counter accept
ct state { established, related } counter accept
ct state established,related counter accept
}
}
#
这可能就是应该使用的,或者最终可能会被使用的,只是因为当手动处理而不是通过工具处理时,转储规则集,编辑它并重新加载它通常是可行的。
中的情况ct
根本无法概括:只有涉及两个值的幂时才能完成第二种变体(如果实现了特定的语法支持),因此它们可以通过按位运算进行组合:
# nft describe ct state
ct expression, datatype ct_state (conntrack state) (basetype bitmask, integer), 32 bits
pre-defined symbolic constants (in hexadecimal):
invalid 0x00000001
new 0x00000008
established 0x00000002
related 0x00000004
untracked 0x00000040
#
一个明显的例子是使用 TCP 标志nftables:
# nft describe tcp flags
payload expression, datatype tcp_flag (TCP flag) (basetype bitmask, integer), 8 bits
pre-defined symbolic constants (in hexadecimal):
fin 0x01
syn 0x02
rst 0x04
psh 0x08
ack 0x10
urg 0x20
ecn 0x40
cwr 0x80
#
就像ct
:
# nft --debug=netlink add rule t c 'tcp flags { ack,syn } accept'
__set%d t 3 size 2
__set%d t 0
element 00000010 : 0 [end] element 00000002 : 0 [end]
ip t c
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 1b @ transport header + 13 => reg 1 ]
[ lookup reg 1 set __set%d ]
[ immediate reg 0 accept ]
# nft --debug=netlink add rule t c 'tcp flags ack,syn accept'
ip t c
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 1b @ transport header + 13 => reg 1 ]
[ bitwise reg 1 = ( reg 1 & 0x00000012 ) ^ 0x00000000 ]
[ cmp neq reg 1 0x00000000 ]
[ immediate reg 0 accept ]
# nft --debug=netlink add rule t c 'tcp flags ack|syn accept'
ip t c
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 1b @ transport header + 13 => reg 1 ]
[ bitwise reg 1 = ( reg 1 & 0x00000012 ) ^ 0x00000000 ]
[ cmp neq reg 1 0x00000000 ]
[ immediate reg 0 accept ]
#
最后两条规则(请注意使用|
按位或运算而不是,
内置语法)完全相同。但第一条规则使用匿名集,就像上一种情况一样。在此示例的所有情况下,多个 TCP 标志中有一个匹配就足以匹配:功能等效。如果需要同时匹配两个标志,则只有第二种情况可用。
通常,下面的规则需要同时存在两个标志,不能用匿名集来实现:
# nft --debug=netlink add rule t c 'tcp flags & (syn|ack) == syn|ack accept'
ip t c
[ meta load l4proto => reg 1 ]
[ cmp eq reg 1 0x00000006 ]
[ payload load 1b @ transport header + 13 => reg 1 ]
[ bitwise reg 1 = ( reg 1 & 0x00000012 ) ^ 0x00000000 ]
[ cmp eq reg 1 0x00000012 ]
[ immediate reg 0 accept ]
# nft list ruleset
[...]
tcp flags syn,ack / syn,ack accept
[...]
注意:以这种方式组合标志是没有意义的,ct
因为与 TCP 标志相反,一次只能存在一个标志(给定的数据包不能有多个连接跟踪状态)。