本篇文章更新時間:2020/02/22
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
Fail2ban 是一套強大又簡單的防火牆工具,網路上教學或延伸應用也不少(意思是本文不會做太多介紹)。其中一個常討論的就是與 Cloudflare 的整合!
在「整合」之前要先提到的是:使用 Cloudflare 搭配 Fail2ban 的話會無效。
因為 Cloudflare 如果把請求流量代理化(Proxy模式),伺服器的請求紀錄來源 IP 都會是 Cloudflare 自己的,而 Fail2ban 封鎖是看這份紀錄,所以發生封鎖時,會把 Cloudflare 的代理機器人給封鎖,進而造成網站瀏覽出錯(Cloudflare 524 問題)。
要做到真正的封鎖(整合),一來要先反解析回原始請求方 IP 再來是把封鎖請求改在 Cloudflare 的防火牆功能上。
下方的 bash script 能抓回處理 Nginx 伺服器解析用的 Cloudflare IP 段,反解原始請求 IP。
#!/bin/bash
if [ -z "$(command -v curl)" ]; then
echo "####################################"
echo "Installing CURL"
echo "####################################"
apt-get update
apt-get install curl -y
fi
CURL_BIN=$(command -v curl)
CF_IPV4=$($CURL_BIN -sL https://www.cloudflare.com/ips-v4)
CF_IPV6=$($CURL_BIN -sL https://www.cloudflare.com/ips-v6)
echo '' > cloudflare.conf
echo "####################################"
echo "Adding Cloudflare IPv4"
echo "####################################"
for cf_ip4 in $CF_IPV4; do
echo "set_real_ip_from $cf_ip4;" >> cloudflare.conf
done
echo "####################################"
echo "Adding Cloudflare IPv6"
echo "####################################"
for cf_ip6 in $CF_IPV6; do
echo "set_real_ip_from $cf_ip6;" >> cloudflare.conf
done
echo 'real_ip_header CF-Connecting-IP;' >> cloudflare.conf
Gist: Link
這程式參考 nginx-cloudflare-real-ip 頁面並改簡化些,生成的 cloudflare.conf
可以自行調整對應輸出路徑,與掛上 Cronjob 定期跑更新。
這邊需要 Nginx 有安裝
http_realip_module
模組。
程式產生的清單能讓 Nginx 抓到真實 IP 寫回記錄檔案後(記得把這個設定檔案 include 進 server
的區塊中),就要來處理 Fail2ban 的「觸發事件」。
Fail2ban 安裝目錄下 action.d
資料夾放置了一份 cloudflare.conf
設定,其中 actionban
請確認是否為:
actionban = curl -s -o /dev/null -X POST -H 'X-Auth-Email: ' -H 'X-Auth-Key: ' \
-H 'Content-Type: application/json' -d '{ "mode": "block", "configuration": { "target": "ip", "value": "" } }' \
https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules
和調整 actionunban
為:
actionunban = curl -s -o /dev/null -X DELETE -H 'X-Auth-Email: ' -H 'X-Auth-Key: ' \
https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules/$(curl -s -X GET -H 'X-Auth-Email: ' -H 'X-Auth-Key: ' \
'https://api.cloudflare.com/client/v4/user/firewall/access_rules/rules?mode=block&configuration_target=ip&configuration_value=&page=1&per_page=1' | tr -d '\n' | cut -d'"' -f6)
並且設定下方 cftoken
為 Cloudflare Profile 中 API Tokens
分頁下方的 Global API Key
與 cfuser
設定為 Profile 中顯示的帳號信箱。
上述的這兩個方法分別會在觸發封鎖時把封鎖的 IP 透過請求 Cloudflare API 更新防火牆,解鎖時亦同。
由於 Cloudflare API 有改版,你安裝的 Fail2ban 版本可能會沒更新到最新請求的 API ,所以這邊才要確認。這版本至少 2020/02/22 測試過還有效果。
封鎖對應事件 cloudflare.conf
設定完後就可以補上網站的封鎖設定資料囉!
fail2ban/jail.local
檔案如下
[wordpress]
enabled = true
port = http,https
action = cloudflare
filter = wordpress-auth
logpath = /path/to/*.log
maxretry = 3
bantime = 43200
findtime = 300
fail2ban/filter.d/wordpress-auth.conf
檔案參考如下
[Definition]
failregex = ^.*POST.*(wp-login\.php|xmlrpc\.php).*
^.*POST.*404.*
^.*POST.*wp-content/plugin.*(php|js|jpg|png).*
^.*POST.*wp-content/theme.*(php|js|jpg|png).*
^.*POST.*wp-content/cache.*(php|js|jpg|png).*
^.*POST.*wp-content/upload.*(php|js|jpg|png).*
^.*POST.*wp-include/.*(php|js|jpg|png).*
都設定好後只需要 fail2ban-client reload
重新載入即可~ 這樣就可以啦!上述捕捉問題請求的規則可以自行發揮,和上 GitHub 找找一些組合應用的方法囉!(WordPress 外掛搭配的也有,但有些人沒看清楚文件還可能以為安裝起來就有用,但其實要處理的不只是這樣哦)
文末補充一個 Nginx 資安相關應用:nginx-ultimate-bad-bot-blocker 與 Fail2ban 沒關係,很純粹的透過更新封鎖清單來把壞東西直接拒絕請求,也是滿有意思的。
如果想透過 Cloudflare 防火牆直接把非台灣的後台請求流量封鎖還可以如下圖設定:
補了下方的指令,讓 Cloudflare 判斷請求和來源,不是台灣的 IP 請求後台相關連線就封鎖。
((http.request.uri.path contains "/xmlrpc.php") or (http.request.uri.path contains "/wp-login.php") or (http.request.uri.path contains "/wp-admin/" and not http.request.uri.path contains "/wp-admin/admin-ajax.php" and not http.request.uri.path contains " /wp-admin/theme-editor.php")) and ip.geoip.country ne "TW"
與 Fail2ban 過濾規則一樣,規則越嚴謹和豐富自然能阻止的可能也多了!