返回文章列表

RHEL防火牆ICMP封包與直接規則控制

本文探討 RHEL/CentOS 7 環境下,使用 firewalld 管理防火牆規則,包含控制 ICMP 封包、使用 panic mode、記錄被封鎖封包,以及使用豐富語言規則和直接規則設定。文章詳細說明如何檢視、新增、刪除和使規則永久生效,並提供程式碼範例和詳細的指令說明,幫助讀者理解並應用於實際操作。

系統管理 資安

在 Linux 系統中,防火牆是確保系統安全的重要組成部分。本文將探討如何在 RHEL/CentOS 7 環境下,使用 firewalld 這個動態防火牆管理工具來控制 ICMP 封包,以及如何使用 panic mode 和記錄被封鎖的封包。同時,我們也會探討如何使用豐富語言規則和直接規則進行更精細的防火牆設定,並提供相關指令和程式碼範例,讓讀者能夠更好地理解和應用這些技術。

管理防火牆規則與ICMP封包控制

在前面的章節中,我們探討瞭如何使用 firewall-cmd 指令來管理防火牆規則,包括開啟和關閉特定埠號的存取許可權。在本章節中,我們將進一步討論如何控制 ICMP 封包,以及如何使用 panic mode 和記錄被封鎖的封包。

控制ICMP封包

ICMP(Internet Control Message Protocol)是一種用於網路診斷和錯誤報告的協定。然而,某些型別的 ICMP 封包可能會被惡意利用,因此我們需要對其進行控制。

首先,讓我們檢視目前預設的 public 區域的狀態:

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

從輸出結果中,我們可以看到 icmp-blocks 行是空的,這意味著目前尚未封鎖任何 ICMP 封包。

檢視可用的ICMP型別

要檢視所有可用的 ICMP 型別,可以使用以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --get-icmptypes
address-unreachable bad-header communication-prohibited destination-unreachable echo-reply echo-r
[donnie@localhost ~]$

檢視特定ICMP型別的資訊

要檢視特定 ICMP 型別的資訊,可以使用以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --info-icmptype=network-redirect
network-redirect destina
[donnie@localhost ~]$ sudo firewall-cmd --info-icmptype=neighbour-advertisement
neighbour-advertis
destination: ipv6
[donnie@localhost ~]$

封鎖特定ICMP封包

要封鎖特定的 ICMP 封包,可以使用 --add-icmp-block 選項。例如,要封鎖 host-redirect 封包,可以執行以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --add-icmp-block=host-redirect
success
[donnie@localhost ~]$ sudo firewall-cmd --query-icmp-block=host-redirect
yes
[donnie@localhost ~]$

同時封鎖多個ICMP型別

要同時封鎖多個 ICMP 型別,可以使用以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --add-icmp-block={host-redirect,network-redirect}
success
[donnie@localhost ~]$

使變更永久生效

要使變更永久生效,可以使用 --runtime-to-permanent 選項:

[donnie@localhost ~]$ sudo firewall-cmd --runtime-to-permanent
success
[donnie@localhost ~]$

使用panic mode

panic mode 可以立即中斷所有網路通訊。要啟用 panic mode,可以執行以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --panic-on
[sudo] password for donnie:
success
[donnie@localhost ~]$

要關閉 panic mode,可以執行以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --panic-off
[sudo] password for donnie:
success
[donnie@localhost ~]$

檢查panic mode狀態

要檢查 panic mode 的狀態,可以執行以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --query-panic
[sudo] password for donnie:
no
[donnie@localhost ~]$

記錄被封鎖的封包

要記錄被封鎖的封包,可以使用 --set-log-denied 選項。例如,要記錄所有被封鎖的封包,可以執行以下指令:

[donnie@localhost ~]$ sudo firewall-cmd --set-log-denied=all
success
[donnie@localhost ~]$ sudo firewall-cmd --get-log-denied
all
[donnie@localhost ~]$

要使變更永久生效,可以使用 --runtime-to-permanent 選項。

檢視記錄的封包

在 RHEL 系統中,被封鎖的封包的記錄會被寫入 /var/log/messages 檔案中。

RHEL 防火牆設定:深入理解 firewalld 與 iptables

在 RHEL(Red Hat Enterprise Linux)生態系中,/var/log/messages 是主要的系統日誌檔案,用於記錄系統中的重要事件,包括防火牆相關的訊息。透過特定的訊息標籤(message tags),管理員可以更容易地稽核日誌,以找出被丟棄的封包。

理解 firewalld 訊息標籤

例如,當系統阻止廣播封包時,日誌中可能會出現類別似以下的訊息:

Aug 20 14:57:21 localhost kernel: FINAL_REJECT: IN=enp0s3 OUT= MAC=ff:ff:ff:ff:ff:ff:00:1f:29:02 TTL=64 ID=62867 DF PROTO=UDP SPT=21327 DPT=21327 LEN=120

在這條訊息中,FINAL_REJECT 標籤表示該訊息是由輸入鏈(input chain)末尾的最終 REJECT 規則所產生。DST=255.255.255.255 部分則表明這是一個廣播訊息。

程式碼解析

# 檢視系統日誌
sudo journalctl -u firewalld

內容解密:

  • sudo journalctl -u firewalld:此命令用於檢視 firewalld 服務的日誌輸出,有助於瞭解防火牆的運作狀態和歷史事件。

使用 firewalld 的豐富語言規則(rich language rules)

相較於傳統的 iptables 規則,firewalld 的豐富語言規則更接近自然語言,使得編寫防火牆規則變得更加直觀。以下是一個範例:

sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="200.192.0.0/24" service name="http" drop'

這條規則的作用是封鎖來自 200.192.0.0/24 網段對 HTTP 服務的存取。

程式碼解析

# 新增豐富語言規則
sudo firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="200.192.0.0/24" service name="http" drop'
# 檢視當前區域的設定
sudo firewall-cmd --permanent --info-zone=dmz

內容解密:

  • sudo firewall-cmd --permanent --add-rich-rule='...':新增一條豐富語言規則,並使其在重啟後仍然生效。
  • rule family="ipv4":指定該規則適用於 IPv4。
  • source address="200.192.0.0/24":指定來源位址為 200.192.0.0/24 網段。
  • service name="http":指定該規則針對 HTTP 服務。
  • drop:表示直接丟棄符合條件的封包,不回應任何訊息。

RHEL/CentOS 7 中的 iptables 規則

在 RHEL 7 及其衍生版本中,firewalld 使用 iptables 作為後端引擎。雖然不能直接使用 iptables 命令建立規則,但每次使用 firewall-cmd 建立規則時,iptables 後端都會自動產生相應的 iptables 規則並插入到適當的位置。

程式碼解析

# 檢視目前生效的 iptables 規則
sudo iptables -L

內容解密:

  • sudo iptables -L:列出目前生效的 iptables 規則,用於檢查防火牆的設定狀態。

在RHEL/CentOS 7中使用firewalld建立直接規則

理解預設規則組態

在RHEL/CentOS 7中,firewalld預設使用iptables作為其後端。當我們執行iptables -L命令時,可以看到許多預設規則已經被組態好。在INPUT鏈的頂部,我們可以看到連線狀態規則和阻止無效封包的規則。預設策略是ACCEPT,但鏈的最後一條規則是REJECT未被明確允許的內容。

DROP all -- anywhere anywhere ctstate INVALID
REJECT all -- anywhere anywhere reject-with icmp-host-prohibited

內容解密:

  • DROP all -- anywhere anywhere ctstate INVALID:丟棄所有狀態為INVALID的封包。
  • REJECT all -- anywhere anywhere reject-with icmp-host-prohibited:拒絕所有未被明確允許的封包,並傳回ICMP主機禁止訊息。

檢視預設規則儲存位置

預設規則儲存在/usr/lib/python2.7/site-packages/firewall/core/目錄下的Python指令碼中。其中,ipXtables.py指令碼負責設定初始預設防火牆規則。

[donnie@localhost core]$ ls
base.py fw_config.pyc fw_helper.pyo fw_ipset.py fw_policies.pyc fw_service.pyo fw_zone.py icmp.py

內容解密:

  • ipXtables.py指令碼包含了iptables命令的列表,與iptables -L輸出的內容相匹配。

使用直接組態命令

當正常使用firewall-cmd命令無法實作某些功能時,可以使用直接組態命令。但是,這些命令需要謹慎使用,因為它們不會自動將新規則放置在正確的位置,可能會破壞整個防火牆。

建立直接規則

假設我們想要在mangle表的PREROUTING鏈中新增規則,以增強防火牆效能。首先,驗證是否已有直接規則:

sudo firewall-cmd --direct --get-rules ipv4 mangle PREROUTING
sudo firewall-cmd --direct --get-rules ipv6 mangle PREROUTING

然後,新增兩條新規則(針對IPv4和IPv6):

sudo firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 0 -m conntrack --ctstate INVALID -j DROP
sudo firewall-cmd --direct --add-rule ipv4 mangle PREROUTING 1 -p tcp ! --syn -m conntrack --ctstate NEW -j DROP
sudo firewall-cmd --direct --add-rule ipv6 mangle PREROUTING 0 -m conntrack --ctstate INVALID -j DROP
sudo firewall-cmd --direct --add-rule ipv6 mangle PREROUTING 1 -p tcp ! --syn -m conntrack --ctstate NEW -j DROP

內容解密:

  • --direct --add-rule:新增直接規則。
  • ipv4 mangle PREROUTING 0:在PREROUTING鏈中新增優先順序為0的規則(針對IPv4)。
  • -m conntrack --ctstate INVALID -j DROP:丟棄所有狀態為INVALID的封包。
  • -p tcp ! --syn -m conntrack --ctstate NEW -j DROP:丟棄所有非SYN封包且狀態為NEW的TCP封包。

驗證直接規則

新增規則後,使用以下命令驗證:

[donnie@localhost ~]$ sudo firewall-cmd --direct --get-rules ipv4 mangle PREROUTING
0 -m conntrack --ctstate INVALID -j DROP
1 -p tcp '!' --syn -m conntrack --ctstate NEW -j DROP
[donnie@localhost ~]$ sudo firewall-cmd --direct --get-rules ipv6 mangle PREROUTING
0 -m conntrack --ctstate INVALID -j DROP
1 -p tcp '!' --syn -m conntrack --ctstate NEW -j DROP

內容解密:

  • 驗證結果顯示新增的規則已生效。

使直接規則永久生效

最後,使用以下命令使直接規則永久生效:

[donnie@localhost ~]$ sudo firewall-cmd --runtime-to-permanent
[sudo] password for donnie:
success
[donnie@localhost ~]$

內容解密:

  • --runtime-to-permanent:將目前執行的規則儲存為永久組態。