Typecho 1.1 升级到 1.3.0 实录:主题兼容、登录限流与日志收敛
in 服务器 with 0 comment

Typecho 1.1 升级到 1.3.0 实录:主题兼容、登录限流与日志收敛

in 服务器 with 0 comment

背景

博客长期停留在 Typecho 1.1(17.10.30),最近决定升级到 1.3.0。升级本身不复杂,真正花时间的是插件兼容、主题适配和登录故障排查。整个过程记录如下,供同样在老版本上「养老」的朋友参考。

一、升级前的备份

备份只做一次是不够的——每次改动前先确认「能退回去」,后面才敢动配置。

二、数据库迁移

1.3.0 的数据结构与 1.1 有差异(路由表、附件信息改为 JSON 等)。用命令行引导框架执行官方升级脚本:

<?php
chdir('/path/to/blog');
require 'config.inc.php';
\Utils\Upgrade::v1_3_0(\Typecho\Db::get(), \Widget\Options::alloc());

迁移后确认 generator 为 Typecho 1.3.0、路由表已包含新条目、草稿数量正常;另外记得移除 config.inc.php 里升级时临时加的 __TYPECHO_DEBUG__。

三、主题兼容

使用的 pinghsu 1.5.4 在 1.3.0 下会直接报错,主要是两类问题:

改完逐个页面回归:首页、文章页、分页、独立页面、feed 全部 200,错误日志无新增。

四、登录不上:插件才是元凶

升级后后台登录页能打开,但提交账号密码一直跳回登录页。排查发现是 LoginLimit(登录失败次数限制)插件:它接管了 Widget_User:login 钩子,而 1.3.0 的登录流程在钩子被插件处理后直接 return——插件自身逻辑已不兼容新版本,于是登录永远「未成功」。

处理方式是停用插件,但不走插件自带的 deactivate()(它会删掉登录日志表),而是手工从激活列表、钩子注册、后台菜单、动作表中移除,登录日志数据完整保留。停用后错误密码能正常返回「密码错误」,登录恢复。

五、用 Nginx 限流替代插件

插件没了,暴力破解防护不能没有。服务器上没装 WAF,fail2ban 也只管 SSH / FTP,于是用 Nginx 自带的 limit_req:

# http 段
map "$request_method:$uri" $login_limit_key {
    default "";
    "POST:/index.php/action/login"  $binary_remote_addr;
    "POST:/admin/login.php"         $binary_remote_addr;   # 后台入口按实际路径替换
}
limit_req_zone $login_limit_key zone=login_limit:10m rate=10r/m;
limit_req_status 429;

# 站点 server 段
limit_req zone=login_limit burst=5 nodelay;

关键点:只对 POST 登录请求计数。最初按 URI 计数时,GET 登录页也占额度,试错几次后连登录页本身都返回 429,反而把管理员挡在门外。改用「方法 + URI」作为 map 键后,刷新登录页永远正常,只有真正的登录提交会被限制。

实测:连续 8 次错误密码提交 → 前 6 次 302,后 2 次 429;额度按分钟滚动恢复,不需要额外服务。

六、让错误日志安静下来

升级初期错误日志被弃用提示刷了几十万行,平均每天上千条,既占空间又掩盖真问题。把 PHP 错误级别收紧到只记录致命错误:

error_reporting = E_ERROR

改 php.ini 后 reload php-fpm,并用一次真实的 FPM 请求验证运行时取值确实为 1——不能只看 CLI,两边的 ini 往往是分开的。之后清理当天日志条目,注意用「读出来再写回」的方式原地截断,保留 inode 与权限,避免正在写日志的进程句柄失效。

七、检查清单

小结

老版本 Typecho 升级,难点几乎都在周边:主题模板里对旧 API 的硬编码、插件的钩子兼容性,以及「顺手」留下的宽松配置;数据库迁移反而是最省心的一步。建议顺序是:先备份 → 再升级 → 逐个停用并替换旧插件 → 最后收紧日志与访问控制,每一步都留可回滚的余地。

Responses
kotori.png