本篇介紹如何使用 Fail2ban 工具,阻擋網路攻擊、保護系統免於被入侵的風險。
任何處於公開網路環境的服務都會有遭遇到惡意程式攻擊的風險,以暴力法(brute-force)嘗試入侵系統就是一個常見的攻擊手法,如果系統上剛好有帳號與密碼的強度不足,就有被入侵的可能。
Fail2ban 是一個用來防止暴力法攻擊的防護工具,它會定期掃描系統的紀錄檔,尋找符合條件的網路攻擊來源,當次數達到門檻值的時候,就透過設置防火牆的方式暫時阻擋網路攻擊的來源 IP 位址,過了一段時間之後才會再度開放。
若在 Ubuntu Linux 中,可以使用 apt
安裝 Fail2ban:
# 安裝 fail2ban 套件
sudo apt install fail2ban
安裝完 fail2ban
套件之後,預設就會自動啟動 fail2ban
服務:
# 查看 fail2ban 服務
systemctl status fail2ban
● fail2ban.service - Fail2Ban Service Loaded: loaded (/lib/systemd/system/fail2ban.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2022-04-22 13:58:46 CST; 18s ago Docs: man:fail2ban(1) Main PID: 3682494 (f2b/server) Tasks: 5 (limit: 19106) Memory: 12.0M CGroup: /system.slice/fail2ban.service └─3682494 /usr/bin/python3 /usr/bin/fail2ban-server -xf start Apr 22 13:58:46 imgqc systemd[1]: Starting Fail2Ban Service... Apr 22 13:58:46 imgqc systemd[1]: Started Fail2Ban Service. Apr 22 13:58:46 imgqc fail2ban-server[3682494]: Server ready
Fail2ban 的設定檔位於 /etc/fail2ban/
目錄之下,可分為四大部分:
fail2ban.conf
與 fail2ban.d/*.conf
fail2ban
服務本身的基本設定。filter.d/*.conf
action.d/*.conf
jail.conf
與 jail.d/*.conf
各類的 *.conf
檔案都是伴隨 Fail2ban 發行的標準設定檔,在升級 Fail2ban 版本時可能會被新版的設定蓋過去,所以若需要修改其中的設定,建議寫在 *.local
設定檔中。例如若要修改 jail.conf
中的設定,可以將 jail.conf
複製為 jail.local
後再進行修改(或是僅在 jail.local
中加入需要變更的設定),*.local
中的設定會覆蓋掉 *.conf
中的設定。
jail.conf
設定在 jail.conf
中的設定分為多個區塊,[INCLUDES]
區塊指定要事先引入的其他設定檔路徑,[DEFAULT]
區塊中的參數屬於全域性的預設設定值,在個別系統服務的 jail 設定區塊中(例如 [sshd]
)也可以覆蓋掉這些設定。
首先將 jail.conf
複製為 jail.local
:
# 複製 jail.conf 設定檔
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
然後編輯 jail.local
設定檔,調整自己所需要的設定值。以下是一些常用的參數設定與範例。
若要設定 IP 位址的白名單,可以修改 ignoreip
參數,ignoreip
的值可以是多個 IP 位址、CIDR 網段、DNS 主機名稱,各 IP 之間以空白分隔,例如:
# IP 位址白名單
ignoreip = 127.0.0.1/8 ::1 123.123.123.123 192.168.1.0/24
若需要動態指定 IP 位址白名單,可以使用 ignorecommand
參數指定檢查 IP 位址指令,該指令接受一個 IP 位址的參數,若傳回 0
則代表此 IP 位址在白名單內,若傳回 1
則代表此 IP 位址不在白名單內:
# 以指令檢查 IP 位址白名單
ignorecommand = /path/to/check_ip.sh <ip>
這裡的 <ip>
在執行指令之前會被替換為要進行檢查的 IP 位址,透過參數的方式傳入 check_ip.sh
指令稿。以下是一個簡單的 check_ip.sh
指令稿範例:
#!/usr/bin/bash # 取得傳入的 IP 位址 ip=$1 # 檢查 IP 位址是否為 192.168.21.80 if [ "$ip" == "192.168.21.80" ]; then # IP 位址在白名單內 exit 0 else # IP 位址不在白名單內 exit 1 fi
ignoreself
參數可指定是否要忽略本機自己的 IP 位址,預設值是 true
:
# 忽略本機自己的 IP 位址
ignoreself = true
bantime
參數可設定每一次阻擋攻擊來源的持續時間,預設是 10 分鐘(10m
),以下是一些設定範例:
# 阻擋持續時間為 10 分鐘 bantime = 10m # 阻擋持續時間為 2 小時 bantime = 2h # 阻擋持續時間為 1 天 bantime = 1d # 阻擋持續時間為 1 天 6 小時 30 分鐘 bantime = 1d6h30m
以下是所有可用的時間單位:
單位 | 說明 |
---|---|
s |
秒 |
m |
分鐘 |
h |
小時 |
d |
天 |
w |
週 |
mo |
月 |
y |
年 |
findtime
與 maxretry
參數是用來設定判定為惡意攻擊的門檻,findtime
是一段觀察時間,而 maxretry
則是錯誤次數(例如登入失敗次數),當發現在 findtime
所設定的時間區間內出現的錯誤次數達到 maxretry
的設定值,則判定為惡意攻擊,並進行阻擋。以下是一個設定範例:
# 若 10 分鐘內錯誤次數達 5 次,則進行阻擋
findtime = 10m
maxretry = 5
findtime
參數所採用的時間格式跟 bantime
相同。
filter
參數可以指定要採用的識別規則(filter)設定檔以及選用的模式(mode),預設會使用服務的名稱搭配預設的 normal
模式,這部分的設定在大部分的情況下不需要更動:
# 指定 filter 的模式 mode = normal # 以服務區塊名稱作為識別規則(filter)設定檔名稱 filter = %(__name__)s[mode=%(mode)s]
這裡的識別規則(filter)設定檔名稱就對應到 /etc/fail2ban/filter.d/
目錄之下的設定檔(不包含 .conf
)。以 sshd
這個例子來說,預設就會採用 /etc/fail2ban/filter.d/sshd.conf
這個設定檔中 normal
模式的識別規則。
Fail2ban 的 action 就是指當判定為惡意攻擊時,所要採取的動作,預設的 action
設定只會對攻擊來源 IP 進行阻擋,若要採取其他的動作,就可以修改這個參數。
若希望 Fail2ban 在阻擋攻擊來源的時候,可以一併發出含有 whois 報表的 email 通知,可以將 action
參數設定為 action_mw
:
# 阻擋來源,並發出含有 whois 報表的 email 通知信
action = %(action_mw)s
若將 action
設定為 action_mwl
,則可自動發出含有 whois 報表以及相關記錄的 email 通知信:
# 阻擋來源,並發出含有 whois 報表與相關記錄的 email 通知信
action = %(action_mwl)s
這些 action
相關設定的原始定義都在 jail.conf
設定檔中,若要設定 email 通知信的寄送信箱,可以參考原始定義並修改 destemail
參數。預設的 destemail
設定會讓 email 通知信寄送至本機的 root
管理者信箱:
# Email 通知信的寄送信箱
destemail = root@localhost
若要指定 email 通知信的寄件者,可以修改 sender
參數:
# Email 通知信的寄件者
sender = root@<fq-hostname>
除了以上兩種 action 組合之外,在 jail.conf
中還有其他許多種 action 組合可以選擇。
Fail2ban 的 jail 設定是用來指定要針對哪一些系統上的服務進行監控,並指定各服務所採用的篩選條件(filter)與動作(action),在預設的 jail.conf
設定檔中已經提供了各種常見服務的設定樣板,例如 sshd
、apache-auth
、nginx-http-auth
、openwebmail
、drupal-auth
等,而在預設的狀態下只有啟用 sshd
服務的監控。
在個別的服務區塊中,可以透過 enabled
參數來指定是否啟用,另外也可以指定個別服務專用的設定值,這裡的設定會覆蓋掉前面全域的設定值,以下是一個 sshd
的設定範例:
# 啟用 sshd 服務監控,並調整設定值
[sshd]
enabled = true
maxretry = 3
findtime = 1d
bantime = 4w
ignoreip = 127.0.0.1/8 12.34.56.78
調整完 Fail2ban 的設定之後,要重新啟動 fail2ban
服務才會讓新設定生效。
# 重新啟動 fail2ban 服務
sudo systemctl restart fail2ban
Fail2ban 的記錄檔預設放在 /var/log/fail2ban.log
,我們可以在這個記錄檔中查看有哪些 IP 位址被偵測、判定為異常攻擊,以及阻擋 IP 位址與解除阻擋的記錄。
Fail2ban 附帶了一個 fail2ban-client
工具,可以用來設定與操控 Fail2ban 系統服務,以下是常用的幾個操作指令。
fail2ban-client status
可以查看指定服務的 Fail2ban 狀態,包含採用的 filters 與 actions:
# 查看 sshd 服務的 fail2ban 狀態
sudo fail2ban-client status sshd
Status for the jail: sshd |- Filter | |- Currently failed: 7 | |- Total failed: 8657 | `- File list: /var/log/auth.log `- Actions |- Currently banned: 2 |- Total banned: 1387 `- Banned IP list: 188.166.35.32 61.177.173.36
在 Filter 中可以看到其採用的系統記錄檔,而 Actions 中則會列出目前被阻擋(列入黑名單)的 IP 位址清單。
若只要單純查詢被 Fail2ban 阻擋的 IP 位址清單,可以使用以下指令:
# 查詢被 Fail2ban 阻擋的 IP 位址清單
sudo fail2ban-client get sshd banip
若想查看各個 IP 位址被阻的的開始時間與預定解除時間,可以加上 --with-time
參數:
# 查詢被 Fail2ban 阻擋的 IP 位址清單(含時間) sudo fail2ban-client get sshd banip --with-time
188.166.35.32 2022-04-24 17:54:36 + 600 = 2022-04-24 18:04:36 61.177.173.36 2022-04-24 17:56:10 + 600 = 2022-04-24 18:06:10
被 Fail2ban 阻擋的 IP 位址會在 bantime
所設定的時間之後自動解除,若要提前開放特定的 IP 位址,可以使用以下指令:
# 解除 sshd 服務中阻擋的 IP 位址
sudo fail2ban-client set sshd unbanip 188.166.35.32
也可以一次開放多個 IP 位址:
# 解除 sshd 服務中阻擋的 IP 位址
sudo fail2ban-client set sshd unbanip 188.166.35.32 61.177.173.36
若要解除所有被 Fail2ban 阻擋的 IP 位址,可以加上 --all
參數:
# 解除 sshd 服務中所有阻擋的 IP 位址 sudo fail2ban-client set sshd unbanip --all
我們也可以手動將特定 IP 位址加入至 Fail2ban 的阻擋清單內:
# 在 sshd 服務中加入阻擋的 IP 位址
sudo fail2ban-client set sshd banip 188.166.35.32
亦可加入多組要進行阻擋的 IP 位址:
# 在 sshd 服務中加入阻擋的 IP 位址
sudo fail2ban-client set sshd banip 188.166.35.32 61.177.173.36
IP 位址白名單也可以透過 fail2ban-client
指令手動調整:
# 在 sshd 服務中加入白名單 IP 位址 sudo fail2ban-client set sshd addignoreip 192.168.1.2 # 在 sshd 服務中移除白名單 IP 位址 sudo fail2ban-client set sshd delignoreip 192.168.1.2
fail2ban-client
指令說明除了這幾個常用功能之外,fail2ban-client
還有非常多的功能,詳細的說明可以參考 fail2ban-client
指令的線上手冊或參數說明:
# 查詢 fail2ban-client 線上手冊 man fail2ban-client # 顯示 fail2ban-client 參數說明 fail2ban-client -h