我正在开发一个应用程序,该应用程序应根据某些规则将 UDP 数据包从一个主机中继到另一个主机。它基本上是 NAT。
我与两个主机协商 UDP 端口,然后我需要使用协商后的端口从主机 A 接收数据并发送到主机 B。
所以我正在动态地添加和删除iptables
规则。
# 我的地址是 10.1.1.1 # A 是 10.10.10.10:30590 - 10.1.1.1:36232 # B 是 10.20.20.20:30588 - 10.1.1.1:36230 # 从 A 到 B iptables -t nat -A PREROUTING -s 10.10.10.10/32 -i eth0 -p udp -m udp --sport 30590 -j DNAT --to-destination 10.20.20.20:30588 iptables -t nat -A POSTROUTING -d 10.20.20.20/32 -p udp -m udp --dport 30588 -j SNAT --to-source 10.1.1.1:36232 # B 到 A iptables -t nat -A PREROUTING -s 10.20.20.20/32 -i eth0 -p udp -m udp --sport 30588 -j DNAT --to-destination 10.10.10.10:30590 iptables -t nat -A POSTROUTING -d 10.10.10.10/32 -p udp -m udp --dport 30590 -j SNAT --to-source 10.1.1.1:36230
这种方法在大多数情况下都有效,但是有时第一个数据包在规则添加之前就开始到达。清除 UDP“连接”可使规则生效(conntrack -D -p udp
)。
我尝试使用如下规则禁用连接跟踪:
iptables -t raw -A PREROUTING -j NOTRACK iptables -t raw -A OUTPUT -j NOTRACK # 或者 iptables -t raw -A PREROUTING -j CT --notrack iptables -t raw -A OUTPUT -j CT --notrack
但这些似乎都不起作用。
唯一的解决方案是清除每个流的 UDP 连接跟踪吗?
我需要支持数千个并发流,并且每秒都会添加和删除几个。
编辑2020:
我们最终使用 BPF XDP 来管理流,而且效果非常好!
答案1
禁用连接跟踪并不合适,因为 NAT 依赖于连接跟踪,因此 NAT 将停止工作。
插入 NAT 规则后,您必须清除所有相关的现有连接跟踪记录,以便任何后续到达的数据包都会检查表中nat
是否有新的 DNAT/SNAT 规则,而不仅仅是查找“缓存”结果。
然而,你能使其比conntrack -D -p udp
影响所有 udp 连接跟踪记录的目标更具体;例如,conntrack -D -p udp --src <ip> --sport <port> --dst <ip> --dport <port>
只允许清除特定 src/dst ip 和端口对的记录。