跳转到帖子
在手机APP中查看

一个更好的浏览方法。了解更多

PHP论坛人

主屏幕上的全屏APP,带有推送通知、徽章等。

在iOS和iPadOS上安装此APP
  1. 在Safari中轻敲分享图标
  2. 滚动菜单并轻敲添加到主屏幕
  3. 轻敲右上角的添加按钮。
在安卓上安装此APP
  1. 轻敲浏览器右上角的三个点菜单 (⋮) 。
  2. 轻敲添加到主屏幕安装APP
  3. 轻敲安装进行确认。

Debian 13 原生防火牆 nftables、Fail2ban入侵防護/Fail2ban Part 1

精选回复


Debian 13 原生防火牆 nftables、Fail2ban入侵防護/Fail2ban Part 1



******************************************************
Fail2ban Part 1

等待LNMP服務都安裝設置完,再做 Part 2
******************************************************



---------------
前言
---------------

為何選擇原生 nftables?

相較於 iptables、ufw 或 firewalld,nftables 具備以下優勢:

雙棧統一管理:使用 inet 位址族,一套規則同時覆蓋 IPv4 與 IPv6,不會有遺漏

原子性載入:規則集一次性套用,不會出現套用到一半的中間狀態

內建計量器:速率限制更精確,無需額外核心模組

語法預驗證:nft -c -f 可在套用前驗證語法,大幅降低鎖死SSH的風險

Fail2ban 整合:與 Fail2ban 1.1.0+ 完整整合,可動態封鎖攻擊IP



IPv4 與 IPv6 雙棧的必要性

許多管理員只設定 IPv4 防火牆,卻忽略了 IPv6。若伺服器持有 IPv6 位址而未設定對應規則,IPv6 流量將完全不受保護,形同開了一扇隱形後門

本文使用 inet 位址族,同一套規則自動涵蓋 IPv4 與 IPv6,杜絕此類遺漏



為何採用自訂 firewall.service 而非 nftables.service?

本文採用自訂 firewall.service 驅動腳本,而非直接依賴 nftables.service 載入靜態設定檔,原因如下:

腳本在每次啟動時動態建構規則,可整合環境變數、條件判斷與 Shell 邏輯

Before=network-pre.target 確保規則在網路啟動前就位,不留空窗期

方便日後擴充:直接修改 Shell 腳本即可,語法直觀



------------------
整體流量架構
------------------


外部流量
   │
   ▼
nftables (inet filter)
   ├── INPUT chain
   │     ├── 黑名單 set (f2b-blacklist4/6、blacklist4/6) → DROP  ← 最高優先
   │     ├── lo 介面 → ACCEPT
   │     ├── 已建立連線 (established/related) → ACCEPT           ← 效能優化
   │     ├── 無效封包 (invalid state) → DROP
   │     ├── 管理員 IP 白名單 → ACCEPT                           ← 無任何限速
   │     ├── 私有網段白名單 → ACCEPT                             ← VPC/監控/LB
   │     ├── 異常 TCP flags → DROP                               ← 防掃描/畸形封包
   │     ├── ICMPv4 速率限制 → ACCEPT
   │     ├── ICMPv6 必要類型 → ACCEPT                            ← NDP,IPv6 必需
   │     ├── SSH 速率限制 (10/min) → ACCEPT / DROP
   │     ├── Web (80/443) → ACCEPT                               ← 完全開放
   │     ├── 管理後台 (888) → 僅限白名單 IP
   │     └── 其餘 → LOG + DROP                                   ← 限速 2/min 避免日誌洪流
   ├── FORWARD chain → DROP                                       ← 此主機非路由器
   └── OUTPUT chain → ACCEPT                                      ← 主機主動對外連線
         │
         ▼
    Fail2ban(持續掃描日誌,偵測暴力攻擊)
         └── 操作 nftables set,動態加入封鎖 IP(含 timeout 自動過期)





---------------------------
持久化黑名單生命週期
---------------------------


Fail2ban 啟動
    └─> actionstart
           ├─ 建立 set(若不存在,冪等操作)
           ├─ flush set(清空避免重複累積)
           └─ 從 .ipset 檔案恢復黑名單(含 bantime timeout)

偵測到攻擊
    └─> actionban
           ├─ nft add element(加入 set,設定 timeout)
           └─ 追加寫入 .ipset 持久化檔案

Ban 過期或手動解封
    └─> actionunban
           ├─ nft delete element
           └─ sed 移除 .ipset 對應行

Fail2ban 正常停止
    └─> actionstop
           ├─ 從 nft 讀取目前黑名單
           └─ 原子性寫入 .ipset(.new 暫存 → 正式)

Cron(每小時整點)
    └─> 從 nft 讀取目前 set → 覆寫 .ipset
           └─ 確保強制重啟時(reboot、核心 panic)也能保留最近 1 小時內的封鎖



為何需要 Cron 備份?

Fail2ban 的 nftables set 是記憶體狀態。actionstop 只在 Fail2ban 正常停止時觸發

若發生強制重啟或電源中斷,actionstop 不會執行,若無 Cron 備份,黑名單將全部消失



--------------------
操作前安全提醒
--------------------

錯誤的防火牆規則會導致SSH連線立即中斷,操作前請務必閱讀


開啟帶外管理備援:在套用規則前,請先透過雲端主控台開啟 VNC / Serial Console / IPMI 等帶外管理通道,確保即使SSH中斷也能進行補救

記下所有管理IP(含 IPv6):務必將目前的管理IP(包含 IPv6 位址)加入允許清單,缺一不可。動態IP用戶每次操作前都應重新確認

善用測試模式:腳本提供 test 指令,規則套用後 120 秒自動復原,可安全驗證而不影響後續連線。務必先用 test,確認SSH正常後再用 start 正式套用

雲端內網IP需加入白名單:AWS、GCP、阿里雲、騰訊雲、Hetzner 等平台的內網 IP(如 10.x.x.x)若有負載平衡器或監控系統

需填入 PRIVATE_NETS_V4,否則健康檢查可能被誤封

修改前備份:重要資料請在操作前完成備份





--------------------------
事前準備:收集必要資訊
--------------------------

在開始前,請收集以下資訊並記錄備用


查看目前SSH連線的來源IP

確認你目前透過哪個IP 連入伺服器(包含 IPv6),此IP必須填入防火牆白名單
ss -tnp | grep :22 | grep ESTAB



查詢本機對外 IPv4 位址(必填)
curl -4 ifconfig.me


查詢本機對外 IPv6 位址(若有則填)
curl -6 ifconfig.me


請記下輸出結果,稍後需填入防火牆腳本的 ADMIN_IP4 與 ADMIN_IP6




確認 IPv6 是否已啟用(預期輸出為 0,代表已啟用)
sysctl net.ipv6.conf.all.disable_ipv6



確認本機的 IPv6 位址
ip -6 addr show



查詢 VPS 私有IP

雲端平台的負載平衡器、監控系統會透過私有IP通訊,需加入白名單
ip addr show | grep 'inet ' | grep -v 127.0.0.1




---------------------------------
安裝 nftables 並清除衝突工具
---------------------------------

更新套件清單並升級
apt update -y && apt upgrade -y



安裝 nftables 防火牆主體、conntrack 用於連線追蹤統計(firewall.sh stats 指令會用到)
apt install -y nftables conntrack



確認nftables版本,預期 nftables v1.1.3 以上
nft --version






-------------------------
停用衝突的防火牆工具
-------------------------

同時啟用多套防火牆工具會造成規則衝突,請依實際安裝情況停用

2>/dev/null || true 的作用:若該服務本就不存在,指令不會報錯中止




停用 ufw(若有安裝)
systemctl disable --now ufw 2>/dev/null || true



停用 firewalld(若有安裝)
systemctl disable --now firewalld 2>/dev/null || true




停用 iptables / ip6tables(若有安裝)

systemctl disable --now iptables 2>/dev/null || true


systemctl disable --now ip6tables 2>/dev/null || true



確認無殘留規則,若有殘留 iptables 規則,執行以下清空

iptables -F 2>/dev/null || true


ip6tables -F 2>/dev/null || true




-------------------------------
清空 nftables 預設設定檔
-------------------------------

nftables.service 預設在開機時載入 /etc/nftables.conf

後續我們將停用 nftables.service,但為了防止它被意外啟用時載入空規則而清掉防火牆,建議將此檔案改為僅執行 flush ruleset:


以下幾行一起貼上

cat > /etc/nftables.conf << 'EOF'
#!/usr/sbin/nft -f
# 此檔案由 firewall.service 接管,請勿直接編輯
# 若 nftables.service 意外被啟用,flush ruleset 可避免載入錯誤規則
flush ruleset
EOF

--------------------

建立防火牆腳本

--------------------

建立目錄

mkdir -p /usr/local/bin

建立防火牆腳本

vi /usr/local/bin/firewall.sh

firewall.sh

貼入以下完整內容,務必修改使用者配置區塊

ADMIN_IP4="請改為您的IPv4"

ADMIN_PORT="888"

# 內網白名單(請根據 ip addr 查詢後填寫)

PRIVATE_NETS_V4=""

PRIVATE_NETS_V6=""

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter

----------------
設定權限
----------------

設定腳本權限 (700 表示僅 root 可讀寫執行,防止其他使用者查看或修改)

chmod 700 /usr/local/bin/firewall.sh


chown root:root /usr/local/bin/firewall.sh






--------------------------------
測試防火牆
--------------------------------

執行測試模式
/usr/local/bin/firewall.sh test



測試模式流程:
1. 產生規則至暫存檔
2. 語法預驗證(通過才繼續)
3. 原子性載入規則(無空窗期)
4. 啟動 120 秒緊急還原計時器
5. 若 SSH 正常 → 按 Enter 取消還原並永久保留規則
6. 若 SSH 異常中斷 → 120 秒後自動還原至套用前狀態



---------------------------------------
另開終端機確認連線 (測試期間進行)
---------------------------------------

在測試期間,另開一個終端機視窗進行以下驗證


測試SSH連線 (應成功)
ssh 你的伺服器IP


測試 IPv4 對外連線 (應成功)
ping -c 3 8.8.8.8


測試 IPv6 對外連線(若有 IPv6)
ping6 -c 3 2001:4860:4860::8888




--------------------------
正式套用規則
--------------------------

確認測試無誤後,正式套用規則

/usr/local/bin/firewall.sh start





---------------------
確認規則已套用
---------------------

查看完整規則集
nft list ruleset



查看 input chain
nft list chain inet filter input




查看統計資訊
/usr/local/bin/firewall.sh stats



----------------------------------------
建立 systemd 服務(開機自動啟動)
----------------------------------------

本文採用自訂 firewall.service 驅動腳本,而非直接依賴 nftables.service 載入靜態設定


建立
vi /etc/systemd/system/firewall.service



貼上以下內容


[Unit]
Description=Custom nftables Firewall (IPv4 + IPv6 Dual Stack)
After=network-pre.target
Before=network.target network-online.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/firewall.sh start
ExecStop=/usr/local/bin/firewall.sh stop
RemainAfterExit=yes
StandardOutput=journal
StandardError=journal

[Install]
WantedBy=multi-user.target





儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter




------------------
啟用並啟動服務
------------------

重新載入 systemd 設定(每次修改 .service 檔案後必須執行)
systemctl daemon-reload



設定開機自動啟動
systemctl enable firewall.service




立即啟動
systemctl start firewall.service




確認狀態,(應顯示 active (exited),oneshot 類型服務執行完畢後正常顯示此狀態)
systemctl status firewall.service




查看啟動日誌
journalctl -u firewall.service --no-pager




---------------------------------------
停用 nftables.service 避免衝突
---------------------------------------

重要:nftables.service 預設在開機時載入 /etc/nftables.conf

若讓它與自訂 firewall.service 並存,可能發生規則衝突或重複載入,必須停用


停用 nftables.service

systemctl disable nftables.service


systemctl stop nftables.service



確認已停用,預期輸出 disabled
systemctl is-enabled nftables.service

-----------------------------------

持久化核心參數 (sysctl)

-----------------------------------

防火牆腳本本身不含 sysctl 調整。sysctl -w 的臨時調整重開機後會恢復預設值,需建立設定檔以持久化

建立

vi /etc/sysctl.d/99-hardening.conf

99-hardening.conf.txt

貼上內容

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter

----------------------
立即套用並驗證
----------------------


立即套用
sysctl --system



驗證,應顯示: = 1
sysctl net.ipv4.tcp_syncookies



驗證,應顯示: = 0
sysctl net.ipv4.conf.all.accept_redirects




-----------------
安裝Fail2ban
-----------------

Fail2ban 持續掃描系統日誌,偵測到多次登入失敗時,自動將來源IP加入nftables封鎖規則,提供動態的入侵防護

同時安裝 whois 以便查詢被封鎖IP的WHOIS資訊,方便排查攻擊來源


apt update -y


apt install -y fail2ban whois





確認版本,預期 Fail2Ban v1.1.0 以上
fail2ban-client --version

------------------------------------------------

設定 Fail2ban × nftables 整合 Action

------------------------------------------------

此設定檔讓 Fail2ban 直接操作 nftables 的 f2b-blacklist4 / f2b-blacklist6 set,並在重啟時從磁碟恢復黑名單

建立

vi /etc/fail2ban/action.d/nftables-set.conf

nftables-set.conf.txt

貼上以下內容(確認以下設置的內容,若你的VPS沒有IPv6,則設置 enable_ipv6 = false)

# 是否啟用 IPv6 支援

# 若伺服器確認無 IPv6 可設為 false,減少 nft 操作與潛在錯誤

enable_ipv6 = false

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter

------------------
設定 jail.local
------------------

為何不直接修改 jail.conf?

/etc/fail2ban/jail.conf 是套件提供的預設設定,套件更新時會被覆蓋

正確做法是建立 /etc/fail2ban/jail.local,Fail2ban啟動時 .local 的設定會覆蓋 .conf,這樣可以在套件更新後保留你的自訂設定

建立

vi /etc/fail2ban/jail.local

jail.local.txt

貼上以下內容

修改 ignoreip 中的佔位文字(你的管理員IPv4、你的管理員IPv6、你VPS的私有IP網段)請替換為實際IP

不存在的項目直接刪除,不要留下佔位文字,否則 fail2ban-client -t 會報錯

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter

-------------------------------
確認 nftables Sets 已建立
-------------------------------

在啟用 Fail2ban 之前,需確認 nftables 的 f2b-blacklist4 與 f2b-blacklist6 sets 已存在(由 firewall.sh start 建立)

若 sets 不存在,Fail2ban 啟動時 actioncheck 會失敗




確認 sets,應看到 f2b-blacklist4 與 f2b-blacklist6
nft list sets








-------------------------------------
設定 fail2ban.local(IPv6 選項)
-------------------------------------

簡單來說:加入 allowipv6 = auto 是為了讓 Fail2ban 能正確處理 IPv6 連線,避免 IPv6 的封鎖失效或產生錯誤

在較舊的 Fail2ban 版本中,如果沒有明確設定 allowipv6,當系統啟用 IPv6 時,可能會導致一些問題

auto 的意義:讓程式自己判斷

結論:加入 allowipv6 = auto 是最佳實務,讓 Fail2ban 自適應系統的網路設定,既能處理 IPv6 攻擊,又不會在無 IPv6 環境中出錯,確保封鎖規則完整生效






建立
vi /etc/fail2ban/fail2ban.local



貼入以下內容


[Definition]
# 選項:allowipv6
# 說明:允許 Fail2ban 使用 IPv6 介面
# 可選值:auto | yes | no
allowipv6 = auto





儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter






--------------------------
Cron 定期備份封鎖清單
--------------------------

Fail2ban 的 nftables set 是記憶體狀態,actionstop 雖然會在 Fail2ban 正常停止時將黑名單寫入磁碟

但若發生強制重啟(reboot、核心 panic、電源中斷),actionstop 不會被觸發

搭配 Cron 定期備份,可確保最多只損失 1小時 內的新增封鎖記錄





建立目錄
mkdir -p /var/lib/fail2ban




設置權限
chmod 750 /var/lib/fail2ban


chown root:root /var/lib/fail2ban



注意:/var/lib/fail2ban 應由 root 擁有並限制存取,避免非特權使用者竄改黑名單檔案

-----------------

建立備份腳本

-----------------

使用獨立腳本比直接在 crontab 中塞長指令更容易維護與排查

建立

vi /usr/local/bin/backup-blacklist.sh

backup-blacklist.sh

貼上內容

儲存檔案並離開vi編輯器

按 Esc,輸入 :wq,按 Enter

----------------------
設定腳本權限
----------------------

chmod 700 /usr/local/bin/backup-blacklist.sh


chown root:root /usr/local/bin/backup-blacklist.sh


----------------------------------
手動執行一次確認
----------------------------------

手動執行一次,確認無誤
/usr/local/bin/backup-blacklist.sh



確認備份結果已寫入,預期有兩個 .ipset 檔案

cd /var/lib/fail2ban/

ls -l



確認已有這 2個 備份檔
nftables-blacklist4.ipset
nftables-blacklist6.ipset







-----------------------
啟用Cron
-----------------------

啟用
systemctl enable --now cron



檢查狀態,確認已運行 active (running)
systemctl status cron





編輯 Cron 任務
crontab -e



在尾部 貼上以下內容


# =====================================
#  備份 Fail2ban 黑名單 相關動作
# =====================================

# 每小時整點備份 nftables Fail2ban 黑名單(IPv4 + IPv6)
0 * * * * /usr/local/bin/backup-blacklist.sh

# 每日凌晨 2:00 清理超過 10000 行的持久化檔案(防止異常成長)
# truncate 只截斷,不能移除過期IP;實務上 Fail2ban actionunban 會即時從檔案移除已解封IP
# 此任務作為最後防線,確保檔案大小可控
0 2 * * * for f in /var/lib/fail2ban/*.ipset; do [ -f "$f" ] && [ "$(wc -l < "$f")" -gt 10000 ] && tail -n 10000 "$f" > "$f.tmp" && mv "$f.tmp" "$f"; done







儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter




-------------------------
驗證
-------------------------

檢視目前所有的Cron任務
crontab -l





-----------------------------
設定 journald 持久化
-----------------------------

預設情況下,systemd-journald 日誌儲存在記憶體中(/run/log/journal),重開機後消失

設定持久化後,日誌會寫入磁碟(/var/log/journal),有利於事後追查攻擊記錄



mkdir -p /var/log/journal


systemd-tmpfiles --create --prefix /var/log/journal



編輯
vi /etc/systemd/journald.conf


找到並修改以下內容(位於 [Journal] 區塊內)


[Journal]

Storage=persistent

# 限制日誌佔用磁碟空間(2GB VPS建議500M)
SystemMaxUse=500M

# 保留7天日誌(604800 秒)
MaxRetentionSec=604800






儲存檔案並離開vi編輯器
按 Esc,輸入 :wq,按 Enter




說明:
SystemMaxUse=500M 限制日誌佔用磁碟空間,避免在 2GB RAM 的小型 VPS 上因磁碟不足造成問題

MaxRetentionSec=604800 保留 7天 日誌







-----------------------------
重啟 journald 使設定生效
-----------------------------


重啟
systemctl restart systemd-journald



確認日誌目錄已建立
ls /var/log/journal/




------------------------
啟用 Fail2ban
------------------------


測試設定檔語法,預期輸出:OK: configuration test is successful
若出現錯誤,請仔細檢查 jail.local 中是否有留下未替換的佔位文字(如 你的管理員IPv4)

fail2ban-client -t






啟用
systemctl enable --now fail2ban



確認狀態,應顯示 active (running)
systemctl status fail2ban






-----------------------
重開機驗證
-----------------------


重開機
reboot



驗證所有服務是否正確自動啟動


確認防火牆服務狀態,應顯示 active (exited)
systemctl status firewall.service



確認 nftables.service 已停用,應顯示 disabled
systemctl is-enabled nftables.service




確認防火牆規則已自動載入

nft list ruleset


nft list chain inet filter input


nft list ruleset | grep -E "whitelist4|blacklist4|f2b"




確認 fail2ban 服務狀態,應顯示為 active (running)
systemctl status fail2ban.service



查看所有啟用的監獄
fail2ban-client status



查看 SSH 監獄狀態
fail2ban-client status sshd



確認 Fail2ban 已整合 nftables(兩個 set 應存在)

nft list set inet filter f2b-blacklist4


nft list set inet filter f2b-blacklist6




確認 Fail2ban 已整合 nftables,應顯示 f2b- 開頭的規則
nft list ruleset | grep f2b




確認白名單已正確載入(應顯示你的管理員IP 與 VPS 私有IP)
fail2ban-client get sshd ignoreip



核心參數驗證

已啟用,應顯示  = 1
sysctl net.ipv4.tcp_syncookies


已禁用,應顯示  = 0
sysctl net.ipv4.conf.all.accept_redirects




確認 SSH 服務監聽狀態(IPv4 + IPv6 雙棧)


ss -tlnp | grep :22


0.0.0.0:22 → IPv4 監聽
[::]:22         → IPv6 監聽

兩個都有才代表雙棧正常




備份腳本驗證

確認 Cron 每小時備份腳本正常運作

ls -lh /var/lib/fail2ban/*.ipset










------------------
測試封鎖功能
------------------

使用 RFC 5737 / RFC 3849 保留的文件用 IP 進行測試,不影響任何真實主機


手動封鎖測試 IPv4 (RFC 5737 文件用IP)
fail2ban-client set sshd banip 192.0.2.100


手動封鎖測試 IPv6 (RFC 3849 文件用IP)
fail2ban-client set sshd banip 2001:db8::100


查看監獄狀態 (Banned IP 欄位應顯示上述被封鎖的IP)
fail2ban-client status sshd



確認 nftables set 中已加入封鎖IP
nft list set inet filter f2b-blacklist4


nft list set inet filter f2b-blacklist6





測試完畢後,解除封鎖
fail2ban-client set sshd unbanip 192.0.2.100


fail2ban-client set sshd unbanip 2001:db8::100



---------------------
常見陷阱與排錯指南
---------------------

陷阱 1:IPv6 防火牆未設定

症狀:IPv4 連線正常,IPv6 流量完全開放

說明:使用 inet 位址族已同時涵蓋 IPv4 與 IPv6,本教學不會有此問題。若自行修改規則只用 ip 族,則需額外建立 ip6 族規則

驗證:
nft list ruleset | grep 'inet\|ip6'


應看到 table inet filter,代表雙棧皆受保護




陷阱 2:ICMPv6 被封鎖

症狀:IPv6 連線時通時不通,或無法取得 IPv6 位址 (SLAAC 失效)

解決:確認 IN_ICMPV6_ALLOWED 包含 133-136 (NDP 鄰居探索) 類型

nft list chain inet filter input | grep icmpv6





陷阱 3:雲端內網IP被封鎖

症狀:重開機後負載平衡器或監控系統無法連線 (常見於 AWS/GCP/Hetzner)

解決:在腳本的 PRIVATE_NETS_V4 填入對應的私有網段 (如 10.0.0.0/8)


查看VPS的私有IP
ip addr show | grep 'inet '




陷阱 4:忘記加入管理 IP

症狀:執行 firewall.sh start 後SSH立即斷線

解決:透過帶外管理 (VNC/Console) 執行:

nft flush ruleset

然後修正腳本中的管理IP再重新測試




陷阱 5:服務只監聽 IPv4

症狀:nftables 規則正確,但 IPv6 用戶仍無法連線論壇

解決:確認 NGINX 監聽 ::80 而非 0.0.0.0:80

ss -tlnp | grep :80

# :::80  → 雙棧(正確)

# 0.0.0.0:80 → 僅 IPv4(需修改 NGINX 設定)



NGINX 設定應包含:
listen 80;
listen [::]:80;
listen 443 ssl;
listen [::]:443 ssl;





陷阱 6:sysctl 參數重開機後消失

症狀:重開機後 net.ipv4.tcp_syncookies 回到預設值 0

解決:確認已完成 持久化核心參數sysctl的設定,建立 /etc/sysctl.d/99-hardening.conf






陷阱 7:nftables.service 與 firewall.service 衝突

症狀:重開機後規則被 nftables.service 覆蓋或清空

解決:確認已停用 nftables.service:

systemctl is-enabled nftables.service


若顯示 enabled,執行:
systemctl disable nftables.service






陷阱 8:Fail2ban 白名單未加入 VPS私有IP

症狀:Fail2ban 誤封鎖雲端平台的健康檢查IP,導致服務中斷

解決:在 jail.local 的 ignoreip 加入VPS分配的私有IP

查看VPS的私有IP
ip addr show | grep 'inet '


確認白名單
fail2ban-client get sshd ignoreip






陷阱 9:論壇靜態資源或 API 被速率限制誤封

症狀:正常用戶在短時間內大量載入頁面(CDN 回源、搜尋爬蟲)被速率限制

解決:針對已知的 CDN / 爬蟲 IP 段加入 PRIVATE_NETS_V4 白名單

例如 Cloudflare 最新 IP 段:https://www.cloudflare.com/ips/(需定期更新)






陷阱 10:網卡名稱不是 eth0

症狀:NAT 規則套用後,SNAT 功能無效

解決:Debian 13 在部分主機商的網卡名稱可能為 ens3、ens18、enp1s0 等,需先確認

ip route | grep default


腳本中 IFACE 變數已使用 ip route 自動偵測,若仍有問題請手動設定






陷阱 11:bantime 單位問題(nftables timeout)

症狀:Fail2ban 封鎖後封鎖時間不符預期,IP提早或延遲解封

說明:nftables timeout 接受帶單位的字串(如 3600s、1h)

nftables-set.conf 中 actionban 的 <bantime> 變數由 Fail2ban 傳入的是秒數整數,需在 action 中手動加上 s 後綴:

nft add element inet filter f2b-blacklist4 { <ip> timeout <bantime>s }




陷阱 12:Fail2ban 重啟後黑名單消失

說明:Fail2ban 的 nftables set 為記憶體狀態,actionstop 只在 Fail2ban 正常停止時觸發

若遇到強制重啟(reboot、電源中斷、核心 panic),actionstop 不會被執行,黑名單無法寫入磁碟

解決:確認已完成 Cron 備份腳本設定。Cron 每小時備份一次,最多只損失 1小時內的新增封鎖






陷阱 13:Debian 13 無 /var/log/auth.log

症狀:Fail2ban 啟動後 sshd jail 無法偵測到任何登入失敗

說明:Debian 13 預設使用 systemd-journald,SSH登入失敗記錄在 journal 而非傳統的 /var/log/auth.log

解決:確認 jail.local 中設定 backend = systemd

驗證SSH登入失敗是否有被 journald 記錄
journalctl -u ssh --since "10 minutes ago" | grep -i fail





陷阱 14:Cron 備份腳本寫入中途被讀取(競態條件)

說明:若不使用原子性寫入,Cron 腳本寫入 .ipset 檔案的過程中若 Fail2ban 重啟,可能讀到寫到一半的不完整內容

解決:本文的備份腳本已使用 mktemp + mv -f 的原子性寫入方式,先寫暫存檔,完成後再搬移,確保讀取到的永遠是完整的備份





陷阱 15:fail2ban-client -t 失敗,顯示 ignoreip 解析錯誤

症狀:執行 fail2ban-client -t 時出現 "IP" is not a valid IP 或類似錯誤

原因:ignoreip 中仍保留了佔位文字(如 你的管理員IPv4),或填入了無效格式的IP

解決:重新檢查 /etc/fail2ban/jail.local,確認所有佔位文字已替換為實際IP或完全刪除










------------------------
日常維護指令速查
------------------------



----------------
管理防火牆
----------------

手動啟動防火牆
/usr/local/bin/firewall.sh start


手動停止防火牆 (清除所有規則)
/usr/local/bin/firewall.sh stop


測試模式 (修改規則後先測試)
/usr/local/bin/firewall.sh test

查看統計
/usr/local/bin/firewall.sh stats


透過 systemd
systemctl start firewall.service

systemctl stop  firewall.service

systemctl restart firewall.service

systemctl status firewall.service


----------------------
查看 nftables 規則
----------------------


查看完整規則集
nft list ruleset


查看 input chain
nft list chain inet filter input


即時監控被丟棄的封包
journalctl -k -f | grep "FW_DROP"


查看核心日誌
dmesg -w | grep "FW_DROP"



--------------------
管理 Fail2ban
--------------------

查看所有監獄
fail2ban-client status


查看特定監獄 (如 sshd)
fail2ban-client status sshd


手動封鎖 IP
fail2ban-client set sshd banip 1.2.3.4


解除封鎖 IP
fail2ban-client set sshd unbanip 1.2.3.4


重新載入設定
fail2ban-client reload


查看日誌(最近 50 筆)
journalctl -u fail2ban.service --no-pager -n 50




------------------
查看服務日誌
------------------

防火牆服務日誌 (本次開機)
journalctl -u firewall.service --boot


Fail2ban 服務日誌 (本次開機)
journalctl -u fail2ban.service --boot


即時監控所有相關日誌
journalctl -f | grep -E "fail2ban|nftables|FW_DROP"


-----------------
管理封鎖清單
-----------------

查看目前 IPv4 黑名單
nft list set inet filter f2b-blacklist4


查看目前 IPv6 黑名單
nft list set inet filter f2b-blacklist6


手動觸發備份
/usr/local/bin/backup-blacklist.sh


查看備份檔案
ls -lh /var/lib/fail2ban/*.ipset

wc -l /var/lib/fail2ban/nftables-blacklist4.ipset




-----------------------
Part 2
-----------------------


等待LNMP服務都安裝配置完畢

再來做 Fail2ban Part 2

本帖最后于,由Jack编辑

创建帐户或登录后发表意见

帐户

导航

搜索

搜索

配置浏览器推送通知

Chrome (安卓)
  1. 轻敲地址栏旁的锁形图标。
  2. 轻敲权限 → 通知。
  3. 调整你的偏好。
Chrome (台式电脑)
  1. 点击地址栏中的挂锁图标。
  2. 选择网站设置。
  3. 找到通知选项并调整你的偏好。