KernelRanch
返回文章列表

WAF 入门:免费计划能配出的第一层防护

2026-11-10 #Cloudflare

WAF 在免费计划里不是"没有",而是"少了高级检测、留下了拦与放的控制权"。具体到手的是两块:一块是持续更新的 Cloudflare Free Managed Ruleset,另一块是几条自定义规则,用来按路径、方法、IP、国家做拦截或挑战。把这两块配好,能挡掉大部分无差别扫描和已知漏洞探测,剩下的靠速率限制与人机验证补。这篇按控制台的菜单顺序走一遍,最后用 Security Events 确认规则确实在拦流量。

前置条件只有两个:域名已经接入并在 Cloudflare 上处于 Active 状态(做法见 49-add-domain-to-cloudflare.md),以及记录是橙色云代理状态——灰云(仅 DNS)的流量不经过边缘,WAF 看不到。

1. 先看清免费档拿到的是什么

能力免费档付费档
WAF 托管规则仅 Free Managed RulesetCloudflare Managed Ruleset、OWASP Core Ruleset 等
自定义规则条数5 条Pro 20 条、Business 50 条、Enterprise 更多
速率限制规则1 条(见 78-rate-limiting.md)Pro 2 条、Business 5 条、Enterprise 100 条
自定义列表(IP / ASN 列表)支持支持
泄露凭据检测、敏感数据检测无部分为付费附加
攻击评分(Attack Score)无付费

自定义规则条数在控制台 WAF 页面底部会写明当前套餐配额,实际数字以控制台为准。

2. 打开免费托管规则集

控制台路径:Security → WAF → Managed rules,找到 Cloudflare Free Managed Ruleset,点 Deploy。

这套规则是官方维护的,跟着公开漏洞和常见攻击模式更新,不需要你写表达式。刚上线时建议不要直接全量 Block,先把动作设成 Managed Challenge 观察一两天。免费托管规则集的规则数量比付费版少,覆盖的是高危 CVE 与最常见 payload,对定制化的业务逻辑漏洞没有判断力。

3. 写第一条自定义规则

控制台路径:Security → WAF → Custom rules → Create rule。一条规则由三部分组成:匹配表达式、动作、以及可选的日志说明。

先挡后台扫描。表达式写成:

(http.request.uri.path contains "/wp-login.php") or
(http.request.uri.path contains "/xmlrpc.php") or
(http.request.uri.path contains "/.env")

动作选 Block。这类请求通常来自批量扫描器,正常用户不会访问,误伤概率低。

再保护管理入口,把来源限制到办公网段:

(http.request.uri.path contains "/admin" and ip.src ne 203.0.113.0/24)

动作选 Managed Challenge 而不是 Block。挑战对真人几乎无感,对脚本是硬门槛;万一网段写错,你自己还能通过一次挑战进去,不至于把自己锁在外面。

第三条可以按国家粗筛,但要谨慎——IP 地理位置只精确到国家,代理与移动网络会漂移:

(ip.geoip.country in {"CN" "RU"} and http.request.uri.path contains "/api/admin")

表达式里可用的字段在免费档有 ip.src、ip.geoip.country、ip.geoip.asnum、http.request.method、http.request.uri.path、http.request.uri.query、http.user_agent、http.referer、cf.threat_score、cf.client.bot。写的时候注意两点:字符串比较用 contains、eq、matches(正则,慎用,性能与误伤都要考虑);and 优先级高于 or,复杂条件用括号分组。

4. 五种动作的差别

动作结果适用场景
Block直接返回 403 拦截页,页面带 Ray ID明确的恶意路径、已知攻击 IP
Managed Challenge非交互式挑战,多数真人无感通过登录口、后台、可疑但不确定的流量
JS Challenge下发 JS 让浏览器执行验证老版本浏览器兼容场景
Interactive Challenge需要点击复选框疑似脚本但证据不足
Log只记录不拦新规则上线前的观察期
Skip跳过后续指定安全功能放过支付回调、Turnstile 验证接口

Skip 动作值得单独说。免费档的 Bot Fight Mode 会给部分自动化客户端下发挑战,如果你有 API 客户端、监控探针、支付回调要走同一域名,用 Skip 规则按路径或 User-Agent 把它们放出来,否则会看到"服务正常但客户端一直 403"。

5. 规则的执行顺序

自定义规则按列表顺序从上到下评估,命中 Block 之后不再往下走;托管规则在自定义规则之后评估。所以想放过某条流量,Skip 规则要放在拦截规则前面。拖动列表调整顺序即可,不用删了重建。

免费档的规则条数少,5 条以内要省着用:优先覆盖后台入口、已知漏洞路径、以及你自己的 API 前缀。自定义规则集(custom rulesets)本身所有套餐都能建,但它解决的是"同一套规则复用到多个域名",不会让单域名的条数变多。

6. 用 Security Events 验证

规则配完不等于生效。到 Security → Events 看最近一小时的事件,每条被拦的请求会带上规则 ID、动作、路径、IP、国家、User-Agent 和 Ray ID。验证方法很直接:用 curl 请求一条你刚拦的路径,看是否返回 403,再回 Events 里找到这条记录。

curl -s -o /dev/null -w "%{http_code}\n" https://example.com/wp-login.php

返回 403 说明规则命中。若返回 200,检查三件事:表达式是否拼错、规则是否处于 Enabled、记录是否走了代理(灰云不经过 WAF)。

排查攻击时的整体顺序见 86-attack-triage-order.md,日志侧的证据留存见 85-logpush-logs.md。

常见问题

免费托管规则集会不会误杀正常用户?

会。规则集里有一部分是针对特定 payload 特征的正则,业务表单里出现类似字符串时可能命中。上线初期把动作设成 Managed Challenge,观察一周的误杀记录,再决定要不要改成 Block。

自定义规则和速率限制规则哪个先执行?

自定义规则先。速率限制在 WAF 之后统计,所以被 Block 的请求不计入速率计数。两者叠加时的顺序细节见 78-rate-limiting.md。

Block 之后用户看到什么?

一个 403 页面,上面有 Ray ID 与"你被网站所有者阻止"的提示,错误码常见 1020。想给出更友好的提示,付费档支持自定义响应页;免费档只能拦或挑战。

小结

免费计划给的 WAF 是一套"手写规则 + 官方基础规则"的组合。它不做智能评分,也不会替你判断业务逻辑是否被绕过,但你可以在十分钟内把后台入口、常见漏洞路径和明显的批量扫描挡在边缘,省掉源站的一堆 404 与异常日志。

配置时把顺序理清楚:先 Skip 放行必要的自动化流量,再 Block 明确恶意的路径,剩下的用 Managed Challenge 兜底。规则数量有限,5 条以内就要按"最可能被打的地方"排优先级,而不是按"能想到的规则"铺满。

数据来源与检索时间

检索时间 2026-11-10,以下页面用 HTTPS 直接抓取,均返回 200。

来源URL对应数据
WAF 概览https://developers.cloudflare.com/waf/免费档"Free Managed Ruleset only"、速率限制 1 条、自定义列表全档可用
自定义规则https://developers.cloudflare.com/waf/custom-rules/表达式与动作模型、规则按顺序评估、Skip 动作的作用
速率限制规则https://developers.cloudflare.com/waf/rate-limiting-rules/各套餐规则条数、免费档可用字段

核验说明

  • 三个官方页面为本机实际抓取(HTTP 200),文中套餐对照表取自页面里的 Availability 表格。
  • 未执行:本机没有 Zone 权限(令牌只有 Workers / KV / 账户读取),控制台里的启用托管规则、创建自定义规则、查看 Security Events 都没有实际点过,步骤依据文档描述写成。
  • 未验证:自定义规则条数 5 条来自公开文档与常见控制台提示,未在真实免费账号上确认;Block 拦截页的错误码 1020 为常见表现,未实测。