我设置了一条匹配多播数据包的规则,如下所示:
add rule filter_4 new_out_4 meta pkttype multicast goto multicast_out_4
filter_4
是 IPv4 表,new_out4
是输出链,multicast_out_4
是处理纯组播流量的链。
以下是排除不相关部分的 IPv4 表的更完整图片:
#!/usr/sbin/nft -f
add table filter_4
add chain filter_4 output {
# filter = 0
type filter hook output priority filter; policy drop;
}
add chain filter_4 multicast_out_4 {
comment "Output multicast IPV4 traffic"
}
add chain filter_4 new_out_4 {
comment "New output IPv4 traffic"
}
#
# Stateful filtering
#
# Established IPv4 traffic
add rule filter_4 input ct state established goto established_in_4
add rule filter_4 output ct state established goto established_out_4
# Related IPv4 traffic
add rule filter_4 input ct state related goto related_in_4
add rule filter_4 output ct state related goto related_out_4
# New IPv4 traffic ( PACKET IS MATCHED HERE )
add rule filter_4 input ct state new goto new_in_4
add rule filter_4 output ct state new goto new_out_4
# Invalid IPv4 traffic
add rule filter_4 input ct state invalid log prefix "drop invalid_filter_in_4: " counter name invalid_filter_count_4 drop
add rule filter_4 output ct state invalid log prefix "drop invalid_filter_out_4: " counter name invalid_filter_count_4 drop
# Untracked IPv4 traffic
add rule filter_4 input ct state untracked log prefix "drop untracked_filter_in_4: " counter name untracked_filter_count_4 drop
add rule filter_4 output ct state untracked log prefix "drop untracked_filter_out_4: " counter name untracked_filter_count_4 drop
在上面的设置中,包括多播在内的新输出流量通过规则进行匹配add rule filter_4 output ct state new goto new_out_4
这是new_out_4
仅包含不起作用的相关(非工作)多播规则的链:
# Multicast IPv4 traffic ( THIS RULE DOES NOT WORK, SEE LOG OUTPUT BELOW)
add rule filter_4 new_out_4 meta pkttype multicast goto multicast_out_4
#
# Default chain action ( MULTICAST PACKET IS DROPPED HERE )
#
add rule filter_4 new_out_4 log prefix "drop new_out_4: " counter name new_out_filter_count_4 drop
以下是日志中有关丢弃的多播数据包的内容:
删除new_out_4:IN = OUT = eth0 SRC = 192.168.1.100 DST = 224.0.0.251 LEN = 163 TOS = 0x00 PREC = 0x00 TTL = 255 ID = 27018 DF PROTO = UDP SPT = 5353 DPT = 5353 LEN = 143
被丢弃的数据包被发送到目标地址224.0.0.251
,这是多播地址,它应该与new_out_4
链中的多播规则匹配,并且应该由multicast_out_4
链处理,但没有。
相反,数据包不匹配,并被上面链中的默认丢弃规则丢弃new_out_4
,请参阅注释(默认链操作)。
显然这意味着组播规则不起作用。
为什么组播规则不起作用?
预期的:
meta pkttype multicast
匹配目标地址224.0.0.251
编辑:
系统信息:
内核:6.5.0-0.deb12.4-amd64
与早期内核 6.1 存在相同的问题
nftables:v1.0.6(莱斯特·古奇#5)
使用一些附加条目复制(并完成缺失的部分)设置,例如:
meta pkttype
实际上,此 skbuff 的属性不是传出多播数据包的host
预期属性。multicast
请注意,当引入这个关键字时,它是关于输入,而不是输出:实际上iptables的直接等价物是pkttype 匹配模块:
将所有这些放在一起,当创建传出 IP(路由:第 3 层)数据包时,它尚未到达第 2 层(链路层),因此它的 skbuff 不会反映它可能会变成什么,即使以后打算这样做。
实际应该测试的是关于路由堆栈的IP地址属性,而不是关于以太网的数据包属性。
iptables
为此提供了addrtype
匹配模块:它的翻译暗示了实际应该使用什么:
fib
表达式:没有多播的直接示例。最近的例子是一个更复杂的例子,关于丢弃不打算用于传入接口上的地址的 pacjet,其中多播属于 3 个例外:
因此,只需替换输出(或后路由)挂钩中使用的任何位置即可:
和:
在输入(或预路由)钩子中,虽然 skbuff 属性可能与 IP 属性匹配,但为了保持一致,也应该将其替换为完全相同:
下面的测试命令在 LAN 中的其他主机(用于测试输入)和主机(用于测试输出)上联合使用:
将正确匹配
fib daddr type multicast
输入和输出。重要说明:
我相信上面解决了这个问题,但请注意,Netfilter 的conntrack无法正确跟踪多播,因为它无法将使用其他单播源地址的回复与初始查询的多播目标地址关联起来:它们不同,因此它考虑回复为其他(新)流,而不是将它们关联起来并将此类回复视为前一个流的一部分。因此,这种流永远不会通过conntrack或
conntrack -L
命令显示为 ESTABLISHED 状态。规则集应该适应这一点:它不能仅依赖于ct state established,related
某种规则,但这超出了这个问题的范围。