我只想将发往单个 IP 和 UDP 端口的非常有限的数据包流量镜像到同一个 IP 但第二个端口。我已经锁定在https://superuser.com/questions/1593995/iptables-nftables-forward-udp-data-to-multiple-targets但似乎 nftable 的 dup 语句只允许复制到另一个 IP 但不一样IP和不同的端口。
例如,到 127.0.0.1 端口 123 的流量应该复制到 127.0.0.1 端口 456。由于这是唯一的单一复制,因此原始端口号丢失没有任何问题。现在我想知道这种复制是否可能,因为 127.0.0.1 不是“排水”/传出接口,而是复制的最终目的地。有没有办法将它与 DNAT 结合起来?
除了将 eBPF 探测附加到带有传入 UDP 流量的 netdev 之外,还有其他可用的机制吗?
这可以通过带有入口链和dup语句的nftables和netdev系列来完成。它需要使用标记来避免无限循环。根据具体的用例,复制也可以在出口上完成(因为它在环回接口上,复制的出口数据包将显示为ingress)但这需要内核 >= 5.17 来支持,而ingress已经可用需很长时间。
需要内核 >= 4.10(用于无状态 UDP 更改正确校验和支持)。
检查候选数据包是否有标记,只有在没有标记时才处理,首先设置标记:这将防止以后出现循环。
它是重复的。作为重复的sk_buff一部分的标记也被重复
副本实际上是未更改的数据包:发送到同一个地方 (
lo
) 以及端口 123该
dup
语句与任何iptables的目标(包括其TEE
目标)相反,不是规则终止语句。规则继续进行数据包的无状态更改:UDP 端口更改为 456重复的数据包也到达入口,但由于它被标记,规则将忽略它:防止循环
可以使用socat测试复制的端口:
笔记:
如果没有在重复端口上监听,则会发出一个 ICMP 端口不可访问,但由于此端口 (456) 与发送应用程序发送到的端口 (123) 不匹配,因此网络堆栈将忽略它。
Netfilter 的入口发生在 AF_PACKET 之后,tcpdump不会捕获更改的端口,也不会捕获重复的数据包。