Ubuntu 22.04 Fail2ban 入侵防護設定

Fail2ban 簡介

Fail2ban 是一款開源的入侵防護軟體,專門用於保護 Linux 伺服器免受暴力破解攻擊。它透過監控系統日誌檔案,偵測重複失敗的登入嘗試或其他可疑行為,並自動將攻擊者的 IP 位址加入防火牆封鎖清單。

主要功能

  • 自動封鎖:偵測到惡意行為後自動封鎖攻擊者 IP
  • 多服務支援:支援 SSH、Apache、Nginx、Postfix 等多種服務
  • 彈性設定:可自訂封鎖時間、重試次數等參數
  • 日誌監控:即時監控系統日誌檔案
  • 通知功能:可設定郵件通知管理員

運作原理

Fail2ban 的工作流程如下:

  1. 持續監控指定的日誌檔案
  2. 使用正規表達式比對失敗的登入模式
  3. 當失敗次數達到閾值時觸發封鎖動作
  4. 透過 iptables 或 firewalld 封鎖攻擊者 IP
  5. 封鎖時間結束後自動解除封鎖

安裝與設定

系統需求

  • 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 伺服器的重要工具,透過本文的設定,您可以:

  1. 有效阻擋 SSH 暴力破解攻擊
  2. 保護 Web 服務免受惡意請求
  3. 建立自訂規則以適應特定需求
  4. 透過日誌監控掌握安全狀況

建議定期檢查 Fail2ban 日誌,並根據實際攻擊模式調整設定,以達到最佳的防護效果。

參考資源

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy