≡articles //snippets ./categories $uses ~about /search

Cloudflare WAF 规则实战:5 条规则挡住 99% 恶意请求

WordPress 是全球被扫描最多的 CMS。随便一个没做防护的 WP 站,日志里每天几万条 /xmlrpc.php、/wp-admin、插件漏洞探测请求。靠 PHP 层的安全插件去拦,你的 CPU 先被打满了。

Cloudflare WAF(Web Application Firewall)的思路不同——它不跑在 PHP 里,而是跑在网络层。恶意请求在到达你的服务器之前就被截住了。Cloudflare WAF 免费套餐自带的自定义规则引擎,让个人站长也能用上企业级防护。

WAF 是什么,为什么 WP 站需要

打个比方:PHP 安全插件相当于你家门口的保安,来了人先盘问。WAF 相当于小区大门——闲杂人等连小区都进不来。

WordPress 站面临的攻击分几类:

  • 暴力破解 — 撞 /xmlrpc.php 或 /wp-login.php 的密码
  • 漏洞扫描 — 探测已知插件/主题漏洞(自动化的,每分钟几百次)
  • DDoS / CC 攻击 — 大量请求打挂服务器
  • 恶意爬虫 — 采集内容、搜刮邮箱

安全插件在 PHP 层拦截这些请求时,每个请求都已经消耗了一次 PHP-FPM 进程。WAF 在这之前就拦住了,PHP 根本不会启动。

前置:Cloudflare 免费套餐能做什么

Cloudflare 的免费套餐自带 5 条自定义 WAF 规则,以及一套托管的 OWASP 规则集。对于个人 WP 站点,这 5 条 Cloudflare WAF 规则用好了完全够——每天几千次攻击请求在到达服务器之前就被挡掉了。

入口:Cloudflare 控制台 → 你的域名 → 安全性 → WAF → 自定义规则。

每条规则的基本结构是:匹配条件 → 执行动作。匹配条件可以组合多个字段(URI、IP、User-Agent、ASN、国家代码等),执行动作可以是阻止、托管质询(JS 验证)、或跳过后续规则。

下面五条规则按优先级从高到低排列。建议保持这个顺序——前面的规则拦截明确恶意流量,后面的做兜底限流。

规则一:屏蔽高频扫描端点

两个被扫描最多的端点:

  • /xmlrpc.php — 如果你不用 WordPress 移动端 App 或通过 XML-RPC 发文章,直接封掉。大多数个人站点用 REST API 就够了
  • /wp-json/wp/v2/users — 暴露用户名列表的接口,攻击者用来枚举用户

WAF 规则配置:

字段值
匹配条件URI 路径 包含 /xmlrpc.php 或 URI 路径 包含 /wp-json/wp/v2/users
动作阻止
优先级最高(放在第一条)

如果你确实需要 XML-RPC(比如用了 Jetpack 或手机 App),把 /xmlrpc.php 从这条里去掉,单独做一条限流规则。更多细节可以看 Cloudflare 自定义规则文档。

这条规则的效果立竿见影。部署前你可以去服务器上看 Nginx 日志里有无数条 xmlrpc.php 的 POST 请求,部署后这些请求在 CF 就被 403 了,服务器日志里一条都没有。关于 xmlrpc.php 的安全风险和 PHP 层防护方案,之前写过一篇 WordPress 安全防护:防止 xmlrpc.php 被恶意扫描爆破,PHP 层和 WAF 层双保险更可靠。

规则二:禁止直接访问 PHP 文件

正常用户不会直接访问 /wp-content/uploads/2024/ 下的 PHP 文件。如果有人在请求这个路径,大概率是在测试你有没有文件上传漏洞——上传了一个 PHP webshell,然后去执行它。

字段值
匹配条件URI 路径 包含 /wp-content/uploads/ 且 URI 路径 以 .php 结尾
动作阻止

这个规则基本零误伤。正常的图片、PDF 等静态文件不受影响。

规则三:限流——防止单个 IP 洪水攻击

前面的规则拦的是特定恶意请求,但攻击者也可能用大量“看起来正常”的请求打挂服务器。限流规则管的就是这种情况。

字段值
匹配条件URI 路径 不包含 .css 且 不包含 .js 且 不包含 .png 且 不包含 .jpg 且 不包含 .webp 且 不包含 .svg 且 不包含 .woff — 只对动态请求限流,静态资源放过
速率限制同一 IP:10 次请求 / 10 秒
动作阻止(或托管质询)

10 次 / 10 秒对于正常用户浏览 WP 站点足够了——正常人点文章、翻页,不会一秒发十几条请求。攻击脚本一跑就会触发。

如果你在 Nginx 层也配了限流(limit_req_zone),这条 WAF 规则可以作为第一道防线。Nginx 限流处理不过来的才到 CF,关于 Nginx 限流的配置我之前写过 Nginx 限流实战:用 limit_req 防 CC 攻击,两篇文章可以对照着看。

规则四:拦截已知恶意 User-Agent 和 Bot

大量扫描器会伪造或使用固定的 User-Agent。把常见的恶意 UA 集中到一条规则里:

字段值
匹配条件User-Agent 包含 python-requests 或 包含 Go-http-client 或 包含 Java/ 或 包含 zgrab 或 包含 Nmap 或 包含 sqlmap 或 包含 libwww-perl 或 包含 wpscan
动作阻止

这些 User-Agent 基本不出现在正常浏览器流量中。如果某个 UA 导致了误伤(比如你用 Python 脚本访问自己的 API),在条件里排除掉 你的服务器 IP 就行。

另外一个强力字段是 ASN(自治系统号)。如果你发现所有攻击都来自某个主机商的 IP 段(某些廉价 VPS 厂商是扫描器的重灾区),可以直接用 ASN 封一整个 IP 段。在 WAF 日志里找攻击者的 ASN,然后在规则里加一个 ASN 匹配条件。

规则五:地理位置限制(可选)

如果你的站点只面向中国大陆的访客,可以考虑限制其他地区的访问。不过这条要慎重——误伤代价很高。

字段值
匹配条件国家 不等于 中国 且 URI 路径 不包含 /wp-admin 且 URI 路径 不包含 /wp-json
动作托管质询(不阻止,先给 JS 验证)

我只建议在你被某个特定国家的 IP 持续攻击时临时启用。日常不建议开——Google 爬虫、国外搜索引擎的索引都会受影响。

部署后验证:Cloudflare WAF 规则是否生效

规则部署后别不管了。三个验证步骤:

1. 看 WAF 事件日志

Cloudflare → 安全性 → 概述。图表上能看到被阻止的请求数量和趋势。如果某条规则误伤了正常用户,这里一眼就能看出来。

2. 确认正常功能没受影响

部署规则后立即检查:

  • WP 后台能正常登录
  • REST API(/wp-json/)能正常返回数据
  • 搜索引擎爬虫没被误拦——Google Search Console 里看抓取错误

3. Nginx 日志对比

# 部署前:看一天有多少 xmlrpc 请求打到服务器
grep xmlrpc /www/wwwlogs/sodebug.com.log | wc -l

# 部署后:应该大幅下降甚至归零

部署一周后回看 WAF 统计,你会惊讶于每天被挡掉的请求数量——个人 WP 站每天几千到几万次攻击请求是常态。

总结

  • Cloudflare WAF 在请求到达 PHP 之前就拦截,不消耗服务器资源——免费套餐就够个人站用
  • Cloudflare 免费套餐 5 条规则够个人站用:封端点 + 限流 + 封恶意 UA + 防 PHP 执行 + 可选地理限制
  • 部署后必须验证:看 WAF 日志、确认正常功能、对比 Nginx 日志
  • WAF 和 Nginx 限流不冲突——WAF 是第一道,Nginx 是第二道

相关阅读:

© 2026 Cloudflare WAF 规则实战:5 条规则挡住 99% 恶意请求 · 本文由 Charlie 原创撰写,发布于 sodebug.com。 未经授权禁止转载、洗稿、机器抓取。AI 训练数据使用需获得书面授权。
GK
独立开发者,在 WordPress、Nginx 和各种 API 之间切换。不写没用的东西。

related相关文章

#01WordPress mu-plugin 实战:3 个零插件安全加固方案6 min#02MariaDB 字符集排查实录:emoji 变问号 → 全文搜索错乱 → 索引静默失效(三个连环坑)6 min#03宝塔 Nginx 限流配置速查:limit_req_zone 参数详解4 min
$ echo "less bullshit, more debugging" | send-to-inbox
新文章直接发到邮箱,一个月 2-4 封。
$ subscribe →