我在虚拟化主机上有两个容器,它们具有“LAN”网桥(vmbr1)和“WAN”网桥(vmbr0)。
虚拟化主机在 vmbr0 网桥上配置了公共 IP(假设虚拟 123.123.123.123)。
在这个虚拟化主机中,我有两个容器:
- 网络容器(10.1.0.210/24)
- 数据库容器 (10.1.0.250/24)
Web容器使用mysql数据库。它被配置为连接 10.1.0.250:3306。
在 mysql 中,我有 Web 应用程序的用户,仅允许从 Web 主机(10.1.0.210)连接。
在我添加这些 NAT 规则(应该允许来自 WAN 的连接)之前,一切都工作正常。这是来自我的 /etc/network/interfaces vmbr1 (LAN) 配置:
# there is no need to add -m multiport here, these rules are from my "template"
# post-up iptables -t nat -A PREROUTING -i vmbr0 -p tcp -m multiport --dport 3306 -j DNAT --to-destination 10.5.0.250
# post-up iptables -t nat -A POSTROUTING -o vmbr1 -p tcp -m multiport --dport 3306 -d 10.5.0.250 -j SNAT --to-source 10.5.0.1
# pre-down iptables -t nat -D PREROUTING -i vmbr0 -p tcp -m multiport --dport 3306 -j DNAT --to-destination 10.5.0.250
# pre-down iptables -t nat -D POSTROUTING -o vmbr1 -p tcp -m multiport --dport 3306 -d 10.5.0.250 -j SNAT --to-source 10.5.0.1
问题是当我将这些规则添加到 iptables 时:
iptables -t nat -A PREROUTING -i vmbr0 -p tcp -m multiport --dport 3306 -j DNAT --to-destination 10.5.0.250
iptables -t nat -A POSTROUTING -o vmbr1 -p tcp -m multiport --dport 3306 -d 10.5.0.250 -j SNAT --to-source 10.5.0.1
我的 Web 应用程序停止工作,因为当 Web 应用程序尝试连接时 mysql 抛出登录错误。从mysql的角度来看,连接来自10.1.0.1地址(LAN侧的网关)而不是真正的10.1.0.210(mysql用户[电子邮件受保护]允许连接,但用户[电子邮件受保护]不允许)。
我猜这是因为 3306 端口的所有连接现在都通过 NAT,并且 NAT 将 10.1.0.210 转换为 10.1.0.1。
我怎样才能解决这个问题?
也许我应该“缩小”这些 nat 规则,使其仅在连接仅来自 WAN 时才起作用,但我对网络和 iptables 没有足够的了解,无法在生产服务器上搞砸它。
答案1
听起来问题是您添加的 NAT 规则导致来自 Web 容器的连接的源 IP 地址更改为 LAN 侧网关的 IP 地址 (10.1.0.1),而不是 Web 容器的 IP 地址。实际 IP 地址 (10.1.0.210)。这导致 MySQL 服务器拒绝连接,因为它们来自不允许连接的 IP 地址。
解决此问题的一种方法是在 DNAT 和 SNAT 规则之前添加一条额外的 iptables 规则,该规则检查传入连接的源 IP 地址,并且仅在连接来自 WAN 时才应用 DNAT 和 SNAT 规则。您可以使用“-s”选项指定源 IP 地址,使用“-j”选项指定规则的目标(在本例中为 DNAT 和 SNAT 规则)。
另一种解决方案是将 Web 容器配置为通过虚拟化主机的公共 IP 地址(而不是数据库容器的内部 IP 地址)连接到 MySQL 服务器。这样,NAT 规则就不会影响连接。
您还可以检查您的mysql是否可以选择将bind-address设置为0.0.0.0而不是10.1.0.250,这样它将监听所有接口并且不会受到NAT规则的影响。