我在数据中心有一个 TCP 服务,它基于源 IP 地址进行过滤和速率限制。我想把它移到另一个数据中心。
我想在新数据中心的 IP 地址上提供相同的服务,并将单个端口上的所有流量转发到旧端口,这样新数据中心和旧数据中心都可以同时工作。我不能只更改主机名,因为一些客户端使用 IP 地址进行连接(叹气),而另一些客户端使用基于 IP 地址的 IP 过滤(叹气),并且需要数周时间才能更改它们。
我知道我可以对连接进行 SNAT,但如果我这样做,所有连接都将来自同一个 IP,这与基于源 IP 地址的过滤和速率限制相冲突。
我可以 DNAT 连接并通过 VPN 隧道路由它们,但这意味着返回的数据包将尝试使用服务的默认路由和服务源 IP 地址,并且将被客户端忽略。
Linux有没有办法以某种方式标记经过DNAT处理的TCP数据包,以便可以通过VPN隧道而不是服务的默认路由将返回的数据包路由回?
有多种方法可以实现您想要的。绘制您的网络拓扑。
最简单的方法
它只需要 S2(新 DC 中的服务器)上的单个 DNAT 规则和 S1(旧 DC 中的服务器)上的附加路由配置。但这也需要您的应用程序也接受 VPN 隧道地址上的请求。
S2
服务器iptables配置:此外,您应该在
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
服务器路由配置:LINUX 会回复来自相同 IP 地址的请求,以及收到的请求。
验证:使用
ip route get <S1.TUN.IP> from 8.8.8.8 iif <S1.TUN.IFACE>
andip route get 8.8.8.8 from <S1.TUN.IP>
命令。它还应该返回有效的路线。也许你会看到类似的东西invalid cross-device link
。在这种情况下,您应该rp_filter
在 vpn 隧道接口上调整。详细解释:
<C.IP>:<SOME.PORT> -> <S2.IP>:<APP.PORT>
.S2
服务器收到此请求,将目标重写为<S1.TUN.IP>
. 它发生在路由之前,因此在此步骤之后数据包将形成<C.IP>:<SOME.PORT> -> <S1.TUN.IP>:<APP.PORT>
.S2
由于路由表,通过VPN隧道转发重写的请求。S1
通过 VPN 隧道接收请求到<S1.TUN.IP>
地址。S1
为请求提供服务并使用源地址回复客户端<S1.TUN.IP>
。回复是<S1.TUN.IP>:<APP.PORT> -> <C1.IP>:<SOME.PORT>
。<S1.TUN.IP>
通过路由表进行路由1
。因此,来自您的应用程序的回复数据包将通过 VPN 隧道发送到S2
服务器。S2
接收回复,对源地址进行反向翻译,将其<S1.TUN.IP>
从<S2.IP>
. 这个回复之后变成了<S2.IP>:<APP.PORT> -> <C.IP>:<SOME.PORT>
。<C.IP>
目标地址。要排除故障,您可以使用
tcpdump
.还有一种方法,那就更复杂了。如果你需要,我会描述它。
这在另一篇文章中得到了回答,尽管 OP 的问题并不完全相同。
在 nat 预路由表中转发数据包时如何在数据包上设置标记?
第一个代码块显示了如何标记在 PREROUTING 中被 DNAT 处理的数据包。
希望这会有所帮助,干杯!