使用 iptables 随机化每个数据包的目标端口

使用 iptables 随机化每个数据包的目标端口

服务器端有一个程序监听端口 3333,还有一个专用的客户端向服务器发送和接收数据包,我想设置一组 iptables 规则,使每一个空中传输带有随机端口号的数据包。

这是我所做的:

####Client side
iptables -t nat -A OUTPUT --dst server.ip.addr -p udp --dport 3333 -j DNAT --to-destination :10000-19999 --random

####Server side
iptables -t nat -A PREROUTING --dst server.ip.addr -p udp --match multiport --dport 10000:19999 -j REDIRECT --to-ports 3333

这基本上是可行的,但是 DNAT 只会对“连接”的第一个数据包进行随机化,后面的数据包只使用保存在连接状态表中的端口号,并且在“连接”存在时不会改变。

然后我尝试使用以下命令禁用连接跟踪:

####Client side
iptables -t raw -A OUTPUT -p udp --dport 3333 -j NOTRACK

现在服务器和客户端无法通信,tcpdump 在服务器端没有显示任何内容,我猜想如果没有连接跟踪,DNAT 可能无法工作。

我还尝试了其他一些组合,但都不起作用。除了 SNAT/DNAT 可以修改端口之外,没有其他目标。

只是想知道我想要的是否有可能实现,或者我从一开始就错了。

谢谢你的帮助。

答案1

您所问的问题与 IP 端口系统、contrack 等的理念相悖。您将无法使用 iptables 做您想做的事情。

您能想象如果客户端中有两个不同的进程尝试与服务器建立这种流量吗?当然会很混乱。

如果您需要让您的流量难以追踪或类似的事情,我建议您考虑不同的替代方案,但始终基于非破坏性 IP 流量。

答案2

由于为您的案例设置测试环境会相当麻烦,因此此答案未经充分测试。使用时请自行承担责任。

我能想到的解决办法如下:

  1. 创建一个类似守护进程的脚本,不断更新客户端 iptables 规则,每秒更改几次端口范围。
  2. 与 1. 类似,但使用conntrack -D -p udp --dst $DEST_IP以下方法重置 UDP 状态表:conntrack 工具
  3. 使用尽可能低的值/proc/sys/net/netfilter/nf_conntrack_udp_timeout或者,可能更好,/proc/sys/net/netfilter/nf_conntrack_udp_timeout_stream

大部头书,选项 2。似乎对性能和一般连接性的损害最小。据我所知,如果没有 3,选项 1 可能无法按预期工作。

答案3

只是一个建议,但由于您只需要更改目标端口,而不是 IP 地址,您是否尝试过对输出链使用 REDIRECT 而不是 DNAT?

例如,iptables -t nat -A OUTPUT --dst server.ip.addr -p udp --dport 3333 -j REDIRECT --to-ports 10000-19999 --random

编辑:

你的问题应该出在客户端。我尝试使用 ncat(没有客户端 iptables 规则)重现你的情况:

服务器端iptables:

iptables -t nat -A PREROUTING --dst 192.168.5.129 -p udp --match multiport --dport 10000:19999 -j REDIRECT --to-ports 3333
iptables -A FORWARD -m state -p udp -d 192.168.5.129 --dport 3333 --state NEW,ESTABLISHED,RELATED -j ACCEPT

服务器端 ncat:

ncat -ul 3333

客户端 ncats:

ncat -p 3333 -u 192.168.5.129 10004
ncat -p 3333 -u 192.168.5.129 10003

使用此设置,服务器端的重定向可以正常工作。我相信问题出在 iptables 的“--random”选项中,这可能意味着 DNAT 会随机化连接的端口映射,而不是单个数据包的端口映射。

另一个问题可能是 UDP 标头中的可选“源端口”字段。如果设置了该字段,防火墙可能仍能跟踪您的连接。

相关内容