无法使用 iptables NAT 从 WAN 访问 LAN 虚拟 IP

无法使用 iptables NAT 从 WAN 访问 LAN 虚拟 IP

设置如下:

  • 2 台运行 CentOS 5.6 的服务器(主机名 =“master1”和“master2”)
  • “master1” LAN IP 为 10.224.45.130,WAN IP 为 184.107.x.1
  • “master2” LAN IP 为 10.224.45.131,WAN IP 为 184.107.x.2
  • 两者上都安装了 Apache + Heartbeat,其中“master1”是 haresources 中 httpd 服务的主要服务。
  • Apache 绑定到虚拟 IP 10.224.45.135(通过心跳启动)
  • 两台服务器上的 iptables NAT PREROUTING 从端口 80 -> 10.224.45.135:80。

(注意:我已登录 VPN,因此可以访问 LAN)

我的 heartbeat 运行正常。它将在“master1”上正确创建虚拟 IP 地址并启动 apache。当我在“master1”上停止 heartbeat 以模拟服务器故障时,heartbeat 会正确通知“master2”,后者接管虚拟 IP 并启动 apache。一切运行正常。

我可以指向任一服务器的 LAN IP,无论哪个服务器当前正在运行 apache,它都会加载该站点(因为两者都有一个指向虚拟 IP 地址的 iptables NAT PREROUTING 端口 80)。当我将浏览器指向虚拟 IP 地址本身时,我也可以加载该站点。

但是,如果我调用任一服务器的公共 WAN IP,则只有调用当前正在运行 apache 的服务器的 IP 时,网站才会加载。例如,如果 master1 当前正在运行 apache,我可以通过调用 master1 的任意三个 LAN IP 地址或 WAN IP 来加载网站。但是,如果我调用 master2 的 WAN IP,则网站将无法加载。但是,如果我停止 master1 上的心跳,以便 apache 在 master2 上启动,则我可以通过调用 master2 的 WAN IP(而不是 master1)来加载网站。

我不确定为什么当我通过运行 apache 的服务器的 LAN IP 和 WAN IP 访问站点时,iptables 会正确地将数据包路由到虚拟 IP,但不会通过另一台服务器的 WAN IP 访问,即使它们都将端口 80 指向虚拟 IP。我还注意到我只能从当前运行 apache 的服务器(因此是当前配置了 VIP 的服务器)ping 虚拟 IP(10.224.45.135)。我假设我可以从任一服务器 ping VIP。但我不确定这是否与 WAN IP 无法正确路由到 VIP 的原因有关。

这是我的 iptables 设置:

*filter
:FORWARD DROP [0:0]
:INPUT DROP [0:0]
:OUTPUT ACCEPT [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -i tun0 -j ACCEPT
-A INPUT -i tap0 -j ACCEPT
-A INPUT -i br0 -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m tcp --dport 20 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 21 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 25 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 80 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 106 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 110 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 143 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 389 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 443 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 465 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 587 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 636 -j ACCEPT
-A INPUT -p udp -m udp --dport 694 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 843 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 873 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 953 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 993 -j ACCEPT
-A INPUT -p udp -m udp --dport 993 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 995 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 1194 -j ACCEPT
-A INPUT -p udp -m udp --dport 1194 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3000 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 3306 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 5901 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 7025 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 10000 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 11211 -j ACCEPT
-A INPUT -p tcp -m tcp --dport 11511 -j ACCEPT
-A FORWARD -i br0 -j ACCEPT
-A FORWARD -o br0 -j ACCEPT
-A FORWARD -p tcp -m tcp --dport 80 -j ACCEPT
COMMIT
*mangle
:PREROUTING ACCEPT [30383:12077327]
:INPUT ACCEPT [30381:12077231]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [26362:10490359]
:POSTROUTING ACCEPT [26362:10490359]
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 80 -j DNAT --to 10.224.45.135:80
-A PREROUTING -p tcp --dport 443 -j DNAT  --to 10.224.45.135:443
-A POSTROUTING -s 10.8.0.0/255.255.255.0 -o venet0 -j MASQUERADE
COMMIT

答案1

我找到答案了!

我需要向设置为 Masquerade 的 NAT 表添加一条 POSTROUTING 规则,以用于 DPT 为 80 或 443 的数据包。

在这里找到答案:http://www.debian-administration.org/articles/73#comment_22

除了本文中的规则外,您还需要一条 POSTROUTING 规则,以便在重定向到另一台计算机时启用伪装。例如:

iptables -t nat -A POSTROUTING -j MASQUERADE -o eth0

否则,响应不会返回到原始机器,并且连接似乎被过滤了。至少这是我在尝试转发时发现的。我知道这已经晚了几年,无法提供帮助,但它可能会帮助其他人。

相关内容