在 nftables 中,我可以使用以下规则来匹配 IPv4 UDP DNS 数据包。
ip protocol udp udp dport 53 accept
但 IPv6 变体
ip6 protocol udp udp dport 53 accept
失败并且 nftables 说
v0001.nft:39:5-12: Error: syntax error, unexpected protocol
ip6 protocol udp udp dport 53 accept
^^^^^^^^
根据文档中的示例ip6 没有协议字段,但是如何使用 nftables 根据协议匹配这些数据包?为什么那里没有协议?
答案1
总结:
务必使用互联网族表,而不是默认的知识产权家庭,作为在 wiki 中有描述:
IPv4/IPv6 数据包都将遵循相同的规则。IPv4 数据包的规则不会影响 IPv6 数据包。两种 L3 协议的规则都会影响两者。
不要使用重复的规则。互联网家庭就是分解共同的规则:
# nft add rule inet mytable myuserchain udp dport 53 accept
将影响 IPv4 和 IPv6。
如果你真的想区分它们,请使用
meta nfproto XX
,不要使用ipXX protocol YY
:# nft add rule inet mytable myuserchain meta nfproto ipv4 udp dport 53 accept # nft add rule inet mytable myuserchain meta nfproto ipv6 udp dport 53 accept
此外,虽然 OP 的示例规则没有显示这种情况,
同样,如果您想要完全匹配整个第 4 层协议而不使用相关的特定匹配(
tcp
,udp
...),您可以执行以下操作:# nft add rule inet mytable myuserchain meta nfproto ipv4 meta l4proto udp # nft add rule inet mytable myuserchain meta nfproto ipv6 meta l4proto udp
欲了解详情,请阅读下文。
您的问题没有包含实际的重要信息:桌子这条规则被添加到。
我假设你真的在使用互联网同时处理 IPv4 和 IPv6 的家族表。
不是这样的:
nft add table ip mytable
或者这个(相同):
nft add table mytable
但像这样:
nft add table inet mytable
您稍后编写的每个命令都必须包含互联网或者它仍然会尝试添加知识产权。 喜欢:
nft add chain inet mytable myuserchain
现在因为布局IPv4和IPv6略有不同,因此规则语法中与其关联的关键字也有所不同。IPv6 固定标题不直接包含它所携带的协议。它包括“下一个报头”中的下一个报头的协议及其相关关键字nftables是nexthdr
。但下一个报头实际上并不总是包含数据有效负载的报头,它可能是任何其他的扩展头,并且您可能拥有一个 IPv6 UDP 数据包,其中 IPv6 固定头的下一个头值不是 UDP。
因此,IPv4 可以像这样正确工作:
nft add rule inet mytable myuserchain ip protocol udp udp dport 53 accept
其直接 IPv6 等效项是出现可以工作,但并不总是这样:
nft add rule inet mytable myuserchain ip6 nexthdr udp udp dport 53 accept
因为它不会匹配包含以下内容的数据包扩展头。当然,这对于最终用户来说将是一场噩梦nftables必须处理这个问题,因为也可能有多个扩展头。
由于系统已经知道所有这些,您真正关心的信息:IPv4 与 IPv6(而不是 IPv4 UDP 与 IPv6 UDP 的事实,这是一种获取ip
和ip6
接受的语法解决方法:UDP 在下一个(最后一个)匹配关键字中单独处理udp
),可用作元信息而不是数据包的内容信息:
nfproto <protocol> meta nfproto ipv4 meta nfproto != ipv6 meta nfproto { ipv4, ipv6 }
您只是试图解决一个语法变通方法,但它并不是要使用的变通方法(它会对 UDP 进行两次检查,而检查一次就足够了)。正确的语法是两个都案件应该是:
nft add rule inet mytable myuserchain meta nfproto ipv4 udp dport 53 accept
nft add rule inet mytable myuserchain meta nfproto ipv6 udp dport 53 accept
如果以后没有使用特定匹配,第 4 层协议也会存在同样的情况:
l4proto <protocol> meta l4proto 22 meta l4proto != 233 meta l4proto 33-45 meta l4proto { 33, 55, 67, 88 } meta l4proto { 33-55 }
这里的 22 并不意味着端口 22, 它的意思是议定书 22,又名xns-idp。
请注意,使用更具体的匹配已经隐含地包括了那些元生成的字节码中的过滤器(可以使用 检查nft -a --debug=netlink list ruleset
)。只有当不需要进一步过滤时,才需要它们。
以上是关于语法。当然,互联网表是为了避免规则重复。因此,在这种情况下,两者都应该简单地替换为:
nft add rule inet mytable myuserchain udp dport 53 accept
它将同时处理 IPv4 和 IPv6:因为这个表系列就是为此而存在的。
注意:protocol
可能最好用于桥家庭餐桌案例。