![具有非对称路由的 Linux IPTables 目标 NAT?](https://linux22.com/image/519973/%E5%85%B7%E6%9C%89%E9%9D%9E%E5%AF%B9%E7%A7%B0%E8%B7%AF%E7%94%B1%E7%9A%84%20Linux%20IPTables%20%E7%9B%AE%E6%A0%87%20NAT%EF%BC%9F.png)
当流量离开的接口与到达的接口不同时,处理 DNAT 的正确方法是什么?发生这种情况时,回复似乎不会自动替换源地址,就像它从到达的同一接口发出时一样。
编辑--SNAT对我来说不起作用:
Chain PREROUTING (policy ACCEPT 386 packets, 23372 bytes)
pkts bytes target prot opt in out source destination
0 0 DNAT all -- * * 0.0.0.0/0 12.12.12.5 to:10.7.0.5
Chain POSTROUTING (policy ACCEPT 288 packets, 18672 bytes)
pkts bytes target prot opt in out source destination
0 0 SNAT all -- * eth0 10.7.0.5 0.0.0.0/0 to:12.12.12.5
0 0 SNAT all -- * eth3 10.7.0.5 0.0.0.0/0 to:12.12.12.5
8 550 MASQUERADE all -- * eth0 172.16.14.0/30 0.0.0.0/0
0 0 MASQUERADE all -- * eth0 10.7.0.0/24 0.0.0.0/0
Chain OUTPUT (policy ACCEPT 23 packets, 1572 bytes)
pkts bytes target prot opt in out source destination
因此,上文中两个路由器具有相同的表和相同的接口布局。两个路由器上的 eth0 都是 Internet 连接,每个路由器上的 eth1 连接到同一个 LAN(10.7.0/24)。eth3 将两个路由器相互连接。
实际情况是,我正在从互联网上的某个位置 ping 地址 12.12.12.5。回复通过 eth0 进入路由器 B,通过 eth1 发出,目标 nat 工作正常。回复进入路由器 A 上的 eth1,通过路由器 A 上的 eth0 退出互联网。但是,源地址没有被覆盖,回复返回到发送带有 10.7.0.5 地址的 ping 的设备*。
*是的,它们实际上通过私有源 IP 跨越了 20 个跳数,并且没有在任何地方被压缩——这有点令人惊奇)。
进一步编辑:
好吧,显然 SNAT(至少从 iptables 手册来看)只有在有状态时才匹配。所以我需要无状态 nat。这可以用 iproute2 来实现,但根据http://linux-ip.net/html/nat-dnat.html#ex-nat-dnat-full也可以通过在 iptables 中使用 --to-destination 和 SNAT 来模拟。但是我的 ubuntu 10.04 只显示未知选项--to-destination
...
答案1
据我所知,只要出站响应数据包由路由/DNAT 传入请求的同一路由器路由,就会发生您描述的地址重写行为。但是,如果高可用性路由器池中的任何其他 N+1 路由器正在处理出站响应数据包,它们将不会在 Netfilter 状态数据库中“看到”该连接。
听起来你想要一个共享 NAT 状态机信息的高可用性 Netfilter 路由器。该论文中提到的 ct_sync 工具已基本被废弃,但连接跟踪conntrack-tools 工具已经开发出来可以执行与 ct_sync 相同的一些操作。
如果您打算进行有状态数据包过滤(或 NAT,它实际上只是有状态数据包过滤的超集),那么您将需要一种方法来分发状态数据库(或者,在网络中采用无状态过滤并在每台主机上进行有状态过滤)。
答案2
对于 Web 流量来说,这种情况变得越来越常见。您是否担心某种特定情况?我没有 SNAT 反映我的所有 DNAT。
我关心的场景..
- 我将办公/开发流量的 SNAT 分开。
- 我确保 DNAT 和 SNAT 与 MX 以及所有传出的 MTA 匹配。
据我所知,经验法则是在合理可能的情况下避免这种情况。但随着现代实现和动态路由的发展,我相信这种观点已经过时了。