CentOS 7 fail2ban + Firewalld 設定教學 – 防止 SSH 暴力登入、基礎 CC 防護
fail2ban 是一種入侵偵測系統 (IDS),以 Python 寫成,透過監控日誌檔案來封鎖惡意 IP 存取。fail2ban 內建許多過濾規則,我們也可以自己寫,功能十分強大。
如果您曾經看過 /var/log/secure
的記錄檔,應該會發現許多不速之客一直在暴力破解 SSH 的連線密碼,今天筆者要介紹如何使用 fail2ban 封鎖惡意 IP。CC (Challenge Collapsar) 是 DDoS 的一種,下面筆者也會談到如何使用 Cloudflare + Nginx + fail2ban 來實作 CC 防護。
筆者使用的防火牆是 Firewalld,此教學不適用於 iptables 哦!
安裝 fail2ban
請先安裝 EPEL Repository
$ yum install epel-release
接著安裝 fail2ban,其中應該會自動附帶安裝幾個 dependencies,分別為 fail2ban-server、fail2ban-firewalld 和 fail2ban-sendmail 等。沒錯,看到 sendmail 您應該猜到 fail2ban 支援傳送封鎖通知的電子郵件,筆者沒有開啟這個功能,因為封鎖的數量太多,信箱會被淹沒。
$ yum install fail2ban
fail2ban 的安裝目錄位於 /etc/fail2ban
中,jail.conf 是主要的設定檔,至於過濾相關規則位於 filter.d 資料夾中。
啟用 SSH 防護
注意,請不要直接對 .conf 設定檔進行修改,因為在更新後可能會被覆蓋,所以請自行建立 jail.local 檔案,其設定值會自動覆蓋到 jail.conf 中,因此只修要填寫您要修改的項目就好。
在網路上可以搜尋到的教學中,有些將全部設定值列出,顯得很繁瑣,筆者看了一下很多選項其實都是預設值,不需要再寫一次,大概比較需要改的地方就只有幾個:
jail.local
在 /etc/fail2ban
建立 jail.local,請依據自己需求更改以下設定值,要修改更多設定請參照 jail.conf。
[DEFAULT]
# IP 白名單,可填 IP 或 CIDR,以空格隔開
# 建議您將自己的 IP 填上,否則測試時不小心 Ban 掉自己就麻煩了XD
# 預設 127.0.0.1/8
ignoreip = 127.0.0.1/8 xxx.xxx.xxx.xxx
# 封鎖時長,預設 600 秒
bantime = 86400
# 預設在 600 秒內達到 maxretry 的次數就封鎖
findtime = 600
# 預設是 5 次
maxretry = 3
[sshd]
# 啟用 SSH 防護
enabled = true
設定完成後即可啟動 fail2ban。
systemctl start fail2ban
接下來您可以參考文末提供的一些常用指令確認其是否有正確執行。
Cloudflare + Nginx + fail2ban 實作 Challenge Collapsar 防護
測試看看就好,請不要用於正式環境!
這個算是實驗性的設定,因為有很多變因會導致問題,例如網站若沒有快取,載入大量資源時 Request 過多可能會封鎖掉正常使用者。
真正發現有人在攻擊時,直接使用 Cloudflare 的「5 秒盾」比較實在一些。 開啟 [Firewall] => 右邊 [Settings] => [Security Level] => 選擇 [I'm Under Attack]
設定檔參考自 HostLoc 一位大佬寫的【教程】CloudFlare + Fail2ban 實現入門級 CC 防禦。
jail.local
此設定的重點在於 findtime 與 maxretry 的配合,每個網站適合的值都不太一樣,所以筆者才會建議除非您真的很清楚自己網站的運作,否則不要使用在正式環境當中。
# 接續上面的設定
[nginx-cc]
enabled = true
filter = nginx-cc
action = cloudflare-api
logpath = /網站記錄檔路徑/example.com.log
findtime = 60
maxretry = 60
bantime = 3600
nginx-cc.conf
在 /etc/fail2ban/filter.d
資料夾中建立此檔案。
[Definition]
failregex = <HOST> -.*- .*HTTP/[123].* .* .*$
ignoreregex =
cloudflare-api.conf
在 /etc/fail2ban/action.d
資料夾中建立此檔案。這邊不使用官方提供的 cloudflare.conf,因為筆者在部署的過程中有一些 Bug。
[Definition]
actionstart =
actionstop =
actioncheck =
actionban = curl -s -X POST "https://api.cloudflare.com/client/v4/zones/<cfzoneid>/firewall/access_rules/rules" \
-H "X-Auth-Email: <cfuser>" \
-H "X-Auth-Key: <cftoken>" \
-H "Content-Type: application/json" \
--data '{"mode":"block","configuration":{"target":"ip","value":"<ip>"},"notes":"CC Attack"}'
actionunban = curl -s -X DELETE "https://api.cloudflare.com/client/v4/zones/<cfzoneid>/firewall/access_rules/rules/$( \
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/<cfzoneid>/firewall/access_rules/rules?page=1&per_page=1&mode=block&configuration.target=ip&configuration.value=<ip>&match=all" \
-H "X-Auth-Email: <cfuser>" \
-H "X-Auth-Key: <cftoken>" \
-H "Content-Type: application/json" | awk -F "[,:}]" '{for(i=1;i<=NF;i++){if($i~/'id'\042/){print $(i+1);}}}' | tr -d '"' | sed -e 's/^[ \t]*//' | head -n 1)" \
-H "X-Auth-Email: <cfuser>" \
-H "X-Auth-Key: <cftoken>" \
-H "Content-Type: application/json"
[Init]
name = default
# 上面的內容不需要修改,只需要改下面三行
cfuser = Cloudflare 帳號的電子郵件
cftoken = 在 [My Profile] => [API Tokens] => [Global API Key]
cfzoneid = [您的域名] => [Overview] => [Zone ID]
常用指令
啟動 fail2ban
$ systemctl start fail2ban
停止 fail2ban
$ systemctl stop fail2ban
重啟 fail2ban
$ systemctl restart fail2ban
檢查 fail2ban 是否正常運作
$ fail2ban-client ping
正常的話會回應:
Server replied: pong
重新載入並套用設定檔
$ fail2ban-client reload
顯示所有套用的設定值
$ fail2ban-client -d
顯示 fail2ban 的所有規則統計
$ fail2ban-client status
Status
|- Number of jail: 1
`- Jail list: sshd
顯示已封鎖的 IP 統計
$ fail2ban-client status sshd
$ fail2ban-client status nginx-cc
顯示已封鎖的 IP (SSH) 與剩餘解封時間
$ ipset list fail2ban-sshd
顯示封鎖規則
$ firewall-cmd --direct --get-all-rules
ipv4 filter INPUT 0 -p tcp -m multiport --dports ssh -m set --match-set fail2ban-sshd src -j REJECT --reject-with icmp-port-unreachable
取消封鎖指定 IP
$ fail2ban-client set sshd unbanip xxx.xxx.xxx.xxx
$ fail2ban-client set nginx-cc unbanip xxx.xxx.xxx.xxx
本文由作者 Chiahong 發表於 iBe 隨筆,歡迎分享,如需引用時請註明來源,感謝您!