Smail/docs/恢复码取消与低资源补充验收.md
smail 7114e9ed4a
Some checks are pending
Security Checks / security (push) Waiting to run
修复恢复码请求取消并完成最终迁移补充验收
2026-09-21 20:26:50 +08:00

9.4 KiB
Raw Permalink Blame History

恢复码取消与低资源补充验收

日期:2026-09-21。本记录接续 SQLite 跨引擎迁移补充验收,不能替代全项目生产放行。

需求确认与任务状态

  • [✓] 保留上一轮失败证据,九文件提交 586f2bc 已推送并核对远端哈希。
  • [✓] 区分恢复码密码计算、数据库事务和 HTTP 请求取消,不把初始化超时写成迁移数据损坏。
  • [✓] 接入请求取消、可取消互斥等待和事务回滚;四个相关 Go 包、全量本地后端及 Linux 专项回归通过,跳过项单独披露。
  • 完整应用的内存目标单变量对照已完成,PostgreSQL → SQLite 中间候选通过。
  • [✓] 最终候选重新编译及云端 PostgreSQL → SQLite 复测通过,实际进程环境核对完成。
  • [✓] 本地运行时回归 81 项、云端完整部署回归 151 项通过,后者零跳过。
  • [✓] 127 份文件本地与远端摘要一致,616 个后端源码摘要一致;八个测试账号锁定,正式六服务和程序未变,测试单元全部停止。
  • [!] 原 64 MiB Go 内存目标的受限环境仍存在 30 秒恢复码生成超时,不能按同条件通过处理。
  • [!] 浏览器、外部邮件、凭据轮换、续期、长时容量和灾备等其他门禁仍未全部关闭。

超时定位证据

不降低 Argon2id 参数,不减少恢复码数量,不放宽探针 30 秒读取超时。密码算法仍为 m=65536,t=3,p=1,每轮生成十枚恢复码。

直接调用凭据服务的受限诊断使用新建 PostgreSQL 空库、专用账号、192 MiB 进程内存上限和 25% CPU 配额:

诊断实例后缀 Go 内存目标 密码计算至事务开始 整体生成 GC 次数
20260921-082512 64 MiB 23.753 秒 23.775 秒 138
20260921-082540 128 MiB 24.079 秒 24.093 秒 10

这两个独立服务诊断没有显示明显的总耗时改善;数据库事务只占十几至二十几毫秒。不能仅凭 GC 次数差异宣称找到了完整应用的全部性能原因。前两次诊断启动遇到隔离挂载与执行路径错误,未进入应用测试,保留记录且专用账号已锁定。

随后用同一个中间候选 062c15539ed0df446d4050bc15b55f717369b58fba0caa2e8c4f28ceabd5ed0c 进行完整应用对照:

实例后缀 Go 内存目标 密码计算 整体生成 结果
20260921-083048 64 MiB 30.208 秒 30.209 秒 客户端取消;尚未进入数据库事务,取消被服务识别
20260921-083337 128 MiB 23.601 秒 23.619 秒 初始化及后续完整迁移通过

两个应用实例均保持 CPU 25%、进程硬上限 192 MiB、交换禁用、GOMAXPROCS=1、十枚恢复码和 30 秒读取超时,仅显式调整 Go 内存目标。直接证据确认失败发生在密码计算阶段,而非 PostgreSQL → SQLite 迁移执行阶段。内存目标变化与本次完整应用耗时改善存在对照证据,但不能从这一组样本外推所有负载下的性能。

原失败记录继续有效。128 MiB 是另一个明确标注的资源配置,不是把旧配置改写为通过,更不是生产容量或性能承诺。正式服务资源配置没有变动。

修改边界与反例

  1. GenerateRecoveryCodesContext 接收 HTTP 请求上下文;旧无上下文入口保留,供兼容调用使用。
  2. 每次 Argon2id 计算之间检查取消;单次计算本身不可中断,不改变哈希强度。
  3. 凭据写入锁允许取消等待;取消不能释放其他请求持有的锁,也不能留下不可再用的锁。
  4. 数据库事务使用请求上下文,插入和提交前检查取消;未提交事务统一回滚。
  5. 自助及管理员代生成入口均传递请求上下文;管理员入口遇到密码计算繁忙时返回 503、Retry-After: 1 和 AUTH_BUSY。
  6. 阶段日志只记录数量、耗时、阶段和成功/取消标志,不记录恢复码、哈希、口令或 Cookie。

反例覆盖:请求开始前取消、第一/第五/第十次计算后取消、等待凭据锁取消、等待数据库连接取消、第一/最后一次插入后取消、密码计算繁忙、互斥并发及非法解锁。成功路径继续检查十枚随机码及原 Argon2id 参数。

本修改保证已观察到取消且尚未提交的事务不会部分轮换恢复码。数据库提交已经成功后发生响应丢失,是另一种状态;不能承诺数据库提交与浏览器收到明文之间具有原子性。

工具与环境

  • 隔离验收工具新增显式 Go 内存目标参数,默认仍是原 64 MiB;Go 目标与进程硬上限之间必须保留至少 64 MiB。
  • 验收器读取进程环境时只保留 GOMEMLIMIT、GOMAXPROCS,不保存其他环境变量。
  • 探针单独记录恢复码阶段和耗时,失败时不再把后续尚未创建的目标库误读为数据库损坏。
  • 中间候选只重编译后端,复用未修改的前端与 Linux 插件资产,不能描述为全资产重建。
  • 每轮使用新空隔离实例和新 SQL 库,不清空正式数据库,不停止正式 Smail 或其他项目,不删除离线证据。

中间候选 PostgreSQL → SQLite 实例 20260921-083337:内部 PID 794879 不变,系统重启为 795359,故障恢复为 795477。三阶段源 PostgreSQL 连接数均为零,目标 SQLite 打开;运行目录只保留 migrated.db,没有第二个状态库。旧邮件、新邮件、正文和附件、配置历史原始字节、目标不可用时拒绝启动、恢复后读写均通过。

本地证据位于 test-log/production-remediation-20260921/,包括 recovery-timing-*、mixed-runtime-evidence/smail-review-runtime-20260921-083048/ 和 mixed-runtime-evidence/smail-review-runtime-20260921-083337/。首次扩大本地回归遇到新测试夹具角色类型编译错误,修正后四个相关包均通过;前后日志均保留。

最终候选与回归结果

最终后端候选 SHA-256 为 87eb782b34ac16473259e4b63caf98dd9dd073c887d0dcad008742bbc913bd35,对应本轮恢复码修改和互斥非法解锁保护。构建仍复用未修改的前端及 Linux 插件资产,不是全资产重新构建,也未替换正式实例。

范围 结果与边界
Windows 本地全量后端 go test -json -p 1 ./... -count=1 -timeout=240s 退出零;62 个包通过,22 个包级跳过;1057 个顶层测试及 831 个子测试通过,34 个顶层测试及 7 个子测试跳过,零失败
Linux 恢复码专项 20260921-085040 两个测试程序退出零,共 19 个测试及子测试通过、零跳过;凭据包十枚强哈希耗时约 24.4 秒
最终候选应用级迁移 20260921-085155 PostgreSQL → SQLite 通过;恢复码 HTTP 耗时 23.772 秒,未放宽 30 秒超时
本地运行时工具回归 81 项通过,证据为 recovery-runtime-python-tests.log
Linux 全部部署工具回归 20260921-201523 实际执行 151 项、零跳过、退出零;峰值 45.9 MiB、交换为零,正式六服务状态未变

本地全量跳过项包含平台相关的符号链接与权限检查、未启用的真实 SQL 集成、浏览器夹具及 Windows 提权 IPC 等,不视为验收通过。Linux 恢复码专项只补足本修改的运行平台证据,不覆盖全部本地跳过项。

最终迁移实例实际进程环境为 GOMEMLIMIT=128MiB、GOMAXPROCS=1,进程硬上限仍为 192 MiB、CPU 配额仍为 25%,无 OOM。内部重启 PID 796642 不变,系统重启后为 797013,故障恢复后为 797134。三阶段源 PostgreSQL 活动连接均为零,目标 SQLite 打开,活动库只有 migrated.db;业务与配置历史同库。

待重启写入被拒绝、原会话保留、配置历史原始字节一致、历史及新增邮件中文正文和附件的 SMTP/IMAP/POP3 读写均通过。目标不可用时退出码为 1、PID 为零,没有回退源库;恢复访问后读写通过。测试账号锁定,桥接和网络隔离单元停止,无资源采集或清理错误。

本轮最后一个迁移方向已获得成功证据,但跨引擎六个方向来自不同阶段候选,不能表述为最终候选在同一轮跑完全部方向。迁移提交及配置切换临界点、SQL 复制中断、历史凭据轮换、静态安全剩余项、真实浏览器、外部投递、自动续期、容量及异机灾备等继续保持未完成。

独立复核与收尾

20 时补充回归后,recheck_recovery.py 对八次跨引擎应用级尝试、两个 Linux 专项程序及部署工具回归执行独立复核,合计检查 127 份文件,包括成功与失败日志、当前工具、最终候选及测试二进制;本地与远端摘要全部一致。616 个后端源码文件与最终构建清单一致。旧工具仅按原始证据摘要复核,不要求旧轮次工具与当前工具一致。

三次恢复码超时失败完整保留。八个 SQL 专用账号均锁定,PostgreSQL 账号不能登录、建库或提权;测试单元全部停止。正式六服务的 PID、InvocationID、重启次数及活动状态与测试前一致,正式主程序 SHA-256 仍为 c14ef1c5ba1dc2096c312c8357039a7330c985cbeac90765aed01d8151e05e1f。用户原 云端全项目测试报告.md 未编辑或暂存。

当前跟踪文件的凭据特征扫描通过,只代表该扫描器覆盖的当前文件检查,不代表历史凭据撤销或完整安全审计通过。整体验收继续未通过,不能部署为已验收生产版本。