没有默认路由的 DNAT

没有默认路由的 DNAT

我在数据中心有一个 TCP 服务,该服务根据源 IP 地址进行过滤和速率限制。我想将其移动到另一个数据中心。

我想在新数据中心的 IP 地址上提供相同的服务,并将单个端口上的所有流量转发到旧数据中心,这样新旧数据中心都可以同时工作。我不能只更改主机名,因为有些客户端使用 IP 地址进行连接(叹气),有些客户端使用基于 IP 地址的传出连接 IP 过滤(叹气),更改它们需要数周时间。

我知道我可以对连接进行 SNAT,但是如果我这样做,所有连接都将来自同一个 IP,这与基于源 IP 地址的过滤和速率限制相冲突。

我可以对连接进行 DNAT 并通过 VPN 隧道对其进行路由,但这意味着返回数据包将尝试使用服务的默认路由和服务源 IP 地址,并将被客户端忽略。

Linux 中是否有某种方式可以标记经过 DNAT 的 TCP 数据包,以便返回数据包可以通过 VPN 隧道而不是服务的默认路由返回?

答案1

有多种方法可以实现您想要的功能。绘制您的网络拓扑。

在此处输入图片描述

最简单的方法

它只需要在 S2(新 DC 中的服务器)上设置单个 DNAT 规则,并在 S1(旧 DC 中的服务器)上进行附加路由配置。但它也要求您的应用接受 VPN 隧道地址上的请求。

服务器S2iptables配置:

iptables -t nat -A PREROUTING \
         -i eth0 --dst <S2.IP> \
         -p tcp --dport <APP.PORT> \
    -j DNAT --to-address <S1.TUN.IP>:<APP.PORT>

另外,您应该在服务器上启用转发S2(使用sysctl -w net.ipv4.ip_forward=1命令启用它)。

验证:使用ip route get <S1.TUN.IP> from 8.8.8.8 iif <S2.IFACE>andip route get 8.8.8.8 from <S1.TUN.IP> iif <S2.TUN.IFACE>命令。它应该返回有效的路线。

服务器S1路由配置:

ip route add 0/0 dev <TUN.IFACE> table 1
ip rule add from <S1.TUN.IP> lookup 1 pref 1000

LINUX 根据收到的请求,回复来自同一 ip 地址的请求。

验证:使用ip route get <S1.TUN.IP> from 8.8.8.8 iif <S1.TUN.IFACE>ip route get 8.8.8.8 from <S1.TUN.IP>命令。它还应返回有效路由。也许您会看到类似这样的内容。在这种情况下,您应该在 VPN 隧道接口上invalid cross-device link调整。rp_filter

详细解释:

  1. 客户端以 的形式发送请求<C.IP>:<SOME.PORT> -> <S2.IP>:<APP.PORT>
  2. S2服务器收到此请求后,将目标重写为<S1.TUN.IP>。它发生在路由之前,因此在此步骤之后,数据包将形成<C.IP>:<SOME.PORT> -> <S1.TUN.IP>:<APP.PORT>
  3. S2根据路由表,通过VPN隧道转发重写的请求。
  4. S1通过VPN隧道接收请求到<S1.TUN.IP>地址。
  5. 您的应用程序S1处理请求并使用源地址回复客户端<S1.TUN.IP>。回复是<S1.TUN.IP>:<APP.PORT> -> <C1.IP>:<SOME.PORT>
  6. 通过路由规则,所有带有源地址的数据包都<S1.TUN.IP>通过路由表进行路由1。因此,来自您的应用程序的回复数据包将通过 VPN 隧道发送到S2服务器。
  7. S2收到回复后,对源地址进行逆向转换,将 改写为 ,<S1.TUN.IP>之后<S2.IP>回复就变成了<S2.IP>:<APP.PORT> -> <C.IP>:<SOME.PORT>
  8. 重写的答复将被转发回客户端的<C.IP>目标地址。
  9. 客户端按预期收到答复。

要进行故障排除,您可以使用tcpdump

还有其他方法,但更复杂。如果你需要的话,我会描述一下。

答案2

尽管 OP 的问题并不完全相同,但这个问题已在另一篇文章中得到回答。

如何在 nat 预路由表中转发数据包时设置标记?

第一个代码块展示了如何标记在 PREROUTING 中被 DNAT 的数据包。

希望这会有所帮助,加油!

相关内容