Cloudflare WAF 配置完全指南:Ruleset API、Terraform、Pulumi 与 Dashboard 多路径部署实战
2026/9/12 19:30:09 网站建设 项目流程

Cloudflare WAF 配置完全指南:Ruleset API、Terraform、Pulumi 与 Dashboard 多路径部署实战

【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills

Cloudflare WAF(Web Application Firewall)通过自定义规则、托管规则集与速率限制为 Web 应用提供攻击防护。本文以 skills 仓库中 cloudflare-deploy 技能(cloudflare-deploy 参考目录)的 WAF 配置文档为骨架,系统讲解从 API Token 准备、TypeScript SDK、Terraform、Pulumi 到 Dashboard 控制台的全部配置路径,并结合仓库中的 api.md、patterns.md 与 gotchas.md 补充表达式语法、动作表、阶段执行顺序与限额等底层细节。读完本文,你将掌握在 Cloudflare 上独立完成 WAF 规则集编排、托管规则集部署与速率限制配置的完整能力。

前置条件:API Token 与 Zone ID

无论使用 SDK、Terraform 还是 Pulumi,调用 Cloudflare API 管理 WAF 之前都需要两样东西:一个具备 WAF 编辑权限的 API Token,以及目标 Zone(站点)的 ID。

API Token 创建(地址:https://dash.cloudflare.com/profile/api-tokens):

  • 权限(Permission):Zone.WAF EditZone.Firewall Services Edit
  • Zone 资源(Zone Resources):可限定为指定 Zone,也可选择所有 Zone

Zone ID 获取:登录 Cloudflare Dashboard 后,进入对应站点 >Overview> 右侧边栏的API区域即可看到。

将二者配置为环境变量:

# 设置环境变量 export CF_API_TOKEN="your_api_token_here" export ZONE_ID="your_zone_id_here"

安全提示:参考 API 配置参考 中的约定,切勿把 Token 提交到版本库;建议使用.env文件(加入.gitignore)或密钥管理器保管,例如在仓库内的 WAF 排错文档 gotchas.md 中同样强调先以log模式验证再上线。

理解 Ruleset:阶段(Phase)、动作(Action)与表达式

Cloudflare WAF 的底层是 Ruleset 引擎,所有规则都以「规则集」为单位挂在某个阶段上。阶段决定了规则的执行时机,动作决定命中的处理方式,表达式(基于 Wirefilter 语法)决定哪些请求被匹配。这是配置一切的基础。

阶段与执行顺序

仓库中的 api.md 明确了阶段(Phase)概念——它们是固定顺序、不可调整的:

  1. http_request_firewall_custom— 自定义规则(第一道防线)
  2. http_request_firewall_managed— 托管规则集(预置防护)
  3. http_ratelimit— 速率限制(请求节流)
  4. http_request_sbfm— Super Bot Fight Mode(Pro+ 套餐)

在同一阶段内,规则按从上到下、首个命中生效(first match wins)的规则执行,除非遇到skip动作。

动作(Action)与阶段的兼容性

来自 api.md 的动作矩阵决定了每个阶段能使用哪些动作:

动作自定义规则托管规则集速率限制说明
block以 403 拒绝请求
challenge展示 CAPTCHA 验证
js_challengeJS 方式挑战
managed_challenge智能挑战(推荐)
log仅记录、不拦截
skip跳过后续规则评估
execute部署托管规则集

常用表达式字段与操作符

表达式是 WAF 规则的核心语言,常用的字段(来源 api.md):

// 请求属性 http.request.method // GET、POST 等 http.request.uri.path // /api/users http.host // example.com // IP 与地理信息 ip.src // 192.0.2.1 ip.geoip.country // US、GB 等 ip.geoip.continent // NA、EU 等 // 攻击检测评分 cf.waf.score // 0-100 攻击评分 cf.waf.score.sqli // SQL 注入评分 cf.waf.score.xss // XSS 评分 // 请求头与 Cookie http.request.headers["authorization"][0] http.request.cookies["session"][0] lower(http.user_agent) // 小写化 User-Agent

操作符分为三类:比较类(eqneltlegtge)、字符串匹配类(containsmatchesstarts_withends_with)、逻辑与集合类(innotandor)。组合示例:

'cf.waf.score gt 40' // 攻击评分 'http.request.uri.path eq "/api/login" and http.request.method eq "POST"' // 路径 + 方法 'ip.src in {192.0.2.0/24 203.0.113.0/24}' // IP 段拦截 'ip.geoip.country in {"CN" "RU" "KP"}' // 国家/地区拦截 'http.user_agent contains "bot"' // User-Agent 匹配 'not http.request.headers["authorization"][0]' // 请求头存在性检查 '(cf.waf.score.sqli gt 20 or cf.waf.score.xss gt 20) and http.request.uri.path starts_with "/api"' // 复杂组合

托管规则集 ID 速查

仓库 waf/README.md 给出了三个官方托管规则集的 ID 与覆盖范围:

规则集名称ID覆盖范围
Cloudflare Managedefb7b8c949ac4650a09736fc376e9aeeOWASP Top 10、CVE
OWASP Core Ruleset4814384a9e5d4991b9815dcfc25d2f1fOWASP ModSecurity CRS
Exposed Credentials Checkc2e184081120413c86c3ab7e14069605撞库(Credential stuffing)检测

TypeScript SDK 配置:自定义规则、托管规则集与速率限制

Cloudflare 官方 TypeScript SDK 是代码化配置 WAF 最直接的方式。先安装依赖:

npm install cloudflare

然后初始化客户端:

import Cloudflare from 'cloudflare'; const client = new Cloudflare({ apiToken: process.env.CF_API_TOKEN });

自定义规则(Custom Rules)

自定义规则挂在http_request_firewall_custom阶段,用于按攻击评分、路径或地理信息等条件精确处置:

await client.rulesets.create({ zone_id: process.env.ZONE_ID, kind: 'zone', phase: 'http_request_firewall_custom', name: 'Custom WAF', rules: [ { action: 'block', expression: 'cf.waf.score gt 50', enabled: true }, { action: 'challenge', expression: 'http.request.uri.path eq "/admin"', enabled: true }, ], });

实战中更常见的做法是分级处置,来自 patterns.md:

rules: [ // 攻击评分分级处置 { action: 'block', expression: 'cf.waf.score gt 50', enabled: true }, { action: 'challenge', expression: 'cf.waf.score gt 20', enabled: true }, // 特定攻击类型 { action: 'block', expression: 'cf.waf.score.sqli gt 30 or cf.waf.score.xss gt 30', enabled: true }, // 地理拦截 { action: 'block', expression: 'ip.geoip.country in {"CN" "RU"}', enabled: true }, ]

部署托管规则集(Managed Ruleset)

托管规则集挂在http_request_firewall_managed阶段,通过execute动作部署,action_parameters.id指向规则集 ID:

await client.rulesets.create({ zone_id: process.env.ZONE_ID, phase: 'http_request_firewall_managed', rules: [{ action: 'execute', action_parameters: { id: 'efb7b8c949ac4650a09736fc376e9aee' }, expression: 'true', }], });

expression: 'true'表示对所有请求生效;也可以改成'http.request.uri.path starts_with "/api"'仅对 API 路径生效。若要微调托管规则集中的单条规则或某个分类(如wordpresssqlixssrce),使用overrides

action_parameters: { id: 'efb7b8c949ac4650a09736fc376e9aee', overrides: { rules: [ { id: '5de7edfa648c4d6891dc3e7f84534ffa', action: 'log', enabled: true }, ], categories: [ { category: 'wordpress', enabled: false }, { category: 'sqli', action: 'log' }, ], }, }

速率限制(Rate Limiting)

速率限制挂在http_ratelimit阶段。核心参数(含义见 api.md):

  • characteristics:识别唯一请求方的特征组合,如ip.srccf.colo.idhttp.request.headers["key"][0]http.request.cookies["session"][0];推荐「按 IP × 按数据中心」组合
  • period:统计时间窗口(秒)
  • requests_per_period:窗口内允许的最大请求数
  • mitigation_timeout:触发后拦截持续时长(秒)
  • counting_expression(可选):仅统计符合条件的请求
  • requests_to_origin:是否只统计回源请求
await client.rulesets.create({ zone_id: process.env.ZONE_ID, phase: 'http_ratelimit', rules: [{ action: 'block', expression: 'http.request.uri.path starts_with "/api"', action_parameters: { ratelimit: { characteristics: ['cf.colo.id', 'ip.src'], period: 60, requests_per_period: 100, mitigation_timeout: 600, }, }, }], });

patterns.md 还提供了登录接口收紧限速、仅统计写请求等进阶模式:

// 登录接口更严格 { action: 'block', expression: 'http.request.uri.path eq "/api/login"', action_parameters: { ratelimit: { characteristics: ['ip.src'], period: 60, requests_per_period: 5, mitigation_timeout: 600 } } }, // 仅统计非 GET 请求(counting_expression 用法) { action: 'block', expression: 'http.request.uri.path starts_with "/api"', action_parameters: { ratelimit: { characteristics: ['cf.colo.id', 'ip.src'], period: 60, requests_per_period: 50, counting_expression: 'http.request.method ne "GET"' } } },

其他常用 SDK 方法

来自 api.md 的完整方法集:

// 列出规则集 await client.rulesets.list({ zone_id: 'zone_id', phase: 'http_request_firewall_managed' }); // 获取规则集详情 await client.rulesets.get({ zone_id: 'zone_id', ruleset_id: 'ruleset_id' }); // 更新规则集(携带 rule id 保留既有规则,省略 id 则为新增规则) await client.rulesets.update({ zone_id: 'zone_id', ruleset_id: 'ruleset_id', rules: [ { id: 'rule_id', action: 'block', expression: 'cf.waf.score gt 40', enabled: true }, { action: 'challenge', expression: 'http.request.uri.path contains "/admin"', enabled: true }, ], }); // 删除规则集 await client.rulesets.delete({ zone_id: 'zone_id', ruleset_id: 'ruleset_id' });

⚠️注意update()整体替换规则列表。更新前务必先get()取回既有规则再合并写入,否则会误删其他规则(详见下文「常见坑位与排错」)。

Terraform 配置:基础设施即代码管理 WAF

对需要版本化管理、审计或团队协作的场景,Terraform 的cloudflareProvider 是推荐选择。Provider 与资源的完整说明可参考 Terraform 配置参考。

先配置 Provider:

provider "cloudflare" { api_token = var.cloudflare_api_token }

自定义规则资源

resource "cloudflare_ruleset" "waf_custom" { zone_id = var.zone_id kind = "zone" phase = "http_request_firewall_custom" rules { action = "block" expression = "cf.waf.score gt 50" } }

托管规则集与覆盖(Managed Ruleset & Override)

resource "cloudflare_ruleset" "waf_managed" { zone_id = var.zone_id name = "Managed Ruleset" kind = "zone" phase = "http_request_firewall_managed" rules { action = "execute" action_parameters { id = "efb7b8c949ac4650a09736fc376e9aee" overrides { rules { id = "5de7edfa648c4d6891dc3e7f84534ffa" action = "log" } } } expression = "true" } }

overrides既可按单条规则 ID 覆盖(rules),也可按分类覆盖(categories,如{ category = "wordpress", enabled = false })。

速率限制资源

resource "cloudflare_ruleset" "rate_limiting" { zone_id = var.zone_id phase = "http_ratelimit" rules { action = "block" expression = "http.request.uri.path starts_with \"/api\"" ratelimit { characteristics = ["cf.colo.id", "ip.src"] period = 60 requests_per_period = 100 mitigation_timeout = 600 } } }

Terraform 同样遵循「一个阶段一个 ruleset 资源」的模型:自定义规则、托管规则集、速率限制分属三个cloudflare_ruleset资源,与 SDK 的分阶段创建完全对应。

Pulumi 配置:TypeScript 化的 WAF 资源编排

Pulumi 以编程语言表达基础设施,适合希望用 TypeScript 统一应用与基础设施代码的团队。其资源映射与 Terraform 一一对应,可参考 Pulumi 资源配置参考。

import * as cloudflare from '@pulumi/cloudflare'; const zoneId = 'zone_id'; // 自定义规则 const wafCustom = new cloudflare.Ruleset('waf-custom', { zoneId, phase: 'http_request_firewall_custom', rules: [ { action: 'block', expression: 'cf.waf.score gt 50', enabled: true }, { action: 'challenge', expression: 'http.request.uri.path eq "/admin"', enabled: true }, ], }); // 托管规则集 const wafManaged = new cloudflare.Ruleset('waf-managed', { zoneId, phase: 'http_request_firewall_managed', rules: [{ action: 'execute', actionParameters: { id: 'efb7b8c949ac4650a09736fc376e9aee' }, expression: 'true', }], }); // 速率限制 const rateLimiting = new cloudflare.Ruleset('rate-limiting', { zoneId, phase: 'http_ratelimit', rules: [{ action: 'block', expression: 'http.request.uri.path starts_with "/api"', ratelimit: { characteristics: ['cf.colo.id', 'ip.src'], period: 60, requestsPerPeriod: 100, mitigationTimeout: 600, }, }], });

Dashboard 控制台配置与验证

不写代码的团队可直接在 Cloudflare 控制台完成同等配置:

  1. 进入Security>WAF
  2. 选择标签页:
    • Managed rules— 部署/配置托管规则集
    • Custom rules— 创建自定义规则
    • Rate limiting rules— 配置速率限制
  3. 点击DeployCreate rule完成创建

测试建议:在正式部署前,使用Security Events(安全事件)功能验证表达式是否符合预期——这也是 gotchas.md 反复强调的实践:先log观察再拦截,可显著降低误杀风险。

Wrangler 集成:Worker 自动受益与 API 查询

WAF 配置是Zone 级别的,并非 Worker 专属。Worker 部署后自动处于该 Zone 的 WAF 防护之下,无需修改任何 Worker 代码即可获得防护能力。配置方式即上文四种:Dashboard UI、Cloudflare API(SDK)、Terraform/Pulumi(IaC)。

若 Worker 运行时需要读取或查询 WAF 配置,可直接调用 Cloudflare API(注意将 Token 与 Zone ID 放入 Worker 的环境变量/密钥,参考 Wrangler 配置参考 的 secrets 机制):

export default { async fetch(request: Request, env: Env): Promise<Response> { return fetch(`https://api.cloudflare.com/client/v4/zones/${env.ZONE_ID}/rulesets`, { headers: { 'Authorization': `Bearer ${env.CF_API_TOKEN}` }, }); }, };

常见坑位与排错指南

来自仓库 gotchas.md 的实战排错要点,是配置过程中最容易被绊倒的地方。

1. 阶段与动作混用导致部署失败

每个阶段有专属动作:execute只能出现在http_request_firewall_managedratelimit参数只能出现在http_ratelimit阶段。错误的做法是在自定义规则阶段里塞execute

// 错误:阶段内混用阶段专属动作 await client.rulesets.create({ phase: 'http_request_firewall_custom', rules: [ { action: 'block', expression: 'cf.waf.score gt 50' }, { action: 'execute', action_parameters: { id: 'managed_id' } }, // 错误! ], });

正确做法是按阶段拆分规则集:

await client.rulesets.create({ phase: 'http_request_firewall_custom', rules: [...] }); await client.rulesets.create({ phase: 'http_request_firewall_managed', rules: [...] });

2. 表达式常见语法错误

'http.request.path' → 'http.request.uri.path' // 字段名错误 'ip.geoip.country eq US' → 'ip.geoip.country eq "US"' // 字符串必须加引号 'http.user_agent eq "Mozilla"' → 'lower(http.user_agent) contains "mozilla"' // 大小写敏感 'matches ".*[.jpg"' → 'matches ".*\\.jpg$"' // 正则必须合法

3. Skip 规则的作用域误区

  • ruleset: 'current':仅跳过当前规则集的剩余规则
  • phases: ['http_request_firewall_managed', 'http_ratelimit']:整体跳过指定阶段

由于执行顺序,自定义阶段里的ruleset: 'current'只能跳过自定义规则,无法影响后续托管规则集阶段;若要放行可信 IP 的托管与限速检查,必须显式列出phases

4. update() 会整体替换规则

// 错误:会删除既有全部规则 await client.rulesets.update({ zone_id, ruleset_id, rules: [{ action: 'block', expression: 'cf.waf.score gt 50' }] }); // 正确:先取回旧规则再合并 const ruleset = await client.rulesets.get({ zone_id, ruleset_id }); await client.rulesets.update({ zone_id, ruleset_id, rules: [...ruleset.rules, { action: 'block', expression: 'cf.waf.score gt 50' }] });

5. 覆盖(Override)不生效

先确认规则 ID 与分类名是否正确。可通过 SDK 列出托管规则集中的实际规则:

const ruleset = await client.rulesets.get({ zone_id: 'zone_id', ruleset_id: 'efb7b8c949ac4650a09736fc376e9aee', }); console.log(ruleset.rules.map(r => ({ id: r.id, description: r.description })));

6. 误杀(False Positive)处理三步走

  1. 先用log模式(overrides: { action: 'log' })观察
  2. 在 Security Events 中甄别误杀请求
  3. 对特定规则覆盖:overrides: { rules: [{ id: 'rule_id', action: 'log' }] }

7. NAT 场景下限速误伤

多用户共享同一出口 IP 时,仅按 IP 限速会误伤。解决方式是在characteristics中加入更多维度(User-Agent、会话 Cookie、Authorization 头):

ratelimit: { characteristics: ['cf.colo.id', 'ip.src', 'http.request.cookies["session"][0]'], period: 60, requests_per_period: 100, }

8. 性能优化建议

  • 尽早用skip放行静态资源:expression: 'http.request.uri.path matches "\\.(jpg|css|js)$"'
  • 按路径收窄托管规则集范围(仅/api/admin
  • 关闭未使用的分类:{ category: 'wordpress', enabled: false }
  • 优先用字符串操作符(starts_withcontains),避免matches正则带来的额外开销

9. 限额与配额参考

以下为各套餐的规则数量与表达式长度限制(来源 gotchas.md,以仓库记录为准):

资源FreeProBusinessEnterprise
自定义规则5201001000
速率限制规则11025100
规则表达式长度4096 字符4096 字符4096 字符4096 字符
每个规则集规则数75754001000
托管规则集支持支持支持支持
限速特征数量2355

10. 常见 API 报错速查

// "Invalid phase" → 使用准确的阶段名 phase: 'http_request_firewall_custom' // "Ruleset already exists" → 先 list 再 update const rulesets = await client.rulesets.list({ zone_id, phase: 'http_request_firewall_custom' }); if (rulesets.result.length > 0) { await client.rulesets.update({ zone_id, ruleset_id: rulesets.result[0].id, rules: [...] }); } // "Expression parse error" → 常见修复 'ip.geoip.country eq "US"' // 字符串加引号 'cf.waf.score gt 40' // 用 gt 而不是 > 'http.request.uri.path' // 不是 http.request.path

完整示例:三阶段一体化防护

将三种阶段组合,构成「放行可信来源 → 评分拦截 → 托管规则 → 限速」的完整防护链(来自 patterns.md 的 Complete Setup Example):

const client = new Cloudflare({ apiToken: process.env.CF_API_TOKEN }); const zoneId = process.env.ZONE_ID; // 1. 自定义规则(最先执行) await client.rulesets.create({ zone_id: zoneId, phase: 'http_request_firewall_custom', rules: [ { action: 'skip', action_parameters: { phases: ['http_request_firewall_managed', 'http_ratelimit'] }, expression: 'ip.src in {192.0.2.0/24}' }, { action: 'block', expression: 'cf.waf.score gt 50' }, { action: 'managed_challenge', expression: 'cf.waf.score gt 20' }, ], }); // 2. 托管规则集(其次执行) await client.rulesets.create({ zone_id: zoneId, phase: 'http_request_firewall_managed', rules: [{ action: 'execute', action_parameters: { id: 'efb7b8c949ac4650a09736fc376e9aee', overrides: { categories: [{ category: 'wordpress', enabled: false }] } }, expression: 'true', }], }); // 3. 速率限制(最后执行) await client.rulesets.create({ zone_id: zoneId, phase: 'http_ratelimit', rules: [ { action: 'block', expression: 'true', action_parameters: { ratelimit: { characteristics: ['cf.colo.id', 'ip.src'], period: 60, requests_per_period: 100, mitigation_timeout: 600 } } }, { action: 'block', expression: 'http.request.uri.path eq "/api/login"', action_parameters: { ratelimit: { characteristics: ['ip.src'], period: 60, requests_per_period: 5, mitigation_timeout: 600 } } }, ], });

相关参考

  • WAF 参考文档总览 — 技能概览、托管规则集 ID 与阅读顺序
  • WAF API 参考 — SDK 方法、表达式字段、动作表与参数详解
  • WAF 常用模式 — 托管规则、覆盖、限速、跳过与完整示例
  • WAF 排错指南 — 执行顺序、限额、表达式错误与 API 报错
  • Terraform 配置参考 — Provider 与全部资源写法
  • Pulumi 配置参考 — Pulumi 资源映射
  • API 客户端配置参考 — SDK 超时、重试与环境变量规范
  • Wrangler 配置参考 — wrangler.jsonc、密钥与部署

【免费下载链接】skillsSkills Catalog for Codex项目地址: https://gitcode.com/GitHub_Trending/skills4/skills

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询