UFW 提供簡潔的指令介面,方便管理 Linux 系統防火牆規則,底層根據 iptables 或 nftables。Firewalld 則以動態管理和區域概念簡化複雜網路環境的防火牆設定。兩種工具各有優勢,適用於不同場景。理解其設定檔結構、規則語法及操作指令,才能有效設定防火牆,保護系統安全。本文將逐步引導讀者瞭解 UFW 與 Firewalld 的設定細節,並提供實務操作範例。

UFW 防火牆規則與設定詳解

UFW(Uncomplicated Firewall)是 Ubuntu 系統上一款簡易的防火牆管理工具,它根據 iptables 或 nftables,為使用者提供了一種更簡單的方式來管理防火牆規則。在本篇文章中,我們將探討 UFW 的設定檔、規則管理,以及如何手動編輯設定檔來實作更複雜的防火牆組態。

UFW 設定檔結構

UFW 的設定檔主要存放在 /etc/ufw 目錄下。其中,user.rulesuser6.rules 分別儲存了 IPv4 和 IPv6 的規則。這些檔案包含了使用 ufw 命令建立的規則。

RULES 區段

user.rules 檔案中,我們可以看到如下的規則範例:


### tuple ### allow any 53 0.0.0.0/0 any 0.0.0.0/0 in
-A ufw-user-input -p tcp --dport 53 -j ACCEPT
-A ufw-user-input -p udp --dport 53 -j ACCEPT

這些規則允許任何來源的 TCP 和 UDP 連線到本機的 53 埠(DNS 埠)。

LOGGING 區段

LOGGING 區段定義瞭如何記錄被防火牆阻擋的封包:


### LOGGING ###
-A ufw-after-logging-input -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-A ufw-after-logging-forward -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-I ufw-logging-deny -m conntrack --ctstate INVALID -j RETURN -m limit --limit 3/min --limit-burst 10
-A ufw-logging-deny -j LOG --log-prefix "[UFW BLOCK] " -m limit --limit 3/min --limit-burst 10
-A ufw-logging-allow -j LOG --log-prefix "[UFW ALLOW] " -m limit --limit 3/min --limit-burst 10

### END LOGGING ###

這些規則將記錄被阻擋的封包到 /var/log/kern.log 檔案中,並限制記錄頻率以避免日誌系統過載。

RATE LIMITING 區段

RATE LIMITING 區段定義了連線速率限制規則:


### RATE LIMITING ###
-A ufw-user-limit -m limit --limit 3/minute -j LOG --log-prefix "[UFW LIMIT BLOCK] "
-A ufw-user-limit -j REJECT
-A ufw-user-limit-accept -j ACCEPT

### END RATE LIMITING ###

這些規則限制了每分鐘允許的連線數,並對超出限制的連線進行記錄和拒絕。

自訂 UFW 規則

除了使用 ufw 命令來管理規則外,我們還可以手動編輯設定檔來新增自訂規則。例如,要新增規則到 before.rulesbefore6.rules 檔案中,可以按照以下步驟進行:

  1. 編輯 /etc/ufw/before.rules/etc/ufw/before6.rules 檔案。
  2. 在檔案末尾的 COMMIT 行下方新增自訂規則,例如:
# Mangle table added by Donnie
*mangle
:PREROUTING ACCEPT [0:0]
-A PREROUTING -m conntrack --ctstate INVALID -j DROP
-A PREROUTING -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j DROP
COMMIT
  1. 過載 UFW 規則:sudo ufw reload

Hands-on Lab:基本 UFW 使用

  1. 在 Ubuntu 20.04 或 Ubuntu 22.04 虛擬機器上執行以下操作。
  2. 關閉虛擬機器並還原到初始快照。
  3. 啟動虛擬機器後,驗證 iptables 或 nftables 規則是否已清除。
  4. 檢視 UFW 狀態:sudo ufw status
  5. 開啟 22/TCP 埠並啟用 UFW:sudo ufw allow 22/tcpsudo ufw enable
  6. 檢視 UFW 狀態和 iptables 或 nftables 規則。

UFW 設定流程圖示

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

title UFW 與 Firewalld 防火牆設定詳解

package "安全架構" {
    package "網路安全" {
        component [防火牆] as firewall
        component [WAF] as waf
        component [DDoS 防護] as ddos
    }

    package "身份認證" {
        component [OAuth 2.0] as oauth
        component [JWT Token] as jwt
        component [MFA] as mfa
    }

    package "資料安全" {
        component [加密傳輸 TLS] as tls
        component [資料加密] as encrypt
        component [金鑰管理] as kms
    }

    package "監控審計" {
        component [日誌收集] as log
        component [威脅偵測] as threat
        component [合規審計] as audit
    }
}

firewall --> waf : 過濾流量
waf --> oauth : 驗證身份
oauth --> jwt : 簽發憑證
jwt --> tls : 加密傳輸
tls --> encrypt : 資料保護
log --> threat : 異常分析
threat --> audit : 報告生成

@enduml

圖表翻譯: 此圖示呈現了編輯 UFW 設定檔並過載規則的流程。首先,開始編輯 before.rules 檔案,接著新增自訂規則,然後過載 UFW 規則,最後驗證規則是否生效。

程式碼範例:新增自訂規則

# 在 before.rules 中新增自訂規則
sudo nano /etc/ufw/before.rules

#### 內容解密:

此範例展示瞭如何使用 nano 編輯器開啟 /etc/ufw/before.rules 檔案,以便新增自訂的防火牆規則。使用者需要具備適當的許可權(如 sudo)來編輯該檔案。

透過本篇文章,我們深入瞭解了 UFW 的設定檔結構、自訂規則的方法,以及如何手動編輯設定檔來實作更複雜的防火牆組態。UFW 提供了一種簡便的方式來管理防火牆規則,但對於更複雜的需求,手動編輯設定檔是必要的。希望本文能幫助讀者更好地理解和使用 UFW。

在 Ubuntu 系統中使用 ufw 管理防火牆

檢查防火牆規則

在 Ubuntu 22.04 上,可以使用以下命令檢查防火牆規則:

sudo nft list ruleset

開啟特定埠號

開啟 TCP 和 UDP 的 53 埠號:

sudo ufw allow 53
sudo ufw status

自訂 ufw 設定檔

  1. 切換到 /etc/ufw/ 目錄,熟悉目錄中的檔案內容。
  2. 編輯 /etc/ufw/before.rules 檔案,在 COMMIT 行下方新增以下程式碼片段:
# Mangle table added by Donnie
*mangle
:PREROUTING ACCEPT [0:0]
-A PREROUTING -m conntrack --ctstate INVALID -j DROP
-A PREROUTING -p tcp -m tcp ! --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j DROP
COMMIT

內容解密:

  • 這段程式碼在 mangle 表中增加了兩個規則。
  • 第一個規則會丟棄狀態無效(INVALID)的連線。
  • 第二個規則會丟棄 TCP 封包中 SYN 旗標未被設定,但連線狀態為 NEW 的封包。
  1. /etc/ufw/before6.rules 檔案重複步驟 2。

重新載入防火牆規則

重新載入防火牆規則:

sudo ufw reload

檢查防火牆規則

在 Ubuntu 20.04 上:

sudo iptables -L
sudo iptables -t mangle -L
sudo ip6tables -L
sudo ip6tables -t mangle -L

在 Ubuntu 22.04 上:

sudo nft list ruleset

檢視 ufw 狀態

sudo ufw status

使用 firewalld 管理 Red Hat 系統的防火牆

驗證 firewalld 狀態

使用 --state 選項驗證 firewalld 狀態:

sudo firewall-cmd --state

或者使用 systemctl 命令檢查 firewalld 狀態:

sudo systemctl status firewalld

使用 firewalld 區域

firewalld 提供多個預先組態的區域和服務。區域檔案存放在 /usr/lib/firewalld/zones/ 目錄中。

檢視區域檔案:

cd /usr/lib/firewalld/zones
ls

firewalld 的優勢

firewalld 的一大優勢是其動態管理能力,可以在不重新啟動防火牆服務的情況下更改防火牆組態,並且不會中斷現有的連線。

Firewalld 區域組態與服務管理詳解

Firewalld 是一種動態防火牆管理工具,用於組態和管理 Linux 系統的網路防火牆規則。它透過定義不同的區域(zone)來控制網路介面的存取許可權,並根據不同的場景需求進行調整。

區域檔案組態

每個區域檔案(zone file)定義了特定網路環境下的防火牆規則,包括允許或封鎖的連線埠、ICMP 訊息處理規則、轉發連線埠設定以及偽裝(masquerading)資訊等。這些檔案通常以 XML 格式儲存,例如 public.xmlhome.xml

Public 區域範例

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Public</short>
  <description>For use in public areas. You do not trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="dhcpv6-client"/>
</zone>

Home 區域範例

<?xml version="1.0" encoding="utf-8"?>
<zone>
  <short>Home</short>
  <description>For use in home areas. You mostly trust the other computers on networks to not harm your computer. Only selected incoming connections are accepted.</description>
  <service name="ssh"/>
  <service name="mdns"/>
  <service name="samba-client"/>
  <service name="dhcpv6-client"/>
</zone>

內容解密:

  1. 區域定義:每個區域檔案定義了一個特定的網路環境,如公共區域或家庭區域。
  2. 服務組態:透過 <service> 標籤指定允許的服務,例如 SSH、DHCPv6 使用者端、Samba 使用者端等。
  3. 安全性設定:根據不同的信任級別,開放必要的服務和連線埠。

使用 firewall-cmd 管理 Firewalld

firewall-cmd 是用於組態和管理 firewalld 的命令列工具。

檢視所有區域

sudo firewall-cmd --get-zones

列出所有區域的詳細組態

sudo firewall-cmd --list-all-zones

檢視特定區域的資訊

sudo firewall-cmd --info-zone=internal

設定預設區域

sudo firewall-cmd --set-default-zone=dmz

內容解密:

  1. --get-zones:列出系統上所有可用的區域。
  2. --list-all-zones:顯示所有區域的詳細組態資訊。
  3. --info-zone:查詢特定區域的詳細設定。
  4. --set-default-zone:設定系統的預設防火牆區域。

網路介面與區域的關聯

每個網路介面卡可以被指派到一個且僅一個 firewalld 區域。

檢視預設區域

sudo firewall-cmd --get-default-zone

檢視活動區域及其關聯的網路介面

sudo firewall-cmd --get-active-zones

內容解密:

  1. --get-default-zone:顯示目前系統的預設防火牆區域。
  2. --get-active-zones:顯示目前啟用的區域及其對應的網路介面。

修改 Firewalld 組態

當修改 firewalld 組態時,變更會儲存在 /etc/firewalld/ 目錄下,而非直接修改 /usr/lib/firewalld/ 中的檔案。

檢視已變更的組態檔案

sudo ls -l /etc/firewalld

比對組態檔案變更前後的差異

sudo diff /etc/firewalld/firewalld.conf /etc/firewalld/firewalld.conf.old

內容解密:

  1. 組態儲存路徑:變更後的組態儲存在 /etc/firewalld/ 目錄。
  2. 比對變更:透過 diff 命令檢視組態檔案的變更內容。

為 Firewalld 區域新增服務

每個服務檔案定義了特定服務所需的開放連線埠和其他相關設定。

檢視可用的服務列表

sudo firewall-cmd --get-services

檢視特定服務的詳細資訊

sudo firewall-cmd --info-service=dropbox-lansync

列出目前區域已啟用的服務

sudo firewall-cmd --list-services

內容解密:

  1. --get-services:列出所有可用的服務。
  2. --info-service:顯示特定服務的詳細資訊,包括開放的連線埠和協定。
  3. --list-services:顯示目前區域已啟用的服務列表。

透過上述指令和組態,可以靈活地管理 firewalld 的區域和服務設定,確保系統安全性的同時滿足不同的網路需求。

管理 firewalld 的服務與連線埠

在前面的章節中,我們已經瞭解瞭如何使用 firewalld 來管理防火牆規則。在本章節中,我們將探討如何使用 firewalld 來管理服務和連線埠。

新增服務到防火牆區域

首先,讓我們來看看如何新增服務到防火牆區域。假設我們已經將 Web 伺服器設定在 DMZ 區域,並且已經將 dmz 區域設為預設區域。

[donnie@localhost ~]$ sudo firewall-cmd --info-zone=dmz
dmz (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources: 
services: ssh
ports: 
protocols: 
masquerade: no
forward-ports: 
source-ports: 
icmp-blocks: 
rich rules:

從上面的輸出結果可以看出,目前只有 SSH 服務是開放的。若要讓使用者能夠存取我們的網站,我們需要開放 HTTP 服務。

[donnie@localhost ~]$ sudo firewall-cmd --add-service=http
success
[donnie@localhost ~]$

執行上述指令後,我們可以再次檢視 dmz 區域的資訊:

[donnie@localhost ~]$ sudo firewall-cmd --info-zone=dmz
dmz (active)
target: default
icmp-block-inversion: no
interfaces: enp0s3
sources: 
services: ssh http
ports: 
protocols: 
masquerade: no
forward-ports: 
source-ports: 
icmp-blocks: 
rich rules:

內容解密:

  1. sudo firewall-cmd --add-service=http:此指令用於將 HTTP 服務新增到目前的預設區域(dmz)。
  2. success:表示指令執行成功。
  3. sudo firewall-cmd --info-zone=dmz:此指令用於檢視 dmz 區域的詳細資訊,確認 HTTP 服務是否已成功新增。

然而,如果我們使用 --permanent 選項來檢視 dmz 區域的資訊,就會發現 HTTP 服務並未被新增:

[donnie@localhost ~]$ sudo firewall-cmd --permanent --info-zone=dmz
dmz
target: default
icmp-block-inversion: no
interfaces: 
sources: 
services: ssh
ports: 
protocols: 
masquerade: no
forward-ports: 
source-ports: 
icmp-blocks: 
rich rules:

內容解密:

  1. --permanent:此選項表示變更將會永久生效,但需要重新載入防火牆設定才能生效。
  2. sudo firewall-cmd --permanent --info-zone=dmz:此指令用於檢視永久設定的 dmz 區域資訊。

這是因為我們在新增 HTTP 服務時沒有使用 --permanent 選項,因此變更只在目前的執行階段生效,而不會永久儲存。

使變更永久生效

若要使變更永久生效,我們需要在新增服務時使用 --permanent 選項,並在完成後重新載入防火牆設定。

[donnie@localhost ~]$ sudo firewall-cmd --permanent --add-service={http,https}
success
[donnie@localhost ~]$ sudo firewall-cmd --reload
success

內容解密:

  1. sudo firewall-cmd --permanent --add-service={http,https}:此指令用於將 HTTP 和 HTTPS 服務永久新增到預設區域。
  2. {http,https}:使用大括號將多個服務包起來,並以逗號分隔,表示同時新增多個服務。
  3. sudo firewall-cmd --reload:此指令用於重新載入防火牆設定,使永久變更生效。

新增連線埠到防火牆區域

有時候,我們需要開放特定的連線埠,而不是依賴預定義的服務。例如,假設我們安裝了 Webmin,它需要開放 TCP 連線埠 10000。

[donnie@localhost ~]$ sudo firewall-cmd --add-port=10000/tcp
success

內容解密:

  1. sudo firewall-cmd --add-port=10000/tcp:此指令用於將 TCP 連線埠 10000 新增到目前的預設區域。
  2. 10000/tcp:表示要開放的連線埠號碼和協定(TCP)。

同樣地,若要使變更永久生效,我們需要使用 --permanent 選項並重新載入防火牆設定。

[donnie@localhost ~]$ sudo firewall-cmd --permanent --add-port=10000/tcp
success
[donnie@localhost ~]$ sudo firewall-cmd --reload
success

內容解密:

  1. --permanent:使變更永久生效。
  2. sudo firewall-cmd --reload:重新載入防火牆設定,使變更生效。

我們也可以一次性新增多個連線埠,只需將它們以逗號分隔並包在大括號內即可。

[donnie@localhost ~]$ sudo firewall-cmd --add-port={636/tcp,637/tcp,638/udp}
success

內容解密:

  1. {636/tcp,637/tcp,638/udp}:表示要新增的多個連線埠和協定。
  2. 此指令一次性新增多個連線埠到目前的預設區域。