如何将 iptables SNAT 应用于发往 localhost(INPUT 链)的数据包?

如何将 iptables SNAT 应用于发往 localhost(INPUT 链)的数据包?

我正在设置一台主机,该主机有两条通往公共互联网的路由:一条通过我的普通家庭网关路由器,另一条通过半专用网络上的网关路由器(AMPRNet 位于 44.0.0.0/8 )。其中大部分都很简单,但有一个棘手的地方:

大多数情况下,44.xx1 IP 用于与 44.0.0.0/8 上的其他主机进行通信。这样可以轻松地将传出数据包路由到为此目的配置的隧道接口 (tunl0)。

公共网络上的主机可以通过 UCSD (169.228.66.251) 的网关路由器到达我的半私有 IP (44.xx1),该路由器在 BGP 上宣布 44.0.0.0/8。然而,来自我的节点的对此类数据包的回复最终会从 eth0 返回到原始主机,这不起作用,因为它们在我的网关路由器的途中进行了 NAT。

我认为我需要做的是使用 iptables 将 tunl0 上的传入数据包从非 44.0.0.0/8 主机 SNAT 到 44.0.0.0/8 空间中的虚拟 IP,并使用状态连接跟踪在返回时对它们进行 DNAT 。然而,这似乎不起作用。

运行后

iptables -t nat -A INPUT -s 44.0.0.0/32 -d 44.x.x.1 -j ACCEPT
iptables -t nat -A INPUT -s 0.0.0.0 -d 44.x.x.1 -j SNAT --to 44.0.0.2

当我从远程主机 ping 44.xx1 时,tunl0 接口上的 tcpdump 显示来自实际外部 IP 的数据包,不是从 44.0.0.2 开始。如果我 tcpdump eth0,我会看到回复数据包返回到该外部 IP。

这个配置可以吗?如果是这样,我错过了什么?

如何使用 iptables 而不是路由将来自特定端口上第二个路由器的数据包发送回路由器似乎是相关的。

编辑:添加更多网络详细信息

pi@raspberrypi ~ $ ifconfig
eth0      Link encap:Ethernet  HWaddr b8:27:eb:3b:93:ba  
          inet addr:192.168.3.192  Bcast:192.168.3.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14477 errors:0 dropped:0 overruns:0 frame:0
          TX packets:6131 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:4475095 (4.2 MiB)  TX bytes:1651639 (1.5 MiB)

lo        Link encap:Local Loopback  
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

tunl0     Link encap:IPIP Tunnel  HWaddr   
          inet addr:44.x.x.1  Mask:255.255.255.255
          UP RUNNING NOARP MULTICAST  MTU:1480  Metric:1
          RX packets:424 errors:0 dropped:0 overruns:0 frame:0
          TX packets:17 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:176191 (172.0 KiB)  TX bytes:836 (836.0 B)

pi@raspberrypi ~ $ sudo ip route
default via 192.168.3.1 dev eth0 
192.168.3.0/24 dev eth0  proto kernel  scope link  src 192.168.3.192 

pi@raspberrypi ~ $ sudo ip rule
0:  from all lookup local 
44: from all to 44.0.0.0/8 lookup 44 
45: from 44.x.x.0/28 lookup 44 
32766:  from all lookup main 
32767:  from all lookup default 

pi@raspberrypi ~ $ sudo ip route show table 44 | head
44.0.0.1 via 169.228.66.251 dev tunl0 onlink  window 840
44.2.2.0/24 via 157.130.198.190 dev tunl0 onlink  window 840
44.2.10.0/29 via 71.130.72.52 dev tunl0 onlink  window 840
44.2.14.0/29 via 50.79.156.221 dev tunl0 onlink  window 840
44.2.50.0/29 via 68.189.35.197 dev tunl0 onlink  window 840
44.4.2.152/29 via 173.167.109.217 dev tunl0 onlink  window 840
44.4.10.40 via 69.12.138.16 dev tunl0 onlink  window 840
44.4.22.198 via 67.161.9.80 dev tunl0 onlink  window 840
44.4.22.200 via 50.136.207.176 dev tunl0 onlink  window 840
44.4.28.50 via 50.79.209.150 dev tunl0 onlink  window 840
...

答案1

好吧,看起来答案很简单:

ip route add default dev tunl0 via 169.228.66.251 onlink table 44

数据包进入特定接口,因此回复将在同一接口上返回。 tunl0 通过表 44 进行路由,因此使用表 44 中的默认路由,我们就可以开始了。

相关内容