使用 IPVS 进行双向 NAT 转发?

使用 IPVS 进行双向 NAT 转发?

我想用 IPVS 替换 iptables(8),以实现涉及双向 NAT 的 TCP 反向代理。

我当前使用的 iptables 设置在功能上相当于用户空间转发器(如 socat(1))。它具有以下设置:

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8000 -j DNAT --to-destination 172.31.1.1:80
# iptables -P FORWARD ACCEPT
iptables -t nat -A POSTROUTING -o eth1 -d 172.31.1.1 -p tcp --dport 80 -j MASQUERADE

该机器上有 10.0.0.2eth0和 172.31.0.2 eth1。它还有以下路由:

default via 10.0.0.1 dev eth0
172.31.0.0/24 dev eth1
172.31.1.0/24 via 172.31.0.1 dev eth1

我说这在功能上等同于用户空间代理,因为所有到达 TCP 地址 10.0.0.2:8000 的流量都会转发到内联网主机 172.31.1.1,而在目标主机上,流量似乎来自 172.31.0.2,而不是真实主机。双方都看不到对方的实际地址,只能看到这个反向代理服务器。

我正在尝试通过用 Linux 虚拟服务器替换此基于 iptables 的设置来学习 IPVS。我从这个开始:

ipvsadm -A -t 10.0.0.2:8000
ipvsadm -a -t 10.0.0.2:8000 -r 172.31.1.1:80 -m

关键点在于,源主机和目标主机经常无法通过与其中一个接口相同的链路到达。流量可能需要发送到两端的网关。

我不明白为什么curl http://10.0.0.2:8000/在此主机上会给出预期的结果,而在网络外部的主机上运行时相同的命令甚至没有建立 TCP 连接(10.0.0.2 / eth0 是面向公众的)。

使用tcpdump,我可以看到一个到后端的 SYN 数据包,一个 SYNACK 数据包返回,但之后没有 ACK(TCP 三次握手的第 3 步)。

我知道 VPN 或隧道可以解决这个问题,但我想在不使用它们的情况下做到这一点。

如果相关的话,这个反向代理正在运行 CentOS 7.7,并且 SELinux 和 Firewalld 均已禁用。

相关内容