iptables REDIRECT仅适用于第一个数据包

如果数据包包含stringtest则需要将所有目标端口为15000的UDP数据包redirect到端口15001。 我有这两个简单的规则:

 iptables -t nat -A PREROUTING -i eth0 -p udp --dport 15000 -m string --string 'test' --algo bm -j LOG --log-prefix='[netfilter] ' iptables -t nat -A PREROUTING -i eth0 -p udp --dport 15000 -m string --string 'test' --algo bm -j REDIRECT --to-ports 15001 

奇怪的行为:

  • 如果第一个数据包包含teststring,则对连接的所有数据包进行redirect;
  • 如果连接的第一个数据包不包含test ,即使后续数据包包含test ,也不会执行redirect

但是所有匹配规则的数据包都被正确logging

我试图添加轨道信息的规则:

 -m state --state NEW,ESTABLISHED 

但行为是一样的。 有些想法?

这是完整的iptables规则集:

过滤表:

 Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination 

nat表:

 Chain PREROUTING (policy ACCEPT) target prot opt source destination LOG udp -- anywhere anywhere udp dpt:15000 STRING match "test" ALGO name bm TO 65535 LOG level warning prefix "[netfilter] " REDIRECT udp -- anywhere anywhere udp dpt:15000 STRING match "test" ALGO name bm TO 65535 redir ports 15001 Chain INPUT (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) 

mangle桌:

 Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain INPUT (policy ACCEPT) target prot opt source destination Chain FORWARD (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination Chain POSTROUTING (policy ACCEPT) target prot opt source destination 

原始表格:

 Chain PREROUTING (policy ACCEPT) target prot opt source destination Chain OUTPUT (policy ACCEPT) target prot opt source destination 

nat表规则总是只适用于连接的第一个数据包。 相同连接的后续数据包不会遍历nat规则列表,只能由conntrack代码支持

由于UDP本质上是无连接的,所以这里的“连接”仅仅由地址,端口和超时来定义。 因此,如果第二个具有相同源端口和地址以及相同目的地端口和地址的UDP包在超时内到达,则Linux认为它属于已build立的“连接”,并且根本不评估nat规则表,重复使用之前发出的判定包。

看到这里: http : //www.netfilter.org/documentation/HOWTO/netfilter-hacking-HOWTO-3.html

这是由于iptables在PREROUTING链上应用连接跟踪的事实造成的。 每当有新的连接时,iptables都会查询conntrackcaching。 如果find匹配项,则不会从nat表应用规则。

如果要禁用更改此行为,请查看原始表中的NOTRACK目标。

请注意,这甚至适用于UDP(这是一个无连接协议)。 第一个数据包被认为是开放连接NEW ,另一个是ESTABLISHED

我在serverfault上find一个相关的post。