紅帽系的linux系統中防火牆--firewalld

厚礼蝎發表於2024-08-29

firewalld簡介

  • firewalld是Red Hat系列Linux發行版(如Fedora、CentOS等)引入的一種動態防火牆管理工具,它充當了 Linux 核心的 Netfilter 框架的前端,具體防火牆執行是由核心的netfilter來執行的。
  • firewalld提供了一個基於區域(zone)和服務(service)的簡化配置介面,使得管理防火牆規則更加容易。
  • 它支援動態更新防火牆規則,可以在執行時新增、刪除、修改規則,而不需要重新載入整個防火牆配置。
  • firewalld的配置檔案位於 /etc/firewalld/ 目錄下,主要是一些XML格式的檔案,如 zones、services、richrules 等。

安裝

firewalld是紅帽系的linux系統的預設防火牆,是預設安裝的,一般不需要手動安裝的。

yum install firewalld firewall-config

firewalld管理

啟動服務

systemctl start firewalld
systemctl restart firewalld

設定開機自啟、禁用開機自啟

systemctl enable firewalld

systemctl disabled firewalld

停止服務

systemctl stop firewalld

檢視服務狀態

systemctl status firewalld
# 或者
firewall-cmd --state

檢視版本

firewall-cmd --version

firewalld中的區域

相比於其他防火牆工具,firewalld引入了區域(Zone)概念。

firewalld將所有的網路資料流量劃分為多個區域,從而簡化防火牆管理。

根據資料包的源IP地址或傳入網路介面等條件,將資料流量轉入相應區域的防火牆規則。

對於進入系統的資料包,首先檢查的就是其源地址.

  • 若源地址關聯到特定的區域,則執行該區域所制定的規則.
  • 若源地址未關聯到特定的區域,則使用傳入網路介面的區域並執行該區域所制定的規則.
  • 若網路介面未關聯到特定的區域,則使用預設區域並執行該區域所制定的規則.

預設區域不是單獨的區域,而是指向系統上定義的某個其他區域。

預設情況下,預設區域是 Public,但是系統管理員可以更改預設區域。

以上匹配規則,按照先後順序,匹配到就不再匹配後面的規則。

預定義的區域

區域 名稱 說明
trusted 信任區域 允許所有網路通訊透過
public 公共區域 只接受那些被選中的連線,預設只允許ssh和dhcpv6-client,這個zone是預設zone
work 工作區域 除非與傳出流量相關,或者與ssh、ipp-client、dhcpv6-client預定義服務匹配的傳入流量,其他均拒絕
home 家庭區域 除非與傳出流量相關,或者與ssh、mdns、ipp-client、samba-client或dhcpv6-client預定義服務匹配的傳入流量,其他均拒絕
internal 內部區域 與home相同
external 外部區域 除非與傳出流量相關,否則除了ssh以外的流量都會被拒絕。
dmz 隔離區域 除非與傳出流量相關,否則除了ssh以外的流量都會被拒絕
drop 丟棄區域 除非與傳出流量相關,否則丟棄所有傳入流量,並且不產生包含icmp的錯誤響應
block 限制區域 除非與傳出流量相關,否則拒絕所有流入流量

區域管理

獲取所有可用區域

$ firewall-cmd --get-zones
block dmz drop external home internal nm-shared public trusted work

獲取當前活動的區域

$ firewall-cmd --get-active-zones 
public
  interfaces: enp0s3 enp0s8

獲取預設區域

$ firewall-cmd --get-default-zone 
public

獲取區域的規則

# 獲取預設區域的規則
firewall-cmd --list-all

# 獲取所有區域的規則
firewall-cmd --list-all-zones

# 獲取指定區域的規則
firewall-cmd --list-all --zone=home

區域中的網路卡

# 獲取網路卡所在的區域
firewall-cmd --get-zone-of-interface=enp0s3

# 為網路卡繫結區域
firewall-cmd --zone=區域名稱 --add-interface=網路卡名稱

# 修改繫結
firewall-cmd --zone=區域名稱 --change-interface=網路卡名稱

# 刪除繫結
firewall-cmd --zone=區域名稱 --remove-interface=網路卡名稱

設定預設區域

firewall-cmd --set-default-zone=home

注意:
後面其他的所有操作都是基於區域的操作
只要命令中不攜帶區域,那麼就是對預設區域的操作

特殊引數

  • --permanent 表示永久生效,但是當前不生效
  • --reload 重新載入防火牆規則,使更改生效
  • --runtime-to-permanent 將當前的執行時配置寫入規則配置檔案中,使之成為永久性配置。
  • --panic-on 拒絕所有包,如果是遠端連線的,會立即斷開連線謹慎使用 不過不會永久生效,重啟服務就會恢復
  • --panic-off 取消拒絕狀態
  • --query-panic 檢視是否拒絕所有包

將源地址新增到區域

# 新增
firewall-cmd --add-source=源地址 --zone=區域名
# 刪除
firewall-cmd --remove-source=源地址 --zone=區域名

服務管理

檢視服務

# 檢視預設區域的允許服務
firewall-cmd --list-services

# 檢視指定區域的允許服務
firewall-cmd --zone=home --list-services

# 檢視所有可被使用的服務
firewall-cmd --get-services

新增服務

# 給home區域新增http服務,並且是永久儲存
firewall-cmd --zone=home --add-service=http --permanent

# 給預設區域新增服務http,當前生效
firewall-cmd --add-service=http

# 同時新增多個服務
firewall-cmd --add-service={http,https,ntp,ftp}

刪除服務

# 刪除預設區域中的http服務,臨時生效
firewall-cmd --remove-service=http

# 刪除home區域中的http服務,永久儲存,但當前不生效
firewall-cmd --zone=home --remove-service=http --permanent

# 同時刪除多個服務
firewall-cmd --remove-service={http,https,ntp,ftp}

查詢指定服務是否開啟

# 檢視當前區域的http服務是否開啟,其他區域可以指定--zone=來查詢
firewall-cmd --query-service=http

自定義服務

可透過xml檔案來建立

  • --new-service-from-file=<filename> [--name=<service>] 根據已有xml檔案來建立
    也可以透過命令列建立
  • --new-service=<service>

注意:
一定要加上 --permanent

# 建立一個名為test的服務
firewall-cmd --new-service=test --permanent
# 為這個服務新增埠
firewall-cmd --service=test --add-port=9090/tcp --permanent
firewall-cmd --service=test --add-source-port=10001-10003/tcp --permanent
firewall-cmd --service=test --add-protocol=udp --permanent
# 新增註釋
firewall-cmd --service=test --set-description='This is a test service !' --permanent
firewall-cmd --service=test --set-short="this is short" --permanent

# 過載,才能透過--get-services看到
firewall-cmd --reload

# 檢視服務
$ cat /etc/firewalld/services/test.xml
<?xml version="1.0" encoding="utf-8"?>
<service>
  <short>this is short</short>
  <description>This is a test service !</description>
  <port port="9090" protocol="tcp"/>
  <protocol value="udp"/>
  <source-port port="10001-10003" protocol="tcp"/>
</service>

# 檢視服務的簡要資訊
firewall-cmd --info-service=test

# 檢視服務路徑
firewall-cmd --path-service=test --permanent

# 刪除服務
firewall-cmd --delete-service=test --permanent

# 都需要重新載入
firewall-cmd --reload

自定義服務的使用有預定義的服務用法相同

埠管理

檢視埠

# 檢視當前預設區域的開放埠
firewall-cmd --list-ports

# 檢視指定區域的開放埠情況
firewall-cmd --list-ports --zone=home

# 檢查埠是否開放
firewall-cmd --query-port=88/tcp
# 檢查多個埠
# 檢查多個連續的埠
firewall-cmd --query-port=80-84/tcp
# 檢查多個非連續埠
firewall-cmd --query-port={88,90}/tcp
firewall-cmd --query-port={88/tcp,77/udp}
# 指定區域查詢埠
firewall-cmd --query-port=88/tcp --zone=home

新增埠

firewall-cmd --add-port=8080/tcp
firewall-cmd --zone=home --add-port=8080/tcp --permanent
firewall-cmd --add-port=8080-8099/tcp --permanent
# 新增多個非連續埠
firewall-cmd --add-port={88,90}/tcp
firewall-cmd --add-port={88/tcp,77/udp}

刪除埠

firewall-cmd --remove-port=8080/tcp
firewall-cmd --zone=home --remove-port=8080/tcp --permanent
firewall-cmd --remove-port=8080-8099/tcp --permanent
# 刪除多個非連續埠
firewall-cmd --remove-port={88,90}/tcp
firewall-cmd --remove-port={88/tcp,77/udp}

拒絕日誌

# 開啟記錄所有的拒絕日誌
firewall-cmd --set-log-denied=all
# 查詢拒絕日誌的狀態
firewall-cmd --get-log-denied

資料轉發

firewall-cmd --add-forward-port=port=80:proto=tcp:toport=8080   # 將80埠的流量轉發至8080
firewall-cmd --add-forward-port=proto=80:proto=tcp:toaddr=192.168.1.0.1 # 將80埠的流量轉發至192.168.0.1
firewall-cmd --add-forward-port=proto=80:proto=tcp:toaddr=192.168.0.1:toport=8080 # 將80埠的流量轉發至192.168.0.1的8080埠

如果是轉發到遠端埠,一定要開啟偽裝IP,否則,無法正常回包,導致訪問失敗

偽裝IP

firewall-cmd --query-masquerade  # 檢查是否允許偽裝IP
firewall-cmd --add-masquerade    # 允許防火牆偽裝IP
firewall-cmd --remove-masquerade # 禁止防火牆偽裝IP

富規則 rich-rule

檢視富規則

firewall-cmd --list-rich-rules
# 指定區域
firewall-cmd --list-rich-rules --zone=home

建立富規則

# 允許10.1.0.12訪問本地的tcp 80埠
firewall-cmd --add-rich-rule="rule family='ipv4' source address='10.1.0.12' port port=80  protocol=tcp accept"

# 拒絕來自10.1.0.12的ping包
firewall-cmd --add-rich-rule='rule family="ipv4" source address="10.1.0.12" protocol value="icmp" drop'

# 拒絕所有的ping包
firewall-cmd --add-rich-rule='rule protocol value=icmp drop'

# 拒絕所有的ping包,並永久生效
firewall-cmd --add-rich-rule='rule protocol value=icmp drop' --permanent
firewall-cmd --reload

# 丟棄掉來自10.1.0.12的ssh服務相關的包
firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.1.0.12 service name=ssh drop'

# 拒絕所有IPv4 UDP流量的53埠訪問。
firewall-cmd --add-rich-rule='rule family="ipv4" port protocol="udp" port="53" drop'

# 拒絕所有從eth0網路介面進入的IPv4流量。
firewall-cmd --add-rich-rule='rule family="ipv4" source interface="eth0" drop'

# 指定區域myzone,僅在工作時間(例如 9AM 到 6PM)允許特定源 IP 訪問本地的6379埠,並永久生效
firewall-cmd --zone=myzone --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port port=6379 protocol=tcp time daytime from="09:00" to="18:00" accept' --permanent
firewall-cmd --reload

# 允許源地址為10.1.0.12來訪問目標地址為10.1.0.16的50000埠
firewall-cmd --add-rich-rule='rule family=ipv4 source address=10.1.0.12 port port=50000 protocol=tcp destination address=10.1.0.16 accept'

引數說明

  • --add-rich-rule= 值表示一條規則,規則必須以 rule 關鍵字開頭
  • family= 指定該規則僅應用於什麼協議的資料包上:可選項 IPv4和IPv6
  • source address= 設定源地址
  • source interface= 設定源介面
  • destination address= 設定目標地址
  • port port= 設定目標埠 設定埠的同時需要指定協議 所以一般格式是 port port=50000 protocol=tcp
  • protocol value= 指的是匹配的協議,例如 ping包是icmp協議,那就是 protocol value=icmp
  • service name= 指定匹配的服務
  • time daytime 設定時間
  • reject/drop/accept 指定動作,拒絕/丟棄/允許

刪除規則

需要完整的寫出規則

firewall-cmd --remove-rich-rule='rule family=ipv4 source address=10.1.0.12 port port=50000 protocol=tcp destination address=10.1.0.14 accept'

direct

可以直接設定iptables的規則

例如

在INPUT鏈的頂部(0)新增一條允許10.1.0.12訪問本地的80埠的規則

firewall-cmd --direct --add-rule ipv4 filter INPUT 0 -s 10.1.0.12 -p tcp -m multiport --dport 80 -j ACCEPT

然後透過iptables檢視

但是要注意的是 這樣設定很容易與firewalld的其他配置衝突或者混淆,容易造成規則不生效的狀況

這個功能已經被標記棄用了,在未來的版本中會被移除掉

相關文章