Fail2ban 簡介
Fail2ban 是一款開源的入侵防護軟體,專門用於保護 Linux 伺服器免受暴力破解攻擊。它透過監控系統日誌檔案,偵測重複失敗的登入嘗試或其他可疑行為,並自動將攻擊者的 IP 位址加入防火牆封鎖清單。
主要功能
- 自動封鎖:偵測到惡意行為後自動封鎖攻擊者 IP
- 多服務支援:支援 SSH、Apache、Nginx、Postfix 等多種服務
- 彈性設定:可自訂封鎖時間、重試次數等參數
- 日誌監控:即時監控系統日誌檔案
- 通知功能:可設定郵件通知管理員
運作原理
Fail2ban 的工作流程如下:
- 持續監控指定的日誌檔案
- 使用正規表達式比對失敗的登入模式
- 當失敗次數達到閾值時觸發封鎖動作
- 透過 iptables 或 firewalld 封鎖攻擊者 IP
- 封鎖時間結束後自動解除封鎖
安裝與設定
系統需求
- Ubuntu 22.04 LTS
- 具有 sudo 權限的使用者帳號
- 已啟用防火牆(iptables 或 firewalld)
安裝 Fail2ban
更新套件庫並安裝 Fail2ban:
1
2
| sudo apt update
sudo apt install fail2ban -y
|
檢查服務狀態
安裝完成後,檢查 Fail2ban 服務狀態:
1
| sudo systemctl status fail2ban
|
設定開機自動啟動
確保 Fail2ban 在系統開機時自動啟動:
1
| sudo systemctl enable fail2ban
|
設定檔結構
Fail2ban 的設定檔位於 /etc/fail2ban/ 目錄下:
| 檔案/目錄 | 說明 |
|---|
fail2ban.conf | 主要設定檔(不建議直接修改) |
jail.conf | 預設 Jail 設定(不建議直接修改) |
jail.local | 自訂 Jail 設定(覆蓋預設值) |
jail.d/ | 額外的 Jail 設定目錄 |
filter.d/ | 過濾器規則目錄 |
action.d/ | 動作腳本目錄 |
建立本地設定檔
建立 jail.local 來覆寫預設設定:
1
| sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
|
Jail 設定
Jail 是 Fail2ban 的核心概念,每個 Jail 負責監控一個特定服務。
基本 Jail 設定
編輯 /etc/fail2ban/jail.local 檔案:
1
| sudo nano /etc/fail2ban/jail.local
|
全域設定
在 [DEFAULT] 區塊中設定全域參數:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| [DEFAULT]
# 忽略的 IP 位址(白名單)
ignoreip = 127.0.0.1/8 ::1 192.168.1.0/24
# 封鎖時間(秒),-1 表示永久封鎖
bantime = 3600
# 偵測時間範圍(秒)
findtime = 600
# 最大重試次數
maxretry = 5
# 封鎖動作
banaction = iptables-multiport
# 通知郵件設定
destemail = admin@example.com
sender = fail2ban@example.com
mta = sendmail
# 動作類型
action = %(action_mwl)s
|
SSH Jail 設定
保護 SSH 服務的 Jail 設定:
1
2
3
4
5
6
7
8
| [sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 86400
findtime = 600
|
Nginx Jail 設定
保護 Nginx 的 Jail 設定範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| # Nginx 認證失敗
[nginx-http-auth]
enabled = true
port = http,https
filter = nginx-http-auth
logpath = /var/log/nginx/error.log
maxretry = 5
# Nginx 惡意請求
[nginx-botsearch]
enabled = true
port = http,https
filter = nginx-botsearch
logpath = /var/log/nginx/access.log
maxretry = 2
|
Apache Jail 設定
保護 Apache 的 Jail 設定範例:
1
2
3
4
5
6
7
8
9
10
11
12
13
| [apache-auth]
enabled = true
port = http,https
filter = apache-auth
logpath = /var/log/apache2/error.log
maxretry = 5
[apache-badbots]
enabled = true
port = http,https
filter = apache-badbots
logpath = /var/log/apache2/access.log
maxretry = 2
|
套用設定
修改設定後,重新啟動 Fail2ban:
1
| sudo systemctl restart fail2ban
|
自訂規則
建立自訂過濾器
過濾器定義了如何從日誌中識別攻擊行為。
建立自訂過濾器檔案:
1
| sudo nano /etc/fail2ban/filter.d/custom-filter.conf
|
過濾器範例:
1
2
3
4
5
6
7
| [Definition]
# 失敗的正規表達式
failregex = ^<HOST> -.*"(GET|POST).*HTTP.*" 403
^<HOST> -.*"(GET|POST).*HTTP.*" 404
# 忽略的正規表達式
ignoreregex =
|
建立自訂 Jail
在 /etc/fail2ban/jail.local 中新增自訂 Jail:
1
2
3
4
5
6
7
8
| [custom-service]
enabled = true
port = http,https
filter = custom-filter
logpath = /var/log/custom-app/access.log
maxretry = 10
bantime = 7200
findtime = 3600
|
測試過濾器規則
使用 fail2ban-regex 測試過濾器:
1
2
3
4
5
| # 測試單行
sudo fail2ban-regex "192.168.1.100 - - [22/Nov/2023:10:00:00] GET /admin HTTP/1.1 403" /etc/fail2ban/filter.d/custom-filter.conf
# 測試日誌檔案
sudo fail2ban-regex /var/log/nginx/access.log /etc/fail2ban/filter.d/custom-filter.conf
|
進階過濾器語法
使用更複雜的正規表達式:
1
2
3
4
5
6
7
8
9
10
| [Definition]
# 定義變數
_daemon = myapp
# 使用變數的正規表達式
failregex = ^%(__prefix_line)sAuthentication failure for .* from <HOST>
^%(__prefix_line)sInvalid user .* from <HOST>
# 日期格式(如果非標準格式)
datepattern = %%Y-%%m-%%d %%H:%%M:%%S
|
日誌與管理
檢視 Fail2ban 狀態
查看整體狀態:
1
| sudo fail2ban-client status
|
輸出範例:
1
2
3
| Status
|- Number of jail: 2
`- Jail list: nginx-http-auth, sshd
|
查看特定 Jail 狀態:
1
| sudo fail2ban-client status sshd
|
輸出範例:
1
2
3
4
5
6
7
8
9
| Status for the jail: sshd
|- Filter
| |- Currently failed: 3
| |- Total failed: 127
| `- File list: /var/log/auth.log
`- Actions
|- Currently banned: 2
|- Total banned: 45
`- Banned IP list: 192.168.1.100 10.0.0.50
|
手動管理封鎖
手動封鎖 IP:
1
| sudo fail2ban-client set sshd banip 192.168.1.100
|
手動解除封鎖:
1
| sudo fail2ban-client set sshd unbanip 192.168.1.100
|
檢視日誌
查看 Fail2ban 日誌:
1
| sudo tail -f /var/log/fail2ban.log
|
搜尋特定 IP 的封鎖記錄:
1
| sudo grep "192.168.1.100" /var/log/fail2ban.log
|
常用管理指令
| 指令 | 說明 |
|---|
fail2ban-client status | 顯示所有 Jail 狀態 |
fail2ban-client status <jail> | 顯示特定 Jail 狀態 |
fail2ban-client set <jail> banip <ip> | 手動封鎖 IP |
fail2ban-client set <jail> unbanip <ip> | 手動解除封鎖 |
fail2ban-client reload | 重新載入設定 |
fail2ban-client restart | 重新啟動服務 |
fail2ban-client get <jail> bantime | 取得封鎖時間設定 |
fail2ban-client get <jail> maxretry | 取得最大重試次數 |
設定日誌輪替
確保日誌檔案不會無限增長,編輯 /etc/logrotate.d/fail2ban:
1
2
3
4
5
6
7
8
9
10
11
| /var/log/fail2ban.log {
weekly
rotate 4
compress
delaycompress
missingok
postrotate
fail2ban-client flushlogs 1>/dev/null
endscript
create 640 root adm
}
|
監控與告警
設定郵件通知,在 jail.local 中加入:
1
2
3
4
5
| [DEFAULT]
destemail = admin@example.com
sender = fail2ban@hostname.com
mta = sendmail
action = %(action_mwl)s
|
動作類型說明:
action_: 僅封鎖action_mw: 封鎖並發送含有 whois 資訊的郵件action_mwl: 封鎖並發送含有 whois 資訊及相關日誌的郵件
總結
Fail2ban 是保護 Linux 伺服器的重要工具,透過本文的設定,您可以:
- 有效阻擋 SSH 暴力破解攻擊
- 保護 Web 服務免受惡意請求
- 建立自訂規則以適應特定需求
- 透過日誌監控掌握安全狀況
建議定期檢查 Fail2ban 日誌,並根據實際攻擊模式調整設定,以達到最佳的防護效果。
參考資源