iptables从内部ip转发数据包到外部ip

我有一个Linux机器(作为路由器)与3个私人接口(eth1,eth2,eth3)和1个公共接口(eth0)。 当数据包从接口eth3进入时,它应该通过eth0出去,当eth0回应时,它应该被redirect到eth3。

iptables中使用这些规则。

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE iptables -A FORWARD -i eth0 -o eth3 -m state --state RELATED,ESTABLISHED -j ACCEPT iptables -A FORWARD -i eth3 -o eth0 -j ACCEPT 

任何人都可以请指出我在哪里做错误。

一般来说,路由决策不是基于接口规范(eth3中的所有内容都应该通过eth0路由出去),而是根据要发送的IP数据包的目标地址进行。 如果数据包中携带一个通过eth0的路由,则将通过eth0(可能还有指定的网关)进行路由。

如果您的eth0后面的networking在目标数据包所在的位置不可路由,您将只需要MASQUERADE或SNAT规则。 在这种情况下,使用MASQUERADE目标的POSTROUTING规则会将输出IP数据包的源地址重写为eth0的地址(显然需要可路由或位于另一个NAT路由器的后面)。 MASQUERADE目标基本上是一个有状态规则,返回应答数据包将根据维护的端口:地址映射表重新写入目标地址。

除了默认的FORWARD策略设置为DROP,或者如果您是前向链中的DROP / REJECT规则(否则会过滤这种stream量),您不需要在FORWARD链中明确指定ACCEPT规则。 在后一种情况下,使用iptables -A将无济于事,因为它将已经存在于链中的DROP / REJECT规则之后插入新的规则。 由于规则是按顺序评估的,第一个匹配规则与最终数据包命运目标(如ACCEPT,DROP或REJECT)最终决定数据包的命运,所以您的接受规则将永远不会被触发。

您的debugging选项:

  • 使用iptables -L FORWARD -v -n来查看你的ACCEPT规则是否被命中(即数据包/字节计数器正在递增) – 如果没有,数据不会像你想象的那样被路由
  • 在丢弃/拒绝数据包之前添加一个iptables -A FORWARD -j LOG规则,这样任何将被拒绝的数据包都将被logging在源/目的地,input/输出接口,协议和标记信息中
  • 运行tcpdump -v -n -i eth0 host <yourtestinghost>同时在可通过eth0访问的networking上引发stream量(如运行ping)到<yourtestinghost> – 查看数据包是否发送以及源地址是否按照定义重写在你的NAT / POSTROUTING规则
  • 请使用ip route查看路由表,查看是否via <yourISProuter> dev eth0存在到达所需目标networking的有效路由,并且是否通过另一个路由器/接口通过更具体的路由替代