這裡介紹如何在 CentOS Linux 7 中使用 firewalld 的指令設定防火牆規則。

在舊版的 CentOS Linux 中,防火牆都是以傳統的 iptables 來設定,而從 CentOS 7 開始,則改用 firewalld 來管理防火牆。


傳統的 iptables 在每次修改防火牆時都要清除舊規則,重新套用一次新規則,使用上不是很方便,而新的 firewalld 以區域(zone)的方式管理規則,並使用動態的方式執行,修改規則後可立即生效,也不需要重新啟動系統的服務(service 或 daemon),所以後來的 RHEL、CentOS 與 Fedora 都改用 firewalld 了。

iptables 與 firewalld 兩個防火牆管理系統只能選用其中一種,不可以同時開啟,否則會有問題。

以下是我在 CentOS Linux 7 的測試環境中所整理出來的 firewalld 使用教學。

安裝 firewalld

安裝 firewalld 之前,請先確認 iptables 是否有被啟用,若系統上原本就有運行 iptables 的防火牆,一定要先將其關閉後,才能啟用 firewalld,否則會有問題:

# 檢查 iptables 服務是否正在運行
systemctl status iptables

# 停止正在執行的 iptables 服務
systemctl stop iptables

# 將 iptables 服務永久關閉
systemctl mask iptables

firewalld 在 RHEL/CentOS 7 與 Fedora 21 之中應該是預設就會安裝好的,若您的系統上沒有安裝,可用 yum 安裝:

sudo yum install firewalld

當 firewalld 安裝好之後,檢查 firewalld 服務是否有啟動:

# 檢查 firewalld 服務狀態
systemctl status firewalld

若 firewalld 沒有啟動,則手動啟動它:

# 啟動 firewalld 服務
systemctl start firewalld

# 停止 firewalld 服務
systemctl stop firewalld

# 重新啟動 firewalld 服務
service firewalld restart

若要設定讓 firewalld 在開機時自動啟動,可執行:

# 設定開機自動啟動 firewalld 服務
systemctl enable firewalld

區域簡介

firewalld 的區域(zone)可用來設定網路連線、介面等所處的運作環境,對內使用的區域其防火牆規則會較為寬鬆,反之若是對外的區域其規則會較為嚴謹。

一條網路連線或介面只能隸屬於一個區域,我們可以自訂區域的設定,也可以直接從 firewalld 預設的幾個區域中選擇:

區域描述
drop任何往內的封包都會被丟棄,只允許往外傳送的封包。
block任何來自於外部的連線都會被阻擋,只允許自己系統主動建立的連線。
 public 公開區域,預設不信任其他電腦與網路,只有被允許的連線才能進入。通常大部分的連線設定都會放在這裡。
 external 公開區域,適用於 NAT 網路環境。
 dmz 非軍事區域(demilitarized zone,有點像是放在外頭的危險區域),允許外部的連線進入,但其對內的連線則有限制,只有被允許的連線才能連進內部網路。
work公司內部等工作區域,在此區域中不應該會有惡意的攻擊者。只有被允許的連線可以進入。
home家裡頭的網路區域,在此區域中不應該會有惡意的攻擊者。只有被允許的連線可以進入。
internal內部網路區域,在此區域中不應該會有惡意的攻擊者。只有被允許的連線可以進入。
trusted完全信任的區域,接受所有連線。

查詢區域設定

firewalld 都是透過 firewall-cmd 指令來操作的,若要列出 firewalld 中已經定義好的區域,可執行:

# 列出所有的區域
firewall-cmd --get-zones
block dmz drop external home internal public trusted work

列出所有的區域與其詳細的設定內容:

# 列出所有的區域與內容
sudo firewall-cmd --list-all-zones
block
  target: %%REJECT%%
  icmp-block-inversion: no
  interfaces:
  sources:
  services:
  ports:
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:
[略]

若要查詢特定區域的內部設定,可執行:

# 列出指定的區域與內容
sudo firewall-cmd --zone=public --list-all
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: enp7s0d1 ib0
  sources:
  services: ssh dhcpv6-client rpc-bind https http tftp dhcp
  ports: 944/tcp 944/udp 945/tcp 945/udp 946/udp 8649/udp 8649/tcp 8651/tcp 8652/tcp 15001/tcp 15002/tcp 15003/tcp 15004/tcp 15007/tcp 17001/tcp 8080/tcp
  protocols:
  masquerade: no
  forward-ports:
  source-ports:
  icmp-blocks:
  rich rules:

上面這個查詢方式所得到的結果是目前系統上執行的設定(runtime),若要查詢寫在硬碟中的永久設定,可以使用:

# 查詢永久設定值
sudo firewall-cmd --zone=public --list-all --permanent

預設區域

當網路介面或是連線沒有指定區域時,就會直接納入預設區域中。若要查詢目前預設的區域,可執行:

# 列出預設區域
firewall-cmd --get-default-zone
public

若要更改 firewalld 預設的區域,可以執行:

# 設定預設區域
firewall-cmd --set-default-zone=home

更改後,可再確認一次預設區域:

# 列出預設區域
firewall-cmd --get-default-zone
home

介面所屬區域

列出目前所有運作中的區域,以及各個網路介面所屬的區域:

# 查詢運作中的區域
firewall-cmd --get-active-zones
public
  interfaces: enp7s0d1 ib0
trusted
  interfaces: eno2

若要查詢指定網路介面所屬區域,可執行:

# 查詢網路介面所屬區域
firewall-cmd --get-zone-of-interface=enp7s0d1
public

若要更改指定網路介面的所屬區域,可以使用:

# 將 enp7s0d1 網路介面設定至 home 區域
sudo firewall-cmd --zone=home --change-interface=enp7s0d1

上面這種修改網路介面所屬區域的方式只是暫時的,若要讓系統重新開機後還可以維持這樣的設定,就要直接更改 /etc/sysconfig/network-scripts/ 底下的設定檔,以 enp7s0d1 這個網路介面來說,就修改 ifcfg-enp7s0d1 這個檔案中的ZONE 設定值:

ZONE=home

接下來要介紹如何在防火牆的區域中開啟特定的連接埠,讓對外的服務可以正常運作,請繼續閱讀下一頁。