前言
Cloudflare 的防火牆規則在流量到達您的網站主機之前就會執行,這樣能減少主機負載並提高安全性。
實做:設定 Cloudflare 防火牆規則,建立 IP 存取白名單,只允許指定的 IP 位址可以存取 WordPress 後台頁面,並阻擋其他所有 IP 的存取請求。
在網站安全領域中,保護 WordPress 後台是至關重要的環節,隨著網路攻擊手法日益複雜,單純依靠帳號密碼已無法提供足夠的安全性,透過 Cloudflare 強大的 WAF(Web Application Firewall)功能,可以實現 IP 位址白名單機制,確保只有授權的 IP 位址能夠存取 WordPress 管理介面,有效阻擋潛在的惡意登入嘗試。
本教學將說明如何利用 Cloudflare 防火牆設定 IP 存取限制,並分享如何處理動態 IP 的情況,讓您即使在不同的網路環境下,也能安全的管理網站,提升 WordPress 網站的安全防護水平。
Cloudflare WAF 防火牆功能
Cloudflare WAF (Web Application Firewall) 是一個網站應用程式防火牆,提供以下的功能:
- 全方位威脅防護
- 即時監控:持續監控網站流量,快速識別並阻擋可疑活動。
- DDoS 防護:自動偵測並防禦分散式阻斷服務攻擊,確保網站可用性。
- 進階過濾:防護 SQL 注入、XSS 跨站腳本等常見網路攻擊。
- 智慧防護機制
- 機器學習:透過進階演算法自動識別異常流量模式。
- 威脅情報:結合全球資安情報,提供即時的威脅預警。
- 自動更新:防護規則持續更新,應對最新的安全威脅。
- 精確的存取控制
- IP 規則:支援白名單和黑名單,精確控制 IP 存取權限。
- 地理限制:可根據來源國家或地區進行存取控制。
- 請求管理:設定速率限制,防止暴力破解攻擊。
- 完整的管理功能
- 統一介面:透過單一控制台管理所有安全設定。
- 即時部署:安全規則更新可立即生效。
- 安全報告:提供詳細的威脅分析與事件記錄。
適合使用 Cloudflare WAF 的情境
- 需要全方位的網站安全防護,包括 DDoS 防護、SQL 注入和 XSS 跨站腳本等常見攻擊的防禦。
- 希望透過即時監控功能快速識別並阻擋可疑活動。
- 需要精確的 IP 存取控制,可以設定白名單和黑名單。
- 需要根據地理位置限制網站存取。
- 希望透過速率限制功能來防止暴力破解攻擊。
- 需要集中管理安全設定,並獲取詳細的威脅分析與事件記錄。
WordPress 後台防護機制
- 後台存取控制
- IP 白名單限制:透過精確的 IP 存取控制,限制只有指定的 IP 位址能夠連線後台。(使用:Cloudflare WAF 防火牆)
- 進階帳戶管理:禁用預設管理員帳號(admin),建立新帳號並使用高強度密碼。
- 登入保護機制:部署登入嘗試限制,防止暴力破解攻擊。(外掛:Login LockDown)
- 智慧防護系統
- 雙重驗證:實施雙因素認證,提供額外的安全防護層。(外掛:Two Factor Authentication)
- 自動監控:持續監控可疑的登入活動,及時發現潛在威脅。
- 進階安全設定:部署全面的安全措施,確保後台管理介面的安全性。(外掛:Wordfence Security)
- 具體操作建議
- 定期安全稽核:定期檢查並更新安全設定,確保防護機制始終有效。
- 即時更新維護:保持系統和外掛的即時更新,修補潛在的安全漏洞。
- 安全備份機制:建立完整的備份策略,確保資料安全性。(外掛:UpdraftPlus)
Cloudflare WAF 設定方法
設定 Cloudflare 防火牆規則,建立 IP 存取白名單,只允許指定的 IP 位址可以存取 WordPress 後台頁面,並阻擋其他所有 IP 的存取請求。
- 點選左側的「網站」,再點選右側的域名
- 點選左側的「網路安全」→「WAF」,再點選右側的「自訂規則」→「建立規則」
-
規則名稱:WordPress後台允許IP
在「欄位、運算子、值」輸入下列內容:
IP 來源位址(IP Source Address)、不在於(is not in):允許的IP位址 → 及(And)
URI 路徑(URI Path)、包含(contains):/wp-admin → 或(Or)
IP 來源位址(IP Source Address)、不在於(is not in):允許的IP位址 → 及(And)
URI 路徑(URI Path)、包含(contains):/wp-login.php
備註:允許的IP位址(可以是一個 IP 或一個 CIDR 區域,如 192.168.1.1 或 192.168.1.0/24 )
運算式:
(not ip.src in {114.25.180.188} and http.request.uri.path contains “/wp-admin”) or (not ip.src in {114.25.180.188} and http.request.uri contains “/wp-login.php”)
選擇動作:封鎖,再點選下方的「部署」
- 名稱為「WordPress後台允許IP」的規則,右方出現「已啟用」的狀態代表設定完成
- 若您的 IP 位址不在白名單內,瀏覽 WordPress 後台的網址就會出現存取被拒的訊息!
https://bugtest.us.kg/wp-admin
https://bugtest.us.kg/wp-login.php
Cloudflare WAF 規則更新方法
Cloudflare DDNS – 動態 IP 自動對應網址
Cloudflare DDNS 是一種技術,讓使用者能夠將變動的動態 IP 地址與域名保持一致,無需手動更改 DNS 記錄,從而確保服務的持續可用性,特別適合那些無法獲得固定 IP 的場景,如家庭網路、監控設備或一些小型企業。
使用 Cloudflare API 實現更新 Cloudflare WAF 規則
在許多情境下,動態 IP 地址可能會影響設備或網站的連線穩定性。為了解決這個問題,我們可以利用 Cloudflare DDNS (動態域名系統),通過 Cloudflare API 來自動更新 Cloudflare WAF 規則,讓允許的 IP 位址始終指向正確的動態 IP。
建置步驟
- 獲取 API Token
點選右上角的人員圖示,再點選「我的設定檔」(My Profile)
點選左邊「API 權杖」(API Token),再點選右邊的「建立 Token」(Create Token)
點選「編輯區域 DNS」(Edit zone DNS) 右方的「使用範本」(Use template)
設定 Token 最小權限範圍
權限(Permissions):區域(Zone) / DNS / 編輯(Edit)、區域(Zone) / 防火牆服務(Firewall Services) / 編輯(Edit)
區域資源(Zone Resources):包含(Include) / 特定區域(Specific zone) / 您的域名(Domain)
設定完成後點選「繼續至摘要」(Continue to summary)
獲取 API Token
點選「Copy」複製 Token,下方是 curl 命令,可以進行 API 測試
Cloudflare API 呼叫測試
◆ Bearer 後方的字串 → 您的 API Token
如果呼叫成功會收到 JSON Success response
API Token:L01u13czcFZ8Wd2_3cWmxxex0qZXTKPEymW_6w8Tcurl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \ -H "Authorization: Bearer L01u13czcFZ8Wd2_3cWmxxex0qZXTKPEymW_6w8T" \ -H "Content-Type:application/json" | python -m json.tool
- 獲取 ZoneID
◆ Bearer 後方的字串 → 您的 API Token
如果呼叫成功會收到 ZoneID,找到 name 是您域名 bugtest.us.kg 的 id
ZoneID:d95801613008c8b6d131a3ff72d7e4becurl -X GET "https://api.cloudflare.com/client/v4/zones" \ -H "Authorization: Bearer L01u13czcFZ8Wd2_3cWmxxex0qZXTKPEymW_6w8T" \ -H "Content-Type:application/json" | python -m json.tool
- 獲取 WAF RuleID、FilterID
◆ zones/ 後方的字串 → 您的 ZoneID
◆ Bearer 後方的字串 → 您的 API Token
如果呼叫成功會收到 WAF RuleID、FilterID,找到 description 是您防火牆規則名稱的 id
WAF RuleID:9e435f4989aa48ac91bd6382062a4748
FilterID:52f145c6d35d432db8c90ceb66ea2ffd
curl -s -X GET "https://api.cloudflare.com/client/v4/zones/d95801613008c8b6d131a3ff72d7e4be/firewall/rules" \ -H "Authorization: Bearer L01u13czcFZ8Wd2_3cWmxxex0qZXTKPEymW_6w8T" \ -H "Content-Type: application/json" | python -m json.tool
- 使用 Cloudflare API 更新 Web Application Firewall (WAF) 防火牆規則
◆ zones/ 後方的字串 → 您的 ZoneID:d95801613008c8b6d131a3ff72d7e4be
◆ filters/ 後方的字串 → 您的 FilterID:52f145c6d35d432db8c90ceb66ea2ffd
◆ Bearer 後方的字串 → 您的 API Token:L01u13czcFZ8Wd2_3cWmxxex0qZXTKPEymW_6w8T
◆ –data id 後方的字串 → 您的 FilterID:52f145c6d35d432db8c90ceb66ea2ffd
◆ expression 後方的字串 → 您的防火牆規則運算式:
(not ip.src in {114.25.180.188 114.25.180.180 } and http.request.uri.path contains “/wp-admin”) or (not ip.src in {114.25.180.188 114.25.180.180 } and http.request.uri contains “/wp-login.php”)
透過下面的命令更新防火牆規則curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/d95801613008c8b6d131a3ff72d7e4be/filters/52f145c6d35d432db8c90ceb66ea2ffd" \ -H "Authorization: Bearer L01u13czcFZ8Wd2_3cWmxxex0qZXTKPEymW_6w8T" \ -H "Content-Type: application/json" \ --data '{"id": "52f145c6d35d432db8c90ceb66ea2ffd", "expression": "(not ip.src in {114.25.180.188 114.25.180.180 } and http.request.uri.path contains \"/wp-admin\") or (not ip.src in {114.25.180.188 114.25.180.180 } and http.request.uri.path contains \"/wp-login.php\")", "paused": false }' \ | python -m json.tool
自動更新防火牆規則腳本
使用 Cloudflare API 自動更新 WAF 規則內主機動態 IP 的腳本
透過 Shell Script 利用 Crontab 排程執行,就可以自動更新 WAF 防火牆規則內 主機的動態 IP,實現自動化的 Cloudflare WAF 功能。
- 自動更新 IP 腳本
cf-waf-wp.sh
#!/bin/bash # 設定變數 CF_TOKEN="L01u13czcFZ8Wd2_3cWmxxex0qZXTKPEymW_6w8T" # Cloudflare API Token CF_ZONE_ID="d95801613008c8b6d131a3ff72d7e4be" # Cloudflare ZoneID CF_WAF_RULE_ID="9e435f4989aa48ac91bd6382062a4748" # Cloudflare WAF RuleID CF_FILTER_ID="52f145c6d35d432db8c90ceb66ea2ffd" # Cloudflare FilterID # 固定 IP 清單(可以是一個或多個) # STATIC_IPS=("110.20.100.101" "110.20.100.102") STATIC_IPS=("110.20.100.101") # 公網 IP 查詢 API 端點 IP_SOURCE="https://api.ipify.org?format=json" # 取得浮動 IP DYNAMIC_IP=$(curl -s "$IP_SOURCE" | jq -r '.ip') if [ -z "$DYNAMIC_IP" ]; then echo "Failed to fetch dynamic IP address." # 無法取得浮動 IP exit 1 fi # 合併(固定 IP)與(浮動 IP) ALL_IPS=$(printf "%s\n" "${STATIC_IPS[@]}" "$DYNAMIC_IP" | sort -u | tr '\n' ' ') UPDATED_EXPRESSION="(not ip.src in {${ALL_IPS}} and http.request.uri.path contains \"/wp-admin\") or (not ip.src in {${ALL_IPS}} and http.request.uri.path contains \"/wp-login.php\")" # 取得現有的 WAF 規則 EXISTING_RULE=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/firewall/rules/${CF_WAF_RULE_ID}" \ -H "Authorization: Bearer ${CF_TOKEN}" \ -H "Content-Type: application/json") # 確認是否成功取得規則 if ! echo "$EXISTING_RULE" | jq -e '.success' >/dev/null; then echo "Failed to fetch existing WAF rule." # 無法取得 WAF 規則 echo "$EXISTING_RULE" exit 1 fi # 提取過濾器 ID 和目前的運算式 # (not ip.src in {10.20.100.101 114.25.180.188} and http.request.uri.path contains "/wp-admin") or (not ip.src in {10.20.100.101 114.25.180.188} and http.request.uri.path contains "/wp-login.php") FILTER_ID=$(echo "$EXISTING_RULE" | jq -r '.result.filter.id') CURRENT_EXPRESSION=$(echo "$EXISTING_RULE" | jq -r '.result.filter.expression') # 比較目前運算式與更新後的運算式 if [ "$CURRENT_EXPRESSION" == "$UPDATED_EXPRESSION" ]; then echo "No changes detected in IP list. WAF rule update is not required." # IP 列表無變動,無需更新 WAF 規則 exit 0 else echo "Changes detected in IP list. Proceeding with WAF rule update." # IP 列表有變動,準備更新 WAF 規則 fi # 使用新運算式更新過濾器 FILTER_UPDATE_PAYLOAD=$(jq -n --arg id "$FILTER_ID" --arg expression "$UPDATED_EXPRESSION" '{ id: $id, expression: $expression, paused: false }') FILTER_UPDATE_RESPONSE=$(curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/${CF_ZONE_ID}/filters/${FILTER_ID}" \ -H "Authorization: Bearer ${CF_TOKEN}" \ -H "Content-Type: application/json" \ --data "$FILTER_UPDATE_PAYLOAD") # 檢查更新回應 if echo "$FILTER_UPDATE_RESPONSE" | jq -e '.success' >/dev/null; then echo "Filter updated successfully with new IP list." # 過濾器成功更新 else echo "Failed to update filter." # 更新過濾器失敗 echo "$FILTER_UPDATE_RESPONSE" exit 1 fi
變更檔案權限成可執行 ( cf-ddns-root.sh )
chmod +x cf-waf-wp.sh
- 排程 每30分鐘 執行腳本
sudo vim /etc/crontab
*/30 * * * * root /root/ddns/cf-waf-wp.sh >/dev/null 2>&1 &
結語
透過本教學,可以了解如何使用 Cloudflare WAF 實現 WordPress 後台的 IP 存取控制,不僅限制了未授權的存取,更提高了網站的整體安全性,另外也提供了處理動態 IP 的解決方案,透過 Cloudflare API 和自動化腳本,即使沒有固定 IP 位址,也能持續維持網站的安全防護機制。
這種安全措施能有效減少暴力破解攻擊的風險,保護您的網站不受惡意攻擊者的侵害,網站安全是一個持續進行的過程,建議要定期檢查防火牆規則的有效性,並結合其他安全措施如定期更新和安全備份,打造全方位的網站安全防護網,透過這些措施,您的 WordPress 網站將更加安全可靠。