ProtectRequest:为 WordPress 私人站点设计一套轻量请求防护体系
本篇目录
在维护 WordPress 站点的过程中,我逐渐意识到一个问题:很多攻击并不是复杂的入侵,而是大量自动化扫描。
它们会不断尝试访问各种文件或路径,例如:
/xmlrpc.php
/.env
/wp-config.php
/.git/
随机 php 文件
/wp-content/plugins/xxx/shell.php
/wp-json/wp/v2/users
这些请求大多数不会真正成功,但它们会带来三个问题:
第一,制造大量无意义访问日志。
第二,让 PHP 和 WordPress 处理本不该处理的请求。
第三,在某些配置不严谨的情况下,可能暴露站点结构或形成真实风险。
ProtectRequest 就是在这样的背景下逐步形成的。
它最初并不是为了替代 Wordfence、NinjaFirewall 这类成熟安全插件,也不是为了做一个通用开源项目,而是为了给我自己的 WordPress 站点增加一层可理解、可控制、可复盘的请求防护能力。
一、为什么没有直接依赖现成安全插件
WordPress 生态中已经有很多成熟安全插件,例如 Wordfence、AIOS、NinjaFirewall、BBQ Firewall 等。它们的功能更完整,规则库也更成熟。
但我的需求并不是安装一个“大而全”的安全套件,而是希望在自己的站点里实现一套更轻量、更明确的防护逻辑:
哪些请求应该在 Nginx 层直接拒绝?
哪些请求应该由 PHP 插件动态判断?
哪些只是 404 噪音?
哪些需要记录但不必立刻封禁?
哪些 IP 应该临时封禁?
哪些行为应该永久封禁?
对我来说,ProtectRequest 的价值不只是“拦截攻击”,更重要的是帮助我理解站点正在面对什么样的访问行为,并把这些行为转化为可管理的安全规则。
二、当前防护体系的分层
目前站点防护大致分为三层:
请求
↓
Nginx
↓
PHP ProtectRequest
↓
WordPress
其中 Nginx 负责更底层、更静态的拦截,例如:
敏感文件访问
协议异常
目录访问
PHP 执行入口限制
xmlrpc.php 前置拦截
ProtectRequest 则负责更贴近 WordPress 的动态判断,例如:
可疑 User-Agent
敏感路径探测
随机 PHP 文件扫描
REST API 用户枚举
作者枚举
IP 封禁
Redis 状态管理
后台封禁列表
WordPress 本身只应该处理真正正常的业务请求,而不是被迫处理大量扫描器请求。
这个分层思路非常重要。
如果所有规则都放到 PHP 层,会导致无效请求仍然进入 WordPress 环境,浪费资源。
如果所有规则都放到 Nginx 层,又会缺少动态判断、后台管理和可视化分析。
所以更合理的方式是:
Nginx:拦截明显非法请求
ProtectRequest:处理动态识别和封禁管理
WordPress:只处理正常业务
三、从日志中看到的真实攻击类型
在日志分析中,我看到的请求大致可以分为几类。
1. 敏感文件探测
这类请求通常访问:
/.env
/wp-config.php
/wp-config.php.bak
/.git/config
/.ssh/
composer.lock
settings.py
它们的目的很明确:寻找配置文件、数据库密码、部署信息或源码泄露。
这类请求不应该进入 WordPress,也不应该被视为普通 404。
对于 .env、wp-config、.git 这类路径,我倾向于直接视为高风险行为,触发永久封禁。
2. XML-RPC 滥用
WordPress 的 /xmlrpc.php 是常见攻击入口,经常被用于暴力破解、批量请求或探测。
在当前站点中,XML-RPC 没有实际业务需求,因此 ProtectRequest 已经对它进行拦截。后续更适合将这类规则前移到 Nginx 层:
location = /xmlrpc.php {
return 403;
}
这样可以避免大量 XML-RPC 请求进入 PHP。
3. 随机 PHP / Webshell 文件名扫描
当我分析日志时也能看到大量类似这样的请求:
/xa.php
/dr.php
/yj09.php
/xstelth.php
/ups.php
/r00t.php
/saim11.php
/wp-includes/css/index.php
/wp-admin/css/index.php
/wp-content/plugins/hellopress/wp_filemanager.php
这些请求大多数返回 404,因为文件本身不存在。
但它们的意图并不是访问正常页面,而是在寻找已经被上传或遗留的 Webshell。
这类请求短期看风险不高,但它暴露出一个重要问题:
如果未来某个上传漏洞、插件漏洞或误操作导致恶意 PHP 文件落入 wp-content 目录,
攻击者就可能通过这些路径直接执行它。
因此,真正可靠的处理方式不是只在 ProtectRequest 里匹配文件名,而是在 Nginx 层限制 PHP 执行入口,例如:
location ~* ^/(wp-content|wp-includes)/.*.php$ {
return 403;
}
这样即使未来某个目录下出现 PHP 文件,也不会被外部直接访问。
4. 499 客户端断开请求
部分扫描器会快速发送请求后立即断开连接,在 Nginx 日志中表现为 499。
这类行为会影响 PHP 层封禁的及时性。因为如果客户端过早断开,请求可能没有完整进入后续处理流程,ProtectRequest 的封禁逻辑不一定每次都来得及执行。
但从实际结果看,只要该 IP 后续命中敏感路径规则,例如 config,ProtectRequest 仍然能够识别并永久封禁。
这说明 499 并不是完全绕过防护,而是提醒我:对于高频扫描和明显恶意 IP,最好尽量在 Nginx 层提前处理。
5. 异常 200 响应
日志中还有一类更值得注意的请求:本不该有意义,却返回了 200。
例如:
/wp-content/index.php
/wp-content/plugins/index.php
/wp-links-opml.php
POST /
这些不一定是漏洞,但它们会给扫描器反馈:
站点是 WordPress
目录结构存在
某些默认文件可访问
首页可以接受脚本 POST
对于这类请求,我更倾向于减少信息反馈。例如将部分 WordPress 占位文件直接返回 403:
location = /wp-content/index.php {
return 403;
}
location = /wp-content/plugins/index.php {
return 403;
}
location = /wp-content/themes/index.php {
return 403;
}
location = /wp-includes/index.php {
return 403;
}
四、ProtectRequest 当前承担的职责
ProtectRequest 当前更像是一个轻量请求防护模块,而不是完整安全插件。
它主要承担以下职责:
1. 请求路径检测
2. 可疑 User-Agent 检测
3. 敏感文件探测识别
4. XML-RPC 拦截
5. REST API 用户枚举防护
6. IP 临时封禁 / 永久封禁
7. Redis 封禁状态存储
8. 后台封禁列表展示
9. 手动封禁和解封
10. 攻击原因记录
它的价值在于形成了一个闭环:
发现恶意请求
↓
记录原因
↓
写入 Redis
↓
后续请求自动拦截
↓
后台可查看和解封
这比单纯在 functions.php 中写几条拦截规则更有管理价值。
五、为什么不把所有安全规则都塞进去
在设计过程中,我也考虑过是否应该把其他安全能力全部集中到 ProtectRequest。
例如:
登录失败限速
邮箱验证
设备信任
评论审核
REST 权限控制
安全响应头
上传目录扫描
Nginx 规则管理
但最后我认为,ProtectRequest 不应该变成一个“大而全”的安全插件。
原因是不同安全能力所属的层级不同:
登录失败限速:属于账户系统
邮箱验证:属于身份验证系统
设备信任:属于登录风控
Nginx 规则:属于 Web Server 层
请求识别和封禁:属于 ProtectRequest
如果所有逻辑都塞进一个插件,短期看集中,长期看会变得混乱:
职责变重
维护困难
误封风险增加
性能开销变大
开源价值降低
一处出错影响全站
所以当前更合理的定位是:
ProtectRequest 可以成为安全状态的管理中心,
但不应该成为所有安全逻辑的唯一执行者。
六、阶段性结论与后续方向
目前 ProtectRequest 已经基本成型并上线,它的很多数据来自真实站点环境,包括自己的访问日志、攻击样本、Redis 封禁设计、Nginx 配置,以及 WordPress 主题和账户系统。
但它暂时并不适合作为通用插件开源。如果直接面向更多站点,就需要处理不同主机环境、Redis 降级、Apache / Nginx 差异、WooCommerce / REST API 误封、公开注册站点适配等问题。同时,安全规则完全公开后,也可能暴露自己的防护边界。
所以我暂时不会把它包装成一个“大而全”的安全插件,也没有必要让它和 Wordfence、NinjaFirewall 这类成熟插件正面对比。对我来说,ProtectRequest 更适合被定位为:一个面向私人 WordPress 站点的轻量请求防护与 IP 封禁管理模块。
后续如果继续增强,我可能会加入以下内容:
风险评分机制
可疑请求观察日志
随机 PHP 探测识别
敏感文件规则库增强
Nginx 建议规则生成
uploads 目录危险 PHP 文件巡检
封禁等级升级机制
攻击分类统计
ProtectRequest 要解决的问题,并不是让 WordPress 变得绝对安全,而是:
减少无效扫描进入 PHP
识别高风险请求
自动封禁恶意 IP
保留攻击行为记录
辅助生成 Nginx 加固规则
让站点安全变得可观察、可管理、可复盘
最终,这套体系的分工应该保持清晰:
Nginx 负责挡掉明显不该进入站点的请求;
ProtectRequest 负责识别、封禁和记录动态风险;
WordPress 负责正常业务;
Redis 负责封禁状态和计数;
人工复盘负责持续优化规则。
它也许无法替代成熟安全插件,但基于真实站点日志,为我私人 WordPress 站点建立了一套轻量、可控、可复盘的请求防护体系。希望它的思路也能给同样维护WordPress 站点的人一些参考。