IPtables SNAT吃包

我正在尝试将输出的UDP数据包与X的源端口转换为Y的源端口。

我已经使用下面的iptables规则做到了这一点:

iptables -t nat -A POSTROUTING -s 10.0.0.1 -p udp --sport X -j SNAT --to-source 10.0.0.1:Y 

这个规则的计数器在源端口为X的数据包生成时增加,但在此之后完全消失。 我找不到他们在任何其他链或表的计数器,并不能看到他们在使用tcpdump的任何接口。

如果我删除了这个规则 ,那么数据包就会和X的源端口一起收到。但是一旦我把规则放回去,数据包就会消失。

我正在使用在Voyage Linux上运行的iptables版本v1.2.11。 我无法轻易更新,因为这需要在几百个远程设备上完成。

我究竟做错了什么?

编辑:添加下面的iptablesconfiguration,有关特定应用程序,不能影响这个规则已被删除。

 # Clear any existing rules iptables -v -t filter -F iptables -v -t nat -F iptables -v -t mangle -F iptables -v -t filter -X iptables -v -t nat -X iptables -v -t mangle -X # Policies iptables -t mangle -P PREROUTING ACCEPT iptables -t nat -P PREROUTING ACCEPT iptables -t filter -P INPUT DROP iptables -t filter -P OUTPUT ACCEPT iptables -t filter -P FORWARD DROP # Allow established connections. iptables -t filter -A INPUT -m state --state ESTABLISHED -j ACCEPT iptables -t filter -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -t filter -A FORWARD -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -t filter -A OUTPUT -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -t filter -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT # Allow localhost to talk to itself. iptables -t filter -A INPUT -i lo -j ACCEPT # Drop stealth scan. iptables -t filter -A INPUT -p tcp -s 0/0 -d 0/0 --tcp-flags ALL NONE -j DROP iptables -t filter -A INPUT -p tcp -s 0/0 -d 0/0 --tcp-flags ALL ALL -j DROP iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,PSH,ACK,URG NONE -j DROP iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags SYN,FIN SYN,FIN -j DROP iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags SYN,RST SYN,RST -j DROP iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags FIN,RST FIN,RST -j DROP iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags ACK,FIN FIN -j DROP iptables -t filter -A INPUT -p tcp -m tcp --tcp-flags ACK,URG URG -j DROP # Allow forwarding from LAN to WAN. iptables -t filter -A FORWARD -i lanif -o wanif -j ACCEPT # The NAT, strict with fixed IP address - might be different with a DHCP assigned WAN_IP iptables -t nat -A POSTROUTING -o wanif -j SNAT --to-source $WAN_IP iptables -t nat -A POSTROUTING -m mark --mark 11 -j ACCEPT # Change source port X to Y - why does this not work??? iptables -t nat -A POSTROUTING -s lanif -p udp --sport X -j SNAT --to-source wanif:Y 

我究竟做错了什么?

可能没什么。 这是数据包穿越Netfilter的方式。

查看此图表作为参考:

(来源:2006年Oskar Andreasson的Iptables教程1.2.1 )

我找不到任何其他连锁或桌子的柜台

SNAT是最终的Netfilter目标,数据包将不会出现在同一链中。 nat -table中的POSTROUTING -chain是数据包可以遍历Netfilter框架的绝对最终表。 Tcpdump附加到一个相当先进的阶段,我认为mangle/POSTROUTING

并不能使用tcpdump在任何接口上看到它们。 这是因为tcpdump在获取SNAT之前就会看到数据包。

实际上出了什么问题 ? 这听起来像是非常正常的Netfilter-tcpdump怪异。

编辑:你的SNAT声明在最后发生。 也许你需要在-o wanif -j SNAT --to-source $WAN_IP语句之前插入它。 由于我没有更多的细节,我不知道这是一个错误还是故意的。

我会期望看到这样的事情:

 iptables -t nat -A POSTROUTING -s 10.0.0.1 -p udp --dport X -j SNAT --to-port Y 

也许有一个服务,已经在该端口上侦听。 iptables的SNAT,在做翻译的时候会试着保留和原始数据包一样的端口。 如果这个端口不可用,它将使用另一个端口。

我有这个问题试图SNAT DNS服务器的答复。 这导致答复从端口1发送,因为DNS服务器已经在使用端口53。

解决的方法是让dns服务器在不同的端口上侦听,redirect从目的端口53到目的端口X的inputstream量,然后SNAT也将端口从X重写为53。