这是工作中开发环境的简化描述,我正在尝试对其进行配置以方便开发人员使用它。

拓扑:

我的设置的拓扑结构如下所示。描述:

  1. 我的裸机服务器 bm1 上运行着 2 个虚拟机(vm1 和 vm2)。
  2. 我有一个在 vm1 上运行的 Web 服务器(监听端口 8080)。
  3. 我有一个面向公众的路由器,即具有 DNS 名称的公共 IP,例如 (IP:10.1.2.3)
  4. 面向公众的路由器已配置为将任何来自端口 9080 的流量转发到裸机服务器 bm1(192.168.2.51)

要求:

我需要能够使用裸机服务器(bm1)和虚拟机(vm1、vm2)上的 DNS 名称通过端口 9080 访问 Web 服务器(vm1-ws1),即应该curl http://www.mysite.com:9080可以从裸机服务器和虚拟机上运行。

尝试的解决方案:

  1. 我验证了使用私有 IP 地址可以从裸机和虚拟机访问 Web 服务器,即可以curl http://192.168.121.29:8080从裸机服务器和虚拟机运行。
  2. 我将IP表规则配置为:
iptables -t nat -I PREROUTING -p tcp --dport 9080 -j DNAT --to 192.168.121.29:8080 
iptables -I FORWARD -d  192.168.121.29 -o virbr1 -j ACCEPT
  1. 添加 IP 表规则后,我可以从虚拟机访问 Web 服务器,但无法从裸机服务器访问。换句话说,可以curl http://www.mysite.com:9080从虚拟机访问,但无法从裸机访问。它会挂起然后超时。

请帮助我了解 iptables 规则配置中可能出现的问题。

1

  • 您使用的是什么 VM 软件?VM 采用什么网络模式?为什么选择这种方式?


    – 


最佳答案
1

来自主机本身的流量受OUTPUT链的管辖,因此您还需要以下规则:

iptables -t nat -I OUTPUT -p tcp --dport 9080 -j DNAT --to-destination 192.168.121.29:8080

-d(根据记录,由于规则中没有匹配项DNAT,因此任何目标端口为的 TCP 流量9080都将被重定向到192.168.121.29:8080,即,无论目标 IP 地址如何。)

您可能还需要以下规则,具体取决于您是否已经有一条MASQUERADE适用于所有通过 传出的流量的规则virbr1(更准确地说,只要它涵盖您路由中首选源 IP 的流量10.1.2.3,即最有可能的default路由):

iptables -t nat -I POSTROUTING -p tcp --dport 8080 -d 192.168.121.29 -j MASQUERADE

理论上,MASQUERADE当主机是虚拟机的默认网关时,不需要规则,也就是说,通常使用的源 IP 是否是流量通过的接口上配置的 IP 并不重要。但是,由于DNAT确实OUTPUT是一个“黑客”行为,也就是说,与 中的情况不同PREROUTING,它是在路由决策之后而不是之前完成的。因此,显然在现实中,您需要确保流量的源 IP 也经过 NAT。

也许还值得一提的是,如果您在 处进行过滤OUTPUT-o virbr0即使流量通过“黑客”DNAT 之后的接口传出,匹配对流量也是无关紧要的。这可能是因为过滤是在它之前执行的,或者,流量“状态”中的出口接口尚未“重写”,因为“重新路由”可能是在过滤之后完成的。(我对“内部”了解不多。)

因此,您要么需要有一个接受规则,例如-p tcp --dport 8080 -d 192.168.121.29,或者一个针对通过“原始”接口(例如-o eno1)传出的(所有)流量的规则。