fail2ban Linux 資訊安全 SSH

fail2ban 教學:為什麼你照著網路教學設定還是沒效?一篇搞懂現代 Linux 的正確設定方式

fail2ban 在 Ubuntu 22.04、24.04、Debian 12 上的安裝與設定教學,重點解決新版系統 backend 預設值造成 sshd jail 無法啟動的常見問題,附完整除錯流程。

開了一台 VPS,跑 sudo tail -f /var/log/auth.log 就會看到成千上萬的 SSH 暴力登入嘗試,來自全世界各地的殭屍網路整天在敲你家的門。這時候最標準的解法就是裝 fail2ban,讓它自動把那些試錯的 IP 關進小黑屋。

問題是,現在網路上九成九的 fail2ban 教學都是七、八年前寫的,照著那些步驟在 Ubuntu 22.04、24.04 或 Debian 12 上操作,你很可能會遇到一個詭異現象:systemctl status fail2ban 顯示服務是 active,/etc/fail2ban/jail.local 也設好了 [sshd],但就是沒擋任何人,或是直接啟動失敗。這篇 fail2ban 教學會從這個坑開始講起,一次把新版 Linux 上的正確設定方式和除錯流程講清楚。

fail2ban 在做什麼,以及它不能做什麼

fail2ban 的運作原理不複雜:它盯著日誌檔(或 systemd journal),用正規表示式比對登入失敗的訊息,超過閾值就呼叫 iptables 或 nftables 把對方 IP 封掉一段時間。

釐清幾個常見誤解:

  • 它不是防火牆。 它是個 log 監控工具,真正擋人的是防火牆(iptables / nftables / firewalld / ufw)。
  • 它擋不了 DDoS。 封 IP 這種機制面對殭屍網路的分散式攻擊完全無效。
  • 如果你已經關掉密碼登入、只開 SSH Key,fail2ban 對 SSH 的防護價值會大幅下降——因為沒有密碼可以試錯了。但它對 Web 應用(WordPress 登入頁、API 等)仍然有用。

結論是:fail2ban 是縱深防禦的一環,不是銀彈。如果你還沒把 SSH Key 設好,建議先看我們另一篇 SSH Key 設定教學,再回頭看這篇。

安裝 fail2ban

以 Ubuntu / Debian 為例(這是台灣 VPS 最常見的系統):

1
2
sudo apt update
sudo apt install fail2ban -y

RHEL / Rocky / AlmaLinux 系:

1
2
sudo dnf install epel-release -y
sudo dnf install fail2ban -y

裝完後確認版本:

1
fail2ban-client --version

現在 Ubuntu 22.04 倉庫的版本是 0.11.2,24.04 是 1.0.2,Debian 12 也是 1.0.2。接下來的設定以 1.0+ 為準。

第一個坑:backend = auto 在新版 Ubuntu 會直接失敗

這是最多人踩的坑,也是多數中文教學沒寫的:Ubuntu 22.04 開始,預設安裝不含 rsyslog,系統日誌全部走 systemd journal,/var/log/auth.log 這個檔案根本不存在。

而 fail2ban 在 Debian/Ubuntu 的套件包裡,sshd jail 的 backend 預設是 auto——它會先去找 /var/log/auth.log,找不到就放棄,不會自動切到 systemd。這導致的結果是:

1
fail2ban ERROR Failed during configuration: Have not found any log file for sshd jail

或更陰險的狀況:服務看起來正常啟動了,但 fail2ban-client status sshd 告訴你 File list: 是空的,封鎖永遠不會觸發。

解決方法有兩種。推薦第二種:

方法一:安裝 rsyslog(不推薦)

1
sudo apt install rsyslog -y

這會讓 /var/log/auth.log 出現,相容舊教學。但多一個 daemon、多一份日誌重複寫入,在小 VPS 上純屬浪費資源。

方法二:明確把 backend 指定為 systemd(推薦)

建立 /etc/fail2ban/jail.local從零開始寫(不要整份複製 jail.conf,那份檔案 600 多行,改起來地雷一堆):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[DEFAULT]
# 忽略名單:你自己的 IP、辦公室 IP 要放進來,否則有天你會把自己鎖在外面
ignoreip = 127.0.0.1/8 ::1 203.0.113.5

# 封鎖時間(支援 s/m/h/d/w,負數代表永久)
bantime = 1h

# 在 findtime 時間內失敗超過 maxretry 次就封鎖
findtime = 10m
maxretry = 5

# 關鍵設定:強制使用 systemd journal
backend = systemd

# IPv6 也要封
allowipv6 = auto

[sshd]
enabled = true
port = ssh

然後重啟:

1
2
sudo systemctl restart fail2ban
sudo systemctl enable fail2ban

驗證有沒有真的跑起來

照教學敲完指令不代表有效,驗證是獨立的一步。

檢查服務狀態:

1
sudo systemctl status fail2ban

看到 active (running) 只是最低標準,不代表 jail 有真的在跑。

檢查 jail 狀態:

1
sudo fail2ban-client status

應該看到:

1
2
3
Status
|- Number of jail: 1
`- Jail list: sshd

檢查 sshd jail 細節:

1
sudo fail2ban-client status sshd

關鍵要看 Journal matches: 有沒有內容(用 systemd backend 時)或 File list: 有沒有檔案(用 auto/polling backend 時)。如果兩個都空的,代表沒在監控任何東西,設定沒生效。

做一次實戰測試:

最直接的驗證是故意讓自己被鎖(當然要先把你的主要 IP 加到 ignoreip)。從另一個不在白名單的 IP(比如手機熱點)連 SSH,故意打錯密碼幾次,然後在伺服器上:

1
sudo fail2ban-client status sshd

你會看到 Banned IP list: 出現那個 IP。要解除封鎖:

1
sudo fail2ban-client set sshd unbanip 1.2.3.4

第二個坑:filter 正則沒匹配到日誌

有時候 jail 跑起來了、日誌也有失敗訊息,但就是不封鎖。這代表 filter 的正規表示式沒比對到你的日誌格式。原因可能是:

  • 你用的 SSH daemon 版本太新或太舊
  • 你改過 sshd 的 log format
  • 某些雲端商的 image 把 log 格式客製化了

這時候拿出 fail2ban 最強的除錯工具 fail2ban-regex

1
2
3
4
5
# 用 systemd journal 測試
sudo fail2ban-regex "systemd-journal[journalflags=1]" /etc/fail2ban/filter.d/sshd.conf

# 或用檔案測試
sudo fail2ban-regex /var/log/auth.log /etc/fail2ban/filter.d/sshd.conf

輸出會告訴你總共掃了幾行、匹配到幾行、哪些規則被觸發。如果匹配數是 0 但你明明看得到登入失敗,那就是 filter 的問題,可以考慮切換 mode

1
2
3
[sshd]
enabled = true
mode = aggressive

aggressive 模式會匹配更多種失敗樣態(包含無效使用者、協議錯誤等),代價是誤判率稍高。

調整封鎖策略,反制慣犯

預設 1 小時封鎖對殭屍網路沒什麼嚇阻力——它會換 IP 繼續試,或等你解封後回來。fail2ban 有個好用的機制叫 recidive jail(慣犯監獄),專門盯已經被封過的 IP,累犯就重罰:

jail.local 加上:

1
2
3
4
5
6
[recidive]
enabled = true
logpath = /var/log/fail2ban.log
bantime = 1w
findtime = 1d
maxretry = 3

意思是:一天內被任何 jail 封鎖超過 3 次的 IP,直接封一週。

另外可以開啟 遞增封鎖時間,讓每次累犯的封鎖時間翻倍:

1
2
3
4
[DEFAULT]
bantime.increment = true
bantime.factor = 2
bantime.maxtime = 30d

白名單的正確用法

ignoreip 千萬要設好,尤其是:

  • 你自己常用的 IP(家裡 + 公司 + 手機熱點常見網段)
  • 監控系統的來源 IP(如果你有 uptime 監控服務)
  • CDN 的 IP 段(如果 Web jail 開了而且網站在 CDN 後面)

如果你是從動態 IP 環境連線(台灣的家用寬頻常見),與其把 IP 寫死,更好的做法是改用 SSH Key + 關閉密碼登入,讓 fail2ban 變成備援,而不是主要防線。

常用指令速查

整理一份實務上最常用的指令:

指令 用途
fail2ban-client status 列出所有啟用中的 jail
fail2ban-client status sshd 看 sshd jail 細節(失敗次數、被封 IP)
fail2ban-client set sshd unbanip 1.2.3.4 手動解封 IP
fail2ban-client set sshd banip 1.2.3.4 手動封鎖 IP
fail2ban-client reload 重新載入設定(不中斷現有封鎖)
fail2ban-regex <log> <filter> 測試 filter 是否匹配
tail -f /var/log/fail2ban.log 即時觀察封鎖動作

結語:fail2ban 是低成本但容易誤設的工具

fail2ban 的價值在於它幾乎零成本——裝完、設好、就在背景默默工作,能擋掉絕大多數腳本小子的嘗試。但也正因為它的「看起來有效」很容易偽裝成真的有效,驗證這一步絕對不能省。

這篇文章列的三個重點——backend 要指定 systemd、要用 fail2ban-client status 驗證、要用 fail2ban-regex 除錯——是在 Ubuntu 22.04 之後架 VPS 務必掌握的。

如果你正在找一台可以穩定跑這套安全設定的台灣 VPS,NCSE Network 提供位於台北是方電訊機房的 VPS 服務,採用 Intel Xeon Gold CPU 與 NVMe SSD,網路延遲低、穩定度高,適合需要長時間運行伺服器服務的開發者與中小企業。歡迎到 NCSE Network 官網 了解方案細節,或到我們的 Discord 社群 交流伺服器架設經驗。

需要穩定的雲端主機?

NCSE Network 提供企業級 VPS,7 天免費試用,臺灣是方電訊機房,99% SLA 保證。

查看 VPS 方案 →