我在一台服务器(虚拟机管理器,VMM)上运行着几台虚拟机。我想将服务器上的端口 80 转发到我的其中一台虚拟机的端口 80。主机运行 CentOS7,因此由防火墙负责。显然,防火墙也被 VMM 用于处理虚拟连接,所以我不能直接把它扔到窗外。
我基本上复制了所有命令这线程没有成功,归结为:
firewall-cmd --permanent --zone=public --add-forward-port=port=80:proto=tcp:toport=80:toaddr=192.168.122.224
或者
firewall-cmd --permanent --zone=public --add-rich-rule 'rule family=ipv4 forward-port port=80 protocol=tcp to-port=80 to-addr=192.168.122.224'
Firewalld 的当前状态如下:
[root@my-machine ~]# firewall-cmd --list-all
public (active)
target: default
icmp-block-inversion: no
interfaces: enp8s0
sources:
services: ssh dhcpv6-client samba smtp http
ports: 25/tcp
protocols:
masquerade: yes
forward-ports:
source-ports:
icmp-blocks:
rich rules:
rule family="ipv4" forward-port port="80" protocol="tcp" to-port="80" to-addr="192.168.xxx.xxx"
这是输出
iptables -L -n -v
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
13917 8976K ACCEPT all -- * virbr0 0.0.0.0/0 192.168.122.0/24 ctstate RELATED,ESTABLISHED
13539 2093K ACCEPT all -- virbr0 * 192.168.122.0/24 0.0.0.0/0
0 0 ACCEPT all -- virbr0 virbr0 0.0.0.0/0 0.0.0.0/0
4 240 REJECT all -- * virbr0 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable <-----
1 133 REJECT all -- virbr0 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 ACCEPT all -- virbr1 virbr1 0.0.0.0/0 0.0.0.0/0
0 0 REJECT all -- * virbr1 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 REJECT all -- virbr1 * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-port-unreachable
0 0 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_direct all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_IN_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_IN_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_OUT_ZONES_SOURCE all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 FORWARD_OUT_ZONES all -- * * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 ctstate INVALID
0 0 REJECT all -- * * 0.0.0.0/0 0.0.0.0/0 reject-with icmp-host-prohibited
问题是第二条规则,它似乎拒绝了我的包裹(我可以看到尝试连接时数量增加)。事实上,如果我用以下方法删除它:
iptables -D FORWARD -o virbr0 -j REJECT --reject-with icmp-port-unreachable
我的端口转发功能正常。我遗漏了什么?
答案1
混合使用firewalld和libvirt可能会让您陷入这种情况。
默认情况下,对于“NAT”网络,libvirt 的网络将设置伪装规则,以便虚拟机可以访问传统的 IPv4 互联网。但是,libvirt 会阻止所有传入“NAT”网络的连接。
解决方案是将网络更改为正常路由网络,然后让firewalld处理您可能需要的任何伪装。
例如,您可以编辑网络 XML 并更改
<forward mode='nat'/>
到
<forward mode='route'/>
我建议你改变全部在这种情况下,如果您想允许网络相互通信,libvirt NAT 网络将进行路由,而不仅仅是您想要转发端口的网络。
然后在与连接到 Internet 其余部分的接口对应的防火墙区域上设置伪装。例如:
firewall-cmd [--permanent] --zone=public --add-masquerade
(对于firewalld 0.4.4.6或更高版本,您不应该使用此功能,而是为IPv4伪装创建丰富的规则。这些版本有一个缺陷,导致在使用时也会添加IPv6伪装规则--add-masquerade
,这将破坏IPv6连接。)
firewall-cmd [--permanent] --zone=public --add-rich-rule='rule family=ipv4 masquerade'