# 用 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

---
## 另一個坑: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 頁面可以隨時撤銷。