# 用 Claude Code + Cloudflare MCP 自動設定 WAF 防火牆規則 透過 nginx log 觀察,我的網站都會收到大量探測請求:掃 `.env`、掃 `wp-admin`、掃 `xmlrpc.php`。這些請求不只浪費頻寬,還是攻擊的前哨。 然後我就想到了 Cloudflare 有出 MCP plugin,可以用 Claude Code 透過對話直接把防火牆規則設定到 Cloudflare,完全不用進 Dashboard 手動操作,超讚! >除了設定權限和產 API Key 需要人工授權 --- ## 安裝 Cloudflare Plugin Claude Code 支援 plugin 生態系。Cloudflare 官方有提供 plugin,整合了 Cloudflare MCP Server,讓 Claude 能直接呼叫 Cloudflare API。 先打開你的 claude code 對話視窗,依序輸入下面官方提供的指令: ``` # 加入資源 /plugin marketplace add cloudflare/skills # 安裝 /plugin install cloudflare@cloudflare # 在這個 session 重載 plugin /reload-plugins ``` 安裝後 Claude 會多出以下幾個工具: - `cloudflare-api` — 執行 Cloudflare API 請求 - `cloudflare-docs` — 搜尋官方文件 - Cloudflare 相關 skills(WAF、Workers、D1 等) --- ## 先查文件,再動手 我習慣在做任何 Cloudflare 設定前先問文件,避免用到過時的 API: ``` 調整 cloudflare 防火牆規則,阻止惡意的連線, 例如 URI 包含 /^\./|wp-/ 之類的請求 ``` Claude 會透過 `cloudflare-docs` 搜尋工具拉取最新文件,確認目前的 WAF 規則語法。 **重要發現**:Cloudflare 的 regex 支援(`matches` operator)只在 Business 和 Enterprise 方案才有。Free 方案只能用: | Operator | 說明 | |----------|------| | `starts_with()` | 路徑開頭比對 | | `ends_with()` | 路徑結尾比對 | | `contains()` | 包含字串 | | `wildcard` | 萬用字元(`*`) | | `eq` | 完全相等 | --- ## OAuth 認證與權限問題 Cloudflare plugin 使用 OAuth 流程認證。Claude 會產生一個授權連結,在瀏覽器完成後,MCP Server 取得 token。 但這裡有個問題:**OAuth token Permission 我不敢全開,所以只有給系統建議的 read only 權限**,呼叫 WAF Rulesets API 會拿到 `Authentication error (10000)`。 解法是手動建立一個有 WAF 寫入權限的 API Token: 1. 前往 Cloudflare Dashboard → **My Profile → API Tokens → Create Token** 2. 選 **Custom Token**,設定: - **Permissions**:`Zone → WAF → Edit` - **Zone Resources**:選擇你的 zone 3. 建立後複製 token ![截圖 2026-04-15 下午6.49.20](https://hackmd.io/_uploads/HyXbxl6hWg.png) --- ## 另一個坑:Rulesets API vs. 舊版 Firewall Rules API Cloudflare 有兩套 WAF API: | API | 路徑 | 狀態 | |-----|------|------| | 舊版 Firewall Rules | `/zones/{id}/firewall/rules` | 已棄用但仍可用 | | 新版 Rulesets | `/zones/{id}/rulesets/phases/http_request_firewall_custom/entrypoint` | 現行標準 | 即使 token 有 `#waf:edit` 權限,呼叫新版 Rulesets API 仍然會拿到 `Authentication error`。原因是新版 Rulesets API 要求的內部權限範圍(`#com.cloudflare.api.account.zone.ruleset:edit`)並非一般 WAF token 能覆蓋的。 實際測試後,用**舊版 API** 完全可行,且 Free 方案也支援。 --- ## 實際使用的 API 流程 (這裡都是 AI 在操作,我只有按確認) 舊版 Firewall Rules API 需要兩步:先建 **Filter**,再建 **Rule**。 ### Step 1:建立 Filters ```python import json, urllib.request zone_id = 'YOUR_ZONE_ID' token = 'YOUR_API_TOKEN' filters = [ { 'expression': '(starts_with(http.request.uri.path, "/."))', 'description': 'Block dotfiles and hidden paths' }, { 'expression': ( '(http.request.uri.path wildcard "/wp-*") or ' '(http.request.uri.path wildcard "/*/wp-*") or ' '(http.request.uri.path eq "/xmlrpc.php")' ), 'description': 'Block WordPress probes' } ] body = json.dumps(filters).encode() req = urllib.request.Request( f'https://api.cloudflare.com/client/v4/zones/{zone_id}/filters', data=body, headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' }, method='POST' ) with urllib.request.urlopen(req) as resp: result = json.loads(resp.read()) print(json.dumps(result, indent=2)) ``` 回傳會包含每個 filter 的 `id`,下一步會用到。 ### Step 2:建立 Firewall Rules ```python rules = [ { 'filter': {'id': 'FILTER_ID_1'}, # dotfiles filter id 'action': 'block', 'description': 'Block dotfiles and hidden paths', 'paused': False }, { 'filter': {'id': 'FILTER_ID_2'}, # wordpress filter id 'action': 'block', 'description': 'Block WordPress probes', 'paused': False } ] body = json.dumps(rules).encode() req = urllib.request.Request( f'https://api.cloudflare.com/client/v4/zones/{zone_id}/firewall/rules', data=body, headers={ 'Authorization': f'Bearer {token}', 'Content-Type': 'application/json' }, method='POST' ) with urllib.request.urlopen(req) as resp: result = json.loads(resp.read()) print(json.dumps(result, indent=2)) ``` --- ## 最終建立的規則 | 規則名稱 | Expression | 涵蓋範圍 | |---------|-----------|---------| | Block dotfiles | `starts_with(uri.path, "/.")` | `.env`, `.git`, `.htaccess`, `.DS_Store` | | Block WordPress probes | `wildcard "/wp-*"` 或 `eq "/xmlrpc.php"` | `wp-admin`, `wp-login.php`, `wp-content`, `xmlrpc.php` | 建立後可在 Dashboard → **Security → WAF → Firewall rules** 看到並管理。 --- ## 心得 整個流程用對話完成,省掉了翻文件和手動點 Dashboard 的時間。最有價值的部分是 Claude 幫忙即時查 Cloudflare 文件確認 Free 方案支援的 operator,避免我寫出跑不動的 regex 規則。 唯一要注意的是 **API Token 的安全管理**:建立用完即可刪除,不要讓 token 長期存在。Cloudflare Dashboard 的 API Tokens 頁面可以隨時撤銷。