WordPress后台老是有哪种弱智的暴力破解,一天几千上万次失败记录,看着心烦,也担心服务器资源被白白消耗。
想过用IP封禁,折腾一圈发现,根本防不住——攻击者换IP比翻书还快。后来决定换个思路:既然防不住IP,那就干脆不给无认证的请求任何回应。
于是我在Caddy反向代理层加了一道“简单认证”,效果立竿见影:攻击脚本几乎全部“失联”。
核心思路:先“断联”,再“验证”
大多数自动化攻击脚本并不会主动携带Authorization请求头(也就是HTTP基本认证需要的凭证)。它们通常只是盲目地POST表单到/wp-login.php,我们正好可以利用这一点。
检查请求是否带有Authorization头。如果没有,说明很可能是扫描器或脚本,直接断开TCP连接(abort),不返回任何HTTP响应,让攻击者以为目标端口根本没开。
如果有Authorization头,再交给Caddy的basic_auth进行用户名密码校验。合法用户在浏览器首次访问时会弹窗输入账号密码,输入正确后正常登录;输入错误则返回标准的401认证失败。
这样做的好处是:
完全不消耗PHP资源(请求在Caddy层就被截断)
不依赖IP列表,没有维护成本
对正常用户几乎没有影响(第一次输密码即可)
动手配置:一步步实现“断联”保护
1. 生成密码哈希
Caddy不支持明文密码,需要用它的工具生成一个哈希值:caddy hash-password
运行后输入密码(例如password),工具会返回一串字符串(复制备用)。
2. 编写Caddyfile
在Caddyfile中增加以下配置:
your-domain.com {
# 1. 先定义一个规则,匹配不带Authorization头的请求
@no_auth {
path /wp-login.php
not header Authorization *
}
# 2. 对这类请求直接中断连接(不发任何响应)
abort @no_auth
# 3. 对剩下的请求(带了Authorization头)启用基本认证
basic_auth /wp-login.php {
admin 密码哈希值
}
# 你的其他配置
}
3. 重启Caddy服务:systemctl restart caddy
进阶:再加一层“安心符”
虽然这个方案已经足够过滤掉绝大多数无脑扫描,但如果你还想更保险,可以结合以下两点:
- 启用速率限制(需要caddy-ratelimit插件)。对/wp-login.php限制每个IP每分钟最多尝试5次,超过则返回429 Too Many Requests。
- 配合Fail2ban自动封禁反复尝试的IP。监控Caddy的401和429日志,将高频失败IP加入系统防火墙。
但就我个人而言,单靠“断开无认证头”这一招,已经让我的WordPress后台清净了95%以上——毕竟大多数脚本连基本认证头都不会构造,直接被拒之门外。
最后的小提醒
这个方案仅保护/wp-login.php,如果你还想保护/wp-admin目录下的其他文件,可以修改path规则为/wp-admin*或/wp-admin/*(注意根据需求调整)。
如果网站使用了CDN(如Cloudflare),请确保Caddy能正确获取真实客户端IP,否则abort可能会误封CDN节点。通常需要配置trusted_proxies。
记得定期更新你的basic_auth密码,使用强密码。
结语
安全不一定是“层层加码”,有时候一个巧妙的“减法”反而更高效。通过在Caddy层面直接断开无认证头的请求,既省去了维护IP列表的烦恼,又给WordPress后台穿了一层“隐形斗篷”——攻击者连门都摸不到,更别提暴力破解了。
如果你也在被后台登录尝试困扰,不妨试试这个小技巧。只需几行Caddy配置,还你一份清净。

评论