# Firewalld 防火牆 ###### tags: `主機管理` > [基於國家 IP 段的資料](https://github.com/herrbischoff/country-ip-blocks) * 透過 state 可以查看目前運行狀態,如果顯示 running 就表示正常運行 ```bash firewall-cmd --state ``` * 查詢指令用法 ```bash firewall-cmd --help ``` * 查看目前防火牆名單 ```bash firewall-cmd --list-all ``` * 永久設定參數 `--permanent` * 設定內容 * 針對port ```bash= firewall-cmd --permanent --add-port=22/TCP firewall-cmd --permanent --remove-port=22/TCP ``` * 針對連線協定 ```bash= firewall-cmd --permanent --add-service=ssh firewall-cmd --permanent --remove-service=ssh ``` * 針對特定ip ```bash= firewall-cmd --permanent --add-source=192.168.1.100 firewall-cmd --permanent --add-source=192.168.1.0/24 firewall-cmd --permanent --remove-source=192.168.1.100 ``` * 利用rich rule來進行細節設定 ```bash= #單一IP firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.100' reject" #除了針對特定單一IP外,再針對特別連線port進行設定 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="192.168.1.100" port protocol="tcp" port="3306" accept' #針對IP範圍 firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source address='192.168.1.0/24' reject" ``` * 規則整合作法 * ipset (IP清單整合) * 簡易指令介紹 ```bash # 新增一個自己定義的ip清單,例如ssh_ip_set # 如果hash:ip改成hash:net,則可以允許設定網段,例如:192.168.0.0/24 firewall-cmd --permanent --new-ipset=ssh_ip_set --type=hash:ip # 新增一個ssh_ip_set白名單可以登入ssh的 firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source ipset='ssh_ip_set' port protocol='tcp' port='22' accept" # 查詢目前的IP清單 firewall-cmd --ipset=ssh_ip_set --get-entries # 新增白名單 firewall-cmd --permanent --ipset=ssh_ip_set --add-entry=192.168.0.1 # 移除白名單 firewall-cmd --permanent --ipset=ssh_ip_set --remove-entry=192.168.0.1 ``` * 開放SSH管理腳本 ```bash #!/bin/bash # 檢查 root 權限 if [[ $EUID -ne 0 ]]; then echo "請以 root 權限執行此腳本" exit 1 fi IPSET_NAME="ssh_whitelist" # 初始化:如果 ipset 不存在則建立 init_ipset() { if ! firewall-cmd --get-ipsets | grep -q "$IPSET_NAME"; then echo "正在初始化 $IPSET_NAME..." firewall-cmd --permanent --new-ipset=$IPSET_NAME --type=hash:ip # 建立規則關聯(只針對此 ipset 開放 port 22) firewall-cmd --permanent --add-rich-rule="rule family='ipv4' source ipset='$IPSET_NAME' port protocol='tcp' port='22' accept" firewall-cmd --reload echo "初始化完成。" fi } # 執行初始化 init_ipset while true; do echo "========================================" echo " Firewalld SSH 白名單管理 (IPSet)" echo "========================================" echo "1) 查看目前白名單" echo "2) 新增 IP 到白名單" echo "3) 移除 IP 從白名單" echo "4) 重新載入防火牆 (Reload)" echo "q) 離開" read -p "請選擇操作 [1-4/q]: " choice case $choice in 1) echo "--- 目前授權的 IP 清單 ---" firewall-cmd --ipset=$IPSET_NAME --get-entries echo "--------------------------" ;; 2) read -p "請輸入要新增的 IP: " target_ip if [[ $target_ip =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]]; then firewall-cmd --permanent --ipset=$IPSET_NAME --add-entry=$target_ip firewall-cmd --reload echo "✅ 已新增 $target_ip 並重新載入。" else echo "❌ IP 格式不正確。" fi ;; 3) read -p "請輸入要移除的 IP: " target_ip firewall-cmd --permanent --ipset=$IPSET_NAME --remove-entry=$target_ip firewall-cmd --reload echo "⚠️ 已移除 $target_ip 並重新載入。" ;; 4) firewall-cmd --reload echo "🔄 防火牆已重新載入。" ;; q) echo "結束管理。" exit 0 ;; *) echo "無效選項,請重新輸入。" ;; esac echo "" done ``` * self-defined services (Port服務整合) ```bash # 創建 ports 清單 firewall-cmd --permanent --new-service=guardium-ports # 增加 ports 清單的內容 firewall-cmd --permanent --service=guardium-ports --add-port=16016-16021/tcp firewall-cmd --permanent --service=guardium-ports --add-port=8081/tcp firewall-cmd --permanent --service=guardium-ports --add-port=9800-9801/tcp # 查看 ports 清單的內容 firewall-cmd --permanent --info-service=guardium-ports # 新增guardium-ports的防火牆規則 firewall-cmd --permanent --add-rich-rule='rule family="ipv4" source address="140.130.2.141" service name="guardium-ports" accept' ``` * 重新載入防火牆規則 > 每次重新設定防火牆後,firewalld 並不會自動生效,需要透過 reload 重新載入規則讓設定生效 ```bash firewall-cmd --reload ```