为什么有些iptables的DNAT规则在重新启动之前不工作?

我的iptables DNAT规则不能工作,直到重新启动。 如果我重新启动我的服务器,所有的规则工作。

架构描述:

数十个主机(发送者)发送一些UDP数据包(单向的特定端口9999)到我的Linux路由器。 这个Linux路由器使用iptables将这些数据包转发给几台主机(接收器)。

senderX 10.0.0.X ====>使用iptables的Linux路由器====> receiverY 10.0.1.Y

Linux路由器有两个网卡eth1 10.0.0.1/24(发送方)和eth0 10.0.1.1/24(接收方)。

iptables设置:

  • ip_forwarding被激活
  • 所有的默认策略都设置为ACCEPT
  • 一个iptables规则存在每个发件人,这里是一个例子:
 iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT  - 到目的地10.0.1.123

networking设置 :

ip addr show

 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 54:9f:35:0a:16:38 brd ff:ff:ff:ff:ff:ff inet 10.0.1.1/24 brd 10.0.1.255 scope global eth0 inet6 fe80::569f:35ff:fe0a:1638/64 scope link valid_lft forever preferred_lft forever 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000 link/ether 54:9f:35:0a:16:3a brd ff:ff:ff:ff:ff:ff inet 10.0.0.1/24 brd 10.0.0.255 scope global eth1 inet6 fe80::569f:35ff:fe0a:163a/64 scope link valid_lft forever preferred_lft forever 

症状:

添加一组规则后,其中一些规则不起作用。 我可以用tcpdump看到UDP数据包不再被路由,数据包被拒绝。

 tcpdump -n -i eth1 host 10.0.0.2 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 65535 bytes 16:12:58.241225 IP 10.0.0.2.56859 > 10.0.0.1.9999: UDP, length 1464 16:12:58.241285 IP 10.0.0.1 > 10.0.0.2: ICMP 10.0.0.1 udp port 9999 unreachable, length 556 
  • 如果我冲洗所有的规则,并在iptables中重新注册它们,那么不起作用的规则仍然不起作用。
  • 如果我重新启动我的服务器所有的规则工作正常。

分析完成:

我已经添加了一个规则来logging特定的发件人不工作:

 iptables -t nat -A PREROUTING -s 10.0.0.2 -i eth1 -j LOG --log-prefix='PREROUTING LOG :' 

但是这个规则不logging任何东西。 数据包来了,因为我看到在tcpdump的,但他们没有logging。 另外在iptables中使用-v选项,我没有看到针对这个规则增加的计数器。

如果我在停止工作之前应用相同的规则,我有一些日志。

题 :

  • 在iptables中UDP转发是否有限制?
  • 我如何解决这个问题?

您描述的症状与NAT规则和连接跟踪条目之间存在冲突时看到的相符。

例如,当一个数据包被匹配

 -A PREROUTING -s 10.0.0.2 -i eth1 -j DNAT --to-destination 10.0.1.123 

需要创build一个新的连接跟踪条目。 这将把传入端的源和目标IP和端口的元组映射到传出端的类似元组。

不存在匹配传入端的现有连接跟踪条目,因为如果存在,将会使用它而不是规则。 然而,一旦元组的目标IP已经被replace以构build出局端的元组,该元组可能与现有的连接跟踪条目冲突。

如果安装conntrack实用程序,则可以键入conntrack -L以查看现有连接跟踪条目的列表。 该实用程序还具有仅列出符合特定条件的连接跟踪条目以及删除所选条目的function。

如果这确实是您所面临的问题,那么删除违规的连接跟踪条目将使问题消失。 永久修复通常包括在两个方向上为数据包configuration相关的NAT规则,以便始终获得所需的连接跟踪条目,即使第一个数据包碰巧发送方向与通常情况相反。