![]()
后台登录页是整站唯一一个没有验证码的地方。Typecho 自带的防护只有一个 sleep(3) —— 每次密码错误后停 3 秒,能拖慢脚本,但挡不住"慢慢试",更不会在试错几十次之后把来源关在门外。
所以我写了个插件:同一 IP 在 15 分钟内失败 5 次,锁定 30 分钟;锁定期间即使密码正确,也拒绝登录。
它能做什么
- 按 IP 统计登录失败次数,达到阈值自动锁定
- 锁定期间密码正确也拒绝(这点最关键,否则爆破只要撞对一次就前功尽弃)
- 登录成功后清空该 IP 的失败记录,正常用户完全无感
- 支持 IP 白名单,避免自己手滑两次就把自己关在门外
- 三项核心参数都能在后台改,也有现成的默认值
- 4 KB 单文件,无第三方依赖,无数据库改动,停用即失效
安装
- 解压,把
LimitLoginAttempts整个文件夹上传到/usr/plugins/ - 后台 → 控制台 → 插件 → 找到「登录失败限制」→ 启用
- 点「设置」,按需调整参数(不改也能直接用)
不用改主题,不用改伪静态,不用手动建目录。
设置项
| 设置 | 默认值 | 说明 |
| 最大失败次数 | 5 | 同一 IP 在统计窗口内允许的最大失败次数,超过即锁定 |
| 统计窗口(分钟) | 15 | 在这个时间范围内统计失败次数 |
| 锁定时长(分钟) | 30 | 触发上限后禁止登录的时长 |
| IP 白名单 | 空 | 多个 IP 用英文逗号分隔,白名单内的 IP 不受限制 |
参数都有范围校验:次数 1–100、窗口 1–1440 分钟、锁定 1–10080 分钟(7 天),填超了自动回落到默认值,不会把自己锁死一年。
被锁定之后是什么体验
登录尝试过于频繁,账号已临时锁定,请稍后再试
然后被退回登录页。注意:登录页本身不会提前告诉你"已被锁定",因为 Typecho 的登录流程里没有这个钩子,只有提交之后才判定。这是插件做不到的地方,先说明白。
实现上的几个取舍
写在代码里的几个决定,顺带记录一下思路:
只认 REMOTE_ADDR,不信任 X-Forwarded-For。 后者是请求头,客户端想写什么写什么,信任它等于把锁的钥匙交给攻击者。
数据存在插件目录的 data/attempts.php,文件第一行是 <?php exit; ?>。 这样即使有人直接访问这个文件,PHP 解析到第一行就退出,剩下的 JSON 一个字都不会输出,IP 列表不会泄露。
锁定期内不再累加失败次数。 否则攻击者一直打,锁会被无限延长,等于给了对方一个"永久踢掉站长"的按钮。
自动清理。 超过 24 小时没活动、且不在锁定期的记录会被删掉;总量上限 500 条,防止被大量 IP 撑爆磁盘。
所有统计逻辑都包在 try/catch 里。 记录失败这件事绝对不能影响正常登录,任何一个异常都只吞掉,不往上抛。
几个需要注意的边界
1. 站前有 CDN 时不要用。
套了 Cloudflare 之类的 CDN,REMOTE_ADDR 全是 CDN 的节点 IP,一个人被锁等于全站被锁。这种情况要么别装,要么在 CDN 那层做限流。
2. 动态 IP 会互相误伤。
家用宽带每次拨号换 IP,被锁后换个 IP 就进来了(防不住);反过来,办公网共用出口 IP,一个人输错会牵连同事。建议把自己的常用 IP 填进白名单。
3. 把自己锁在外面了怎么办。
删掉 usr/plugins/LimitLoginAttempts/data/attempts.php 即可,所有锁立即解除,不需要停用插件,也不需要动数据库。
4. 只适用 Typecho 1.3.x。
插件用的是 1.3 的命名空间写法(namespace TypechoPlugin\LimitLoginAttempts),1.2 及更早版本加载不了。
5. 环境要求。
PHP 7.4 以上,在 PHP 8.2 + LiteSpeed 环境实测通过。不需要 Redis、不需要 cron。
它挡不住什么
说清楚比较好,免得装了就觉得高枕无忧:
- 换 IP 池的分布式爆破 —— 每个 IP 只试一两次,永远达不到阈值。那种要靠按用户名限流或上验证码
- 已经泄露的密码 —— 这是密码管理的问题,跟限流无关
- 管理员自己嫌麻烦 —— 如果你经常在手机热点、公司、家里三地切换 IP,被锁的概率不低
一句话:它是门槛,不是保险箱。 但门槛能挡掉绝大多数粗暴脚本,成本几乎为零,值得装。
下载
| 项目 | 说明 |
| 版本 | 1.0.0 |
| 大小 | 3.6 KB(zip) |
| 环境 | Typecho 1.3.x / PHP 7.4+ |
| 依赖 | 无 |
下载地址:https://www.lanzouq.com/ixxxxxxxx 提取码:y139
解压后把 LimitLoginAttempts 文件夹放进 /usr/plugins/,后台启用即可。
目前我最多也就隐藏登录入口,这里挺好的,有想法对接一个通行密钥,自动填充验证,安全些。
是的
我都没做这些暴力破解的防护功能 😰 等着再吃一次大亏再说。
我先试试好用不😀