Virtual-Machines

使用 firewall-cmd 進行埠轉發

  • November 1, 2018

我有幾個在伺服器(虛擬機管理器,VMM)上執行的虛擬機。我想將伺服器上的埠 80 轉發到我的一台虛擬機的埠 80。主機執行 CentOS7,所以由 firewalld 負責。顯然,VMM 也使用 firewalld 來處理虛擬連接,所以我不能把它扔出窗外。

我基本上沒有成功地複制了這個執行緒中的所有命令,歸結為:

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

我的埠轉發工作。我錯過了什麼?

將 firewalld 與 libvirt 混合使用會使您陷入這種情況。

預設情況下,使用“NAT”網路,libvirt 的網路將設置偽裝規則,以便 VM 可以訪問舊版 IPv4 網際網路。但是,libvirt 會阻止所有到“NAT”網路的傳入連接。

解決方案是將網路更改為普通路由網路,然後讓 firewalld 處理您可能需要的任何偽裝。

例如,您將編輯網路 XML 並更改

 <forward mode='nat'/>

 <forward mode='route'/>

我建議您將所有libvirt NAT 網路更改為路由,在這種情況下,如果您想允許網路相互通信,而不僅僅是您要將埠轉發到的那個。

然後在與連接到 Internet 其餘部分的介面對應的 firewalld 區域上設置偽裝。例如:

~~``` 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’

引用自:https://serverfault.com/questions/933453