159 KiB
Linux 生产流程测试记录
最新执行记录(2026年10月1日,密码重置页面安全信息收敛)
- 公开密码重置页面已移除本机管理命令、操作系统命令和
Scert-admin入口名称。 - 超级管理员查询接口不再在说明中返回可执行维护命令;重置会话、令牌和验证码仍不通过公开查询接口返回。
- 后端全量测试、静态检查、构建、前端 241 项测试和生产前端构建通过。
- [~] 待使用最新候选包部署到 Linux 实机,清理浏览器缓存并复测公开密码重置页面;本项通过不代表 Smail 发信、密码重置闭环或最终生产门禁通过。
最新实机回归记录(2026年10月1日,可信恢复证据候选)
- 最新提交:
0e48dc9,已推送远程仓库。 - 正式 Linux amd64 包:
build/recovery-evidence-20261001/Scert-20261001-V0.1.0-linux-amd64.tar.gz。 - 包 SHA-256:
9b6748b6f25446adcc454fb9ecf88a31cbf70554bcbfcae3451670f9a81e4afe。 - 使用密码 SSH 将候选包安装到
45.136.13.241;Scert、存储 socket、Nginx、MySQL 均 active。 - 通过
https://odacm.cn/登录超级管理员,执行同一域名绑定两台服务器的正式部署两次;两次均为两台推送成功、配置校验及 reload 成功、站点 HTTPS 校验通过。 - 执行
systemctl restart Scert.service后,服务保持 active,HTTPS 管理入口返回 200。 - 数据库只读核查:新事务进入
committed;现场保留两条缺少可信恢复证据的历史recovery_required事务,未删除锁、未修改状态、未伪造验收结果。 - 本记录仅证明候选安装、正常双目标部署和重启后的基础回归;异常中断、负向 HTTPS 恢复、三数据库、双平台、SMTP、密码重置、备份恢复和最终生产门禁仍未完成。
当前核查与开发记录(2026年10月1日,北京时间)
候选构建收尾
- 已提交并推送
8899f7a,从新的规范克隆构建,源码与依赖锁文件无变化,发布清单记录源码未修改、后端五百六十三个与前端一百零五个受跟踪文件均采用规范换行。 - 正式包:
build/rollback-state-20261001/Scert-20261001-V0.1.0-linux-amd64.tar.gz,大小四千九百二十七万四千零三十六字节。 - 归档 SHA256:
69e6389bfedb297997017a608b38d82c5f8f4c2f0102efe2cb5a3c323ae2be24。 - 逐项重算清单二十三项产物的大小与哈希通过;实际解包后核对二十二个文件的完整集合、内容和大小通过;五个执行入口归档权限为
0755。 - 尚未部署。当前启动恢复只判断锁目录存在,并未证明属于哪笔事务;也没有持久化旧站点指纹供重启后严格核验。不能以重启后锁消失替代可靠恢复验收,更不能直接删除现场锁。
- 本条更新本批早期候选未构建状态;本地成功不等于 Linux 原生构建、线上恢复或最终生产验收。
本批本地验证收尾:后端 go test ./...、go vet ./...、go build ./... 均通过;部署、应用、仓库三个包的竞态回归分别约八秒、五十九秒、三十二秒,全部退出零。条件跳过的外部数据库和 SSH 场景没有据此宣称通过,正式生产验收仍未完成。
只读现场核查
- 10:24 使用密码 SSH 并启用已登记主机指纹严格校验连接第二台服务器;Scert、存储 socket、Nginx 均为运行状态。
- 使用 SQLite 只读连接确认:最新任务仍为失败;两笔事务
20260930-231313.144123222-ce71b1dfe14e、20260930-231310.231207974-5bf9d1e37542仍为需要恢复,提示旧文件已经恢复但等待站点恢复核验。 - 目标域名目录仍有三个部署锁;中断测试证据目录也有三个锁。本批没有清库、重启服务、删除文件或改变这些记录。本次只读诊断不是清库首次生产流程验收。
- 上轮报告中的两个域名、两台服务器严格 HTTPS 通过,属于当时站点状态证据;不能据此把当前失败任务判为成功。本批没有重新执行该四次 HTTPS 检查。
确认的代码缺陷与修复边界
- 新回归在修改前稳定失败:双目标恢复核验已经通过,事务终态却为需要恢复而非已回滚。
- 根因是终态判断先匹配所有失败结果,随后已回滚分支永远不可达。修改后,只有恢复核验成功且锁释放成功才记录已回滚,并复用现有中文恢复完成提示;部署任务仍保持失败。
- 补充双目标成功恢复、恢复核验失败、文件回滚失败、锁释放失败、部分目标连接失败场景。没有创建辅助验收脚本。
- 这不是旧事务的自动修复:旧数据不重写,现场锁不移除。崩溃后的站点基线验证、锁归属证明和历史现场接管仍需继续整改与实机验证。
- 修改前检查点为
c96cd43;第一次推送认证失败,第二次推送成功。最终测试、构建与部署状态以本批后续收尾记录为准。
最新任务状态(2026-09-30,双服务器候选部署完成)
- 本轮代码提交
07229ad已推送;正式 Linux amd64 候选包build/acceptance-20260930-smail/Scert-20260930-V0.1.0-linux-amd64.tar.gz已构建并完成归档校验。 - 已使用密码 SSH 将候选包正式安装到
8.137.23.95和45.136.13.241;两台服务器的 Scert、Scert-storage.socket、Nginx 均为 active,管理入口/readyz与基础 HTTPS 校验通过,未关闭 TLS 校验。 - 本条只记录候选包和基础服务部署证据,不将其当作 Smail 发信、清库首次初始化、多服务器业务推送或最终生产门禁通过。
- 当前继续执行:清库并重新初始化、Smail SMTP 验证码和密码重置、多服务器多域名推送、失败恢复与重试幂等、三数据库和 Windows 服务矩阵。
Smail 系统通知通道收敛专项(2026-09-30)
- 代码层识别 Smail
notify:系统通知账号,并固定使用notification+system@邮件域名作为 SMTP 发件身份;不使用管理员邮箱替代。 - 证书任务通知和超级管理员验证码在该账号模式下都只调用 SMTP,不调用普通 HTTP 发信接口;验证码收件人仍严格限定为当前绑定邮箱。
- SMTP 未启用时返回明确配置错误;未关闭 TLS 校验,未记录 SMTP 密码、验证码或其他真实凭据。
- 通知专项、后端全量测试、静态检查和构建均已通过;本记录仅证明代码候选通过,尚未证明远端 Smail SMTP 参数、验证码、密码重置和生产上线流程通过。
- 代码、构建和双服务器基础安装已完成;下一步按生产流程清理测试数据后验证发信与密码重置;总体验收继续保持 P0-03 完成、等待复审。
恢复标准 Nginx 重载命令后正式页面复测(2026-09-30 17:39 UTC)
- 通过正式服务器配置页面将临时测试用的重载命令
/usr/bin/true恢复为标准 Nginx 参数nginx、-s、reload,保存提示“服务器配置已更新”。 - 通过正式页面对
scert-multi-20260930.apmmk.cn执行“部署证书”,结果为“证书部署完成:1 台推送成功,站点 HTTPS 校验通过”;服务器结果为证书部署、配置校验并 reload 成功。 - 本轮未创建辅助验收脚本,未改变 SSH 主机指纹校验,未清理业务数据;本地 Git 工作区保持干净。
- 结论:临时重载命令已恢复,单服务器标准部署路径复测通过;不代表后置 HTTPS 失败自动恢复、进程崩溃事务自动接管、真实多服务器和最终清库首次生产流程已经通过。
陈旧部署锁清理后正式页面复测(2026-09-30 16:55 UTC)
- 通过 SSH 核查
scert-multi-20260930.apmmk.cn目标目录中的cert.pem.scert-lock、fullchain.pem.scert-lock和key.pem.scert-lock:三个均为空目录,创建时间早于本次任务;同时确认没有活动 Scert、SSH 或 SFTP 部署进程,Scert与nginx均为 active。 - 按允许的现场清理范围,仅使用
rmdir删除上述三个已确认陈旧且为空的锁目录;未删除证书、私钥、Nginx 配置、业务数据或证据目录中的历史中断现场。 - 通过正式页面重新部署
scert-multi-20260930.apmmk.cn,页面显示“证书部署完成:1 台推送成功,站点 HTTPS 校验通过”;服务器结果显示证书部署、配置校验并 reload 成功,域名状态恢复为“正常”。 Scert、Scert-storage.socket、nginx均为 active,公网https://odacm.cn/readyz返回{"service":"scert","status":"ready"};两个测试域名 HTTPS 均返回 200。scert-20260930.apmmk.cn目标证书和公网证书 SHA-256 指纹均为5DE99CD681FB8A84745CE4ED6091D76A7B86616421B3048D3C42844B8A4460ED;scert-multi-20260930.apmmk.cn两者均为43063C0726D34362B254CE28B66D7EB637E00B165F68EC0D07FCED0DF2C64AD2。两个目标托管目录无.scert-lock、.scert-backup-*或.scert-tmp-*残留。- 结论:陈旧锁人工核查、清理后的正常恢复路径通过;不代表后置 HTTPS 失败自动恢复、进程崩溃事务自动接管、第二台真实服务器、多服务器任务或最终清库首次生产流程已经通过。
SSH 密码部署公钥、密钥回连及后续部署复测(2026-09-30 23:55)
- 通过正式服务器配置页面临时使用已授权的密码保存服务器配置;Scert 自动生成服务器专属托管密钥,通过密码 SSH 将公钥写入远端
/root/.ssh/authorized_keys,随后关闭密码连接并使用托管私钥执行true回连验证。 - 页面服务器状态由“已配置,待验证”更新为“已部署并验证”;托管私钥指纹为
SHA256:iDWSQY7LgGdy6aYb47C0TMvZfktJxrfjVSGYLFrqhoc,远端ssh-keygen -lf /root/.ssh/authorized_keys -E sha256查询到相同指纹。 - 远端授权目录权限为 700,
authorized_keys权限为 600;主机指纹仍为已核对的SHA256:cVoSXsYmhALjAdN2Gso3JvbnvYQCQBFuRv3IZjFvzsE,未关闭 SSH 主机校验。 - 自动切换为私钥认证后,通过正式页面再次部署
scert-multi-20260930.apmmk.cn,页面显示 1 台推送成功、站点 HTTPS 校验通过;配置校验、reload 和两个域名 HTTPS 200 均保持正常。 - 结论:单服务器“密码首次接入—自动部署公钥—私钥回连—后续密钥部署”闭环通过;不证明第二台真实服务器、多服务器任务、后置 HTTPS 失败自动恢复或最终首次生产流程已通过。
3cc8fb6 正式候选双域名正常部署复测(2026-09-30 23:42)
- 使用密码 SSH 连接 45.136.13.241,未使用密钥登录,未创建辅助验收脚本;线上运行程序为 3cc8fb6,管理入口重新登录成功。
- 通过正式页面对
scert-multi-20260930.apmmk.cn执行“部署证书”,页面结果为“1 台推送成功,站点 HTTPS 校验通过”;服务器结果为证书部署、配置校验并 reload 成功。 Scert.service、Scert-storage.socket和nginx均为 active,/readyz返回{"service":"scert","status":"ready"},活动任务为零。scert-20260930.apmmk.cn公网与目标证书 SHA-256 指纹均为5DE99CD681FB8A84745CE4ED6091D76A7B86616421B3048D3C42844B8A4460ED;scert-multi-20260930.apmmk.cn公网与目标证书 SHA-256 指纹均为43063C0726D34362B254CE28B66D7EB637E00B165F68EC0D07FCED0DF2C64AD2。- 两个域名真实 HTTPS 请求均返回 200;
/ssl下两个托管目录没有残留.scert-lock,证书权限保持公有证书 644、私钥 600。 - 结论:本轮证明
3cc8fb6的正常双域名部署闭环,不证明后置 HTTPS 校验失败自动恢复、进程崩溃事务自动接管、真实多服务器和最终清库首次生产流程已经通过。
固定诊断版本部署与锁测试收尾(2026-09-30 22:55)
6efc89061b干净源码正式构建部署;归档 SHA256 为 443cd7db2a98832c5b1d2eb5d27b0ee704192c5be97ddd0f7585531008c13b5c,主程序 SHA256 为 ee0a5a98c993eb8f512cb53936dd05e0fde079505d2ea78af8f2cde24cbe220f。- 保留已有数据与证书,仅升级及负向复测,不作为最终清库首次流程。复用隔离证据中的空锁进行锁冲突测试,没有新增辅助脚本。
- 失败任务 d6b3be69-c4e1-4a10-b86d-70b8809fcfd8:页面与部署结果接口均显示固定中文核查提示;接口返回 200,不泄露底层错误或凭据。
- 空锁已移回原证据目录;22:52 确认活动任务为零,原六项证据仍保留。正式页面重新部署任务 179bb071-486d-4356-8ba2-e15ce1164eb5 成功,页面两域名均正常。
- 22:55 核对目标目录无锁;两个站点真实 DNS、可信 TLS 请求均返回 200,公网指纹分别为 5DE99CD681FB8A84745CE4ED6091D76A7B86616421B3048D3C42844B8A4460ED、43063C0726D34362B254CE28B66D7EB637E00B165F68EC0D07FCED0DF2C64AD2。
- 本节只证明诊断与正常重新部署,不代表崩溃事务自动恢复或后置 HTTPS 失败自动恢复已完成。
真实部署中断与人工恢复(2026-09-30 22:35)
- 候选仍为 91e1123。沿用已有证书和数据执行破坏性中断验证,没有清库,不能替代最终首次生产流程;未新增辅助验收脚本。
- 通过正式服务器配置接口临时设定校验命令为有界延迟后执行 nginx 配置校验,重载命令保持正常。22:25:00 从正式页面触发第二域名部署,任务 8aa3db95-ab7a-4559-a558-a1a9c8fa5f00、尝试 656a9679-33ab-458e-bcbe-2ed6694735eb 均为 running,远端可见 sleep 45 进程及三个部署锁和对应事务旧文件。
- 首次 systemctl 命令使用当前系统不支持的参数,未终止进程;确认任务与延迟进程仍活动后改用该系统支持的 --kill-who=main。22:25:30 SIGKILL 主 PID 81906,22:25:31 systemd 自动启动 PID 83070,NRestarts=1。不是空闲服务重启,也没有将首条失败命令记为成功。
- 任务恢复为 failed/service_restart,尝试为 failed,task_recovery 审计为 failed;三者旧提示均为“服务重启导致任务中断,请重新执行”。无自动重新签发或重放远端命令。
- 22:26:42 重新登录后通过产品接口恢复 nginx -t 与 nginx -s reload。延迟进程已结束;远端保留三个锁和三个事务旧文件,nginx worker 未变,新旧 cert/fullchain/key 逐一内容一致。
- 22:27:09 产品直接重试,任务 0d6dfdf0-65a0-4af5-8544-0f9c3b604018 失败,接口 502,没有误报成功;原有脱敏只显示“证书部署失败”,不能告知用户遗留锁原因。
- 确认活动任务为零、延迟进程结束、目录真实路径正确、三个锁为空且非符号链接、新旧文件一致后,将六个现场项目移到 /ssl/scert-interruption-evidence/8aa3db95-ab7a-4559-a558-a1a9c8fa5f00。受限目录权限 700,私钥旧文件 600;未删除文件、未自动抢占未知锁,也未覆盖另一域名文件。
- 22:28:14 正式产品接口部署已有证书,任务 800815bd-7fcd-4262-87c0-63fd6174dd29 成功,返回 verification_status=success。22:33 再查主服务、目录 socket、nginx 均 active,活动任务为零,目标目录无残留锁;两域名正常 TLS HTTPS 200,公网指纹各自保持与托管证书一致。
- 结论:启动任务恢复、遗留锁拒绝和人工核查后重新部署取得证据;远端自动回滚及自动解除崩溃事务未实现。已开发固定阶段安全诊断及中断核查提示,尚未部署,不能将本次人工恢复记为自动恢复通过。
- 22:41 开发回归完成:后端全量测试及静态检查退出零,部署、仓储、应用、接口四包竞态通过,前端 240 项通过;开始干净源码正式构建,构建通过不替代实机复测。
单台服务器双域名闭环(2026-09-30 22:18)
- 新域名 scert-multi-20260930.apmmk.cn,资源 ID fd0b6b70-9cca-48d7-9d9f-40551cb95fc5,与第一域名关联同一服务器 3cfe6b82-6807-421d-88ab-a2034370375b。
- 仅新增独立 A 记录,记录 ID 2105298673814337536,TTL 600,未改原有泛解析。DescribeSubDomainRecords 返回未授权,改用产品已有授权的 DescribeDomainRecords 精确组合查询,没有扩权;确认新名称没有已有记录后才新增。
- 正式页面保存域名返回 201、绑定返回 200。22:10:38 任务 603a01dc-1557-4976-ae56-501c944493a4 实际执行 DNS-01;22:11:11 验证通过并清理挑战,22:11:13 签发成功。两台权威服务器查询挑战 TXT 均无返回。
- 产品创建 /ssl/scert-multi-20260930.apmmk.cn/single,三个目标文件与版本化托管文件哈希逐一一致;公有证书文件 644、私钥 600。第一域名三个文件哈希前后不变。
- 首次任务未误报成功:新域名尚无已加载的 Nginx 站点,默认 DNS 仍命中旧泛解析缓存,后置 HTTPS 报 tls: unrecognized name,任务为 failed。随后新增独立 Nginx 站点配置,nginx -t 通过;未覆盖旧站点。仅清本机解析缓存不能消除上游旧缓存,等待实际 TTL 到期,22:15:27 默认解析变为授权目标,没有固定 IP 或禁用 TLS 验证。
- 22:13 通过产品接口精确解除第二域名关联:第二域名服务器列表为空,第一域名仍关联原服务器,服务器总数仍为一;随后重新绑定第二域名,返回 200。
- 22:15:43 正式页面部署已有证书,任务 745a66ff-3b75-47ca-88fa-e4f101a9f879 成功,页面报告一台推送成功、站点 HTTPS 校验通过。
- 第二域名公网、托管和目标证书指纹均为 43063C0726D34362B254CE28B66D7EB637E00B165F68EC0D07FCED0DF2C64AD2;第一域名仍为 5DE99CD681FB8A84745CE4ED6091D76A7B86616421B3048D3C42844B8A4460ED。服务器端两站点和外部 Windows 客户端第二站点正常 TLS 访问均为 200。
- 无残留部署锁;主服务、目录 socket 和 nginx 均 active。没有创建辅助验收脚本;独立 Nginx 配置是实际证书消费端配置,不是测试替身。
- 该结果证明一台服务器多个域名及精确关联隔离,不证明一个域名多台真实服务器;后者仍缺第二台服务器。
新 DNS 候选部署与旧有效证书负向恢复(2026-09-30 22:05)
本轮为保留数据升级复测,不是清库首次生产验收。没有新增辅助验收脚本,没有关闭 TLS 或 SSH 身份验证;通过现有密码 SSH 会话运维。
正式包和部署
- 源码:91e1123fa688ac3660b0c8d0276ee562c3ef9a79,source_dirty=false;规范构建记录后端 549、前端 105 个文件换行检查,23 项清单与 22 个归档文件核对通过,五个执行入口权限 0755。
- 归档 SHA256:7b84e363db748be19a6c932c9cd4d4cd9fc3a409f3d67c3763310e1d8eaeb49f。
- 主程序 SHA256:7e3f07ab9998a43e6d0a3f647026c994e896af93a62ebe717061352e6fce5deb。
- 21:55 后在新目录解包并通过 SHA256SUMS,停止主服务和目录 socket 后执行包内 install-linux.sh,再启动服务;线上程序哈希一致。安装器自行保留旧发布文件,未额外制作备份。
- Scert.service、Scert-storage.socket、nginx 均 active;公开 readyz 返回 ready,管理入口 200;浏览器忽略缓存刷新后重新登录成功。
DNS 与旧证书负向
- 21:58 产品权限检查连续四次全部返回 200,报告 verified、writable、readable、cleanup 均为 true,随机后缀均为三十六位小写十六进制。该有限样本不证明所有网络超时已经消失。
- 22:00 临时将产品服务器重载参数设为 /usr/bin/true,配置校验仍为 nginx -t;22:01 通过正式页面申请同域新生产证书。
- ACME 复用已有有效授权,返回新证书;此次没有重新执行 DNS-01 挑战,不能把它算作新挑战全流程。DNS 写读清理由前述权限探测独立证明。
- 负向任务 d08caabd-ac44-4902-beea-a36f4f3d860c,尝试 9e23e034-0507-4b43-a3e9-91b99dac4469 均 failed;申请接口 502,页面显示“证书申请或部署失败”和域名错误。
- 新托管版本 20260930-V1.1 和目标文件指纹为 5DE99CD681FB8A84745CE4ED6091D76A7B86616421B3048D3C42844B8A4460ED;公网仍为 9A50D4A0E551EC728D4900E595029C52B4F5EDC9E24B518F123646289101FC53,worker 仍为 81412、81413。
- 服务日志明确六次 HTTPS 校验后仍为指纹不一致,而不是 DNS 或连接失败。旧有效证书未被判为本次部署成功。
恢复与边界
- 22:02 已通过产品接口恢复 nginx -s reload,再通过正式页面“部署证书”;任务 ed7770b0-bf23-41c9-b556-972d125c25cd 为 success,页面明确一台推送成功、站点 HTTPS 校验通过。
- worker 更新为 82219、82220;公网、目标、托管指纹均为上述新指纹;正常 TLS 的站点访问返回 200,无 .scert-* 残留。
- 本次证明后置 HTTPS 错误检测与恢复正常配置后重新部署,不证明自动运行态回滚;申请失败页面的通用错误尚未提供阶段诊断,不提前标记可观测性完整通过。
- 多域名、多服务器、任务恢复、数据库矩阵和最终清库首次初始化仍需完成。
DNS 标签整改本地验证(2026-09-30 21:48)
- 修改前检查点
0864300已推送。新增正式回归在旧代码下全部失败:随机后缀不是规定的三十六位安全编码,InvalidRR.Format 被误归入网络或权限通用提示。 - 记录名随机后缀改用十八字节密码学随机数的完整小写十六进制编码,TXT 随机值继续独立生成三十二字节,避免尾部连字符及大小写折叠问题,不依赖失败重试。
- 四类域名各三十二次回归检查后缀可还原十八字节、标签不超过六十三字节、范围不变、TXT 可还原三十二字节、调用顺序 add/describe/delete 不变。随机样本唯一性检查不是独立的熵证明;随机来源和完整编码由源码确定。
- DNS 包完整测试、静态检查和竞态通过;后端全量测试与静态检查退出 0。新修复尚未部署,不提前声明云端问题已复审解决。
重载失败恢复与新增 DNS 阻塞(2026-09-30 21:45)
- 21:33 正式页面部署已有证书成功,报告 status=success、verification_status=success,任务 fe00eb0d-dba8-400e-8c8a-852ab4abb451;页面区分推送与 HTTPS 验证。
- 21:38 通过服务器配置将重载命令设为 sh、-c、nginx -s reload && /usr/bin/false;不是新增辅助脚本。任务 76fd45fe-4495-4ae0-999a-c9107a274243 失败,Nginx 工作进程从 81047/81048 换为 81183/81184,证明重载已实际执行。
- 三个原文件 inode 2580557/2580558/2580559、大小、校验和与 644/644/600 权限恢复一致,无临时文件或锁;网站正常 TLS 返回 200。此处部署内容与原内容相同,仅证明文件回滚及错误状态,不证明新旧证书切换后的自动运行态恢复。
- 21:40 恢复正常重载命令并通过页面重新部署,任务 c0f2ad2c-7bdf-4ebc-8c93-71fe831c1869 成功;工作进程再次更新,公网指纹与托管证书一致。
- 为验证旧有效证书不能误通过,暂设不重载命令并尝试一次同域名签发;21:41 任务 3ba35861-151e-4157-9077-c35461582b0f 在 DNS 权限探测阶段失败,阿里云错误 InvalidRR.Format,未生成新证书,尚未进入 HTTPS 身份验证。
- 21:44 产品权限检查接口相邻两次返回成功与失败。失败记录名为 _scert-authorization-W_BjXXHEGzEC5CbAXQ6Tpw7-.scert-20260930.apmmk.cn.,首标签以连字符结尾;源码使用 RawURLEncoding 生成随机标签。继续整改该偶发格式问题,不能通过反复重试碰运气作为解决方案。
- 失败后已恢复服务器正常 nginx 重载命令并重新部署既有证书。没有修改受保护域或关闭 TLS 校验,未清库。
最新候选升级记录(2026-09-30 21:33)
- 源码 fc57b8e1da5f1e7e145ae191748451deabbea96c;规范克隆正式 Linux 构建成功,source_dirty=false,后端 548 个、前端 105 个受跟踪文件通过 LF 检查。构建后克隆无源码或锁文件差异。
- 清单 23 项大小和 SHA-256 通过;实际归档 22 个文件的名称集合、无重复项、内容哈希及五个执行入口 0755 权限通过。归档位于发布版本目录的父目录;首次核对命令误按版本目录定位归档,修正只读路径后通过,未修改产物。
- 归档 SHA-256:4efd67bccbb871f58ad5e0ec2197bc9131bdecfc1a215e070bfc5d7c1d89b23c;主程序 SHA-256:1d360b720f023f7511ee3f2d54f3a4e54ad74e9ac2fbb3a86b74cf664520d369。
- 密码 SCP 上传,严格主机指纹校验;远端归档哈希及 21 项 SHA256SUMS 通过。在 /tmp/scert-https-verification-20260930 使用正式安装器,先停止 Scert.service、Scert-storage.socket 和目录服务,升级后恢复主服务与目录 socket。
- 安装器保留旧发布文件于 /scert/.install-xPFV6M23;未新建独立远端备份或辅助验收脚本,未删除历史现场。升级后主程序哈希一致,两单元 active,公开 HTTPS readyz 返回 ready,浏览器忽略缓存刷新并重新登录成功。
- 上一批专项竞态全部退出 0:应用 98.960 秒、接口 231.215 秒、部署 13.850 秒。此前“竞态收尾中、未部署”属于历史记录,本节更新当前状态。
- 本轮是保留数据升级复测,没有清库,不代表首次初始化或完整生产门禁通过;正在验证新版本实际部署结果与失败恢复。
部署后 HTTPS 误报整改(2026-09-30,本地验证,未部署)
问题与修复
- 原验证器会验证证书有效期、域名与可信链,但工作流忽略其返回指纹;同域名旧证书仍有效时可直接成功。新增回归覆盖申请、部署已有证书、导入三条入口,旧指纹及空指纹均在修复前复现误成功。
- 原后置 HTTPS 报错只返回外层错误,report.status 仍为 success。修复前独立回归复现,修复后整体状态 failed,域名 error;单台推送结果保留原事实,不伪称文件推送失败或已回滚。
- 部署前校验本地证书、完整链与私钥,从实际文件获取指纹,不依赖 saved 元数据。远端仍沿用可信链校验,再比较指纹;不关闭 TLS 验证,不增加强制 IP 的生产验收绕过方式。
- 本地隔离测试使用临时证书与自有信任根启动真实 TLS 服务,旧有效证书触发重试,新证书才成功。该用例不是外部真实站点、多服务器或重载恢复验收。
部署报告补充约定
申请、部署已有证书、导入响应中的 deployment 新增可选 verification_status:success 表示站点校验通过且指纹相同,failed 表示校验失败或未能确认,省略表示未执行该阶段。旧响应无该字段时不能推断已经校验站点。
total、success、failed、results 继续记录每台服务器的文件推送结果;整体 status 还受后置校验影响。因此可能出现 success=1、failed=0,但 status=failed、verification_status=failed,这表示文件已推送但生效校验未通过,并不矛盾。前端需优先显示生效校验失败,不能单看成功数量或一台结果放行。
任务和尝试整体持久化为 failed;服务器结果表保留成功的文件推送记录。verification_status 当前随执行响应返回,不是新增数据库持久化字段,也不代表对每台服务器独立验证。
前端 239 项及生产前端构建、后端全量测试、静态检查通过。专项竞态结果待本批收尾;未部署本批代码。重载失败、后置 HTTPS 失败后的实际恢复、任务恢复、三数据库和首次清库流程继续保留待办。
最新构建验证记录(2026-09-30 21:07,未部署)
- 本轮沿用既有规范克隆,签出精确提交 9e89edae282d8c18ddf9588751961015d220efcf,正式发布入口输出到 build/review-release-eol,未覆盖历史包。
- Windows 和 Linux amd64 两个目标构建成功,清单 33 项产物大小及校验和通过;Windows 包 9 个文件、Linux 包 22 个文件,实际压缩包读取后的文件集合和内容哈希均与清单一致。Linux 主程序、三个运维程序及安装器权限均为 0755。
- source_dirty=false;后端 547 个、前端 105 个受跟踪文件通过 LF 策略检查;本轮完整后端测试、静态检查和前端 237 项测试通过,结束后源码及锁文件没有变化。
- 首次手工读取 SHA256SUMS 时未指定 UTF-8,导致 PowerShell 把中文文件名错误解码并报找不到路径;改为显式 UTF-8 只读检查后,Windows 8 项、Linux 21 项内容校验全部通过。未改写文件、未替换中文,也没有把核对命令错误当成产品缺陷。
- 21:03 在既有密码 SSH 会话只读核对,实际服务名 Scert.service 为 active,管理 readyz 为 ready;小写 scert 并不是该服务单元,不能据其 inactive 判断产品停止。
- 没有清库、重新初始化、升级服务器或注入新故障。本次仅完成本地正式包验证和线上健康只读检查,不代替实机生产流程。线上仍为此前验证的 0bb427d,新包身份见《构建版本与数据库支持矩阵》最新章节。
构建整改补充(2026-09-30 20:58)
本批只修改正式构建工具与回归,不修改应用业务代码,也未重新部署。修改前检查点 70f19d0 已推送。
- 原工作区正式工具链拒绝非规范换行,发生在依赖安装之前,没有自动改写中文文件。规范独立克隆则通过检查,后端 547 个、前端 105 个受跟踪文件采用允许的换行状态。
- 工具链 31 项、前端全量 237 项测试通过;新增真实 Git 夹具证明 Git diff 可忽略 CRLF,但正式入口仍退出 1,且不生成 node_modules 或锁文件。
- 20:58 管理 API 返回 401,明确提示重新登录,确认此前浏览器会话已失效;公开管理入口和就绪检查仍正常。未把未认证接口的错误当成有效任务列表。
- 后续需在规范克隆用本批提交完成正式发布构建。P0-03 目录边界复审结论不变;P0-04 整项及生产完整门禁仍未完成。
最新实机与复审记录(2026-09-30 20:53)
正式页面配置校验失败与恢复
- 20:06 确认 /etc/nginx/scert-acceptance-missing-20260930.conf 不存在后,通过服务器编辑表单将校验命令临时设为 nginx -t -c 加该路径;不创建辅助脚本、不修改真实 Nginx 配置,不停止站点。
- 20:07:25 正式页面部署已有证书返回 502,任务 434b370b-72a2-41fe-a507-fbc5abe955c9 为 failed,持久化结果记录尝试 10f6606c-3ce2-45bf-b5de-74164af80c11 失败。受保护服务日志明确记录“配置校验失败:退出码 1;文件已回滚”。页面使用脱敏通用失败提示,具体原因从受保护日志核对。
- 失败前后 cert.pem、fullchain.pem、key.pem 的 inode 分别保持 2580557、2580558、2580559,校验和均与成功签发时一致,权限为 644、644、600;目录仅剩这三个文件,没有部署锁、临时文件或备份残留。Nginx 主进程 823 和工作进程 80097、80098 未变,HTTPS 返回 200。
- 20:10:01 正式页面将校验命令恢复 nginx -t;20:10:44 再次部署返回 200、耗时 1375 毫秒,页面显示 1 台成功、域名恢复正常。文件 inode 更新为 2580560、2580561、2580562,内容校验和不变;工作进程变为 80397、80398,配置检查通过、HTTPS 为 200。没有再次申请生产证书。
- 20:49 再查服务 active、管理入口 ready、测试 HTTPS 200。浏览器会话随后已失效,读取任务接口未获得新的有效列表,未把此读取异常当成部署失败或伪造新的报告。
P0-03 当前源码独立复审
- 修改前检查点
1857d72首次推送认证失败,第二次推送成功。全程没有删除工作区既有文件。 - 20:48 从本地仓库独立克隆到 .runtime/source-boundary-review-20260930-2015,使用 no-hardlinks 并签出精确部署源码 0bb427d5f8e230e7f9b600dda5546ef7fdd59ddb;没有复制现有依赖、构建目录或运行配置。
- 正式 build-release.ps1 按锁文件安装前端依赖并构建 Linux amd64 发布包,source_dirty=false。Go 1.26.6、Node 24.19.0、npm 11.17.0;发布路径检查通过。
- 原工作区源码边界专项测试通过(1.251 秒),独立克隆发布模块完整测试通过(3.762 秒);测试核对仓库规则和实际索引,不依赖用户 Git 排除规则。
- 发布清单共 23 项 SHA-256 全部核对一致,Linux 目录共 22 个文件;包内仅正式可执行文件、安装器、服务与 Nginx 模板、中文部署说明及 Web 文件。未携带数据库、私钥、浏览器缓存、源码映射或依赖目录。首次检查误把克隆父目录 .runtime 算作包内容,已改按包内相对路径复查;这是核对命令修正,不是产品缺陷。
- 构建后独立克隆 git status 为空,锁文件差异为空。远端既有正式包 SHA256SUMS 再次全部通过,22 个文件;线上程序仍为此前已验证的 944f2f787089942dd33ffb8b6e1e721b9f624c37cec220c3ca4801ed4e637704。
- 独立克隆复审包归档 SHA-256 为 feb24b5876628e71ad6354063032b82845ef82628e7015e3be11a6697728980a,程序为 d854e343373c0ba15b50075f1b4a70470b413cfb46d11b7d59248b7c0ed13fc6。此包没有部署,不与线上候选混用。
- 结论:P0-03 的源码与产物边界复审通过;不外推为其他 P0 或生产功能全部通过。
新发现与剩余门禁
- 原工作区与独立克隆有 27 个前端输入原始字节不同,比较后全部仅为 CRLF/LF 差异;规范化比较没有其他内容差异。Git 的干净状态不能单独证明原始构建输入字节一致。P0-04 需增加构建前拒绝非规范换行的检查,不自动改写中文源码。
- 配置校验失败的文件回滚已验证,不代表重载部分执行失败、后置 HTTPS 校验失败或中途断电全部通过。
- 多域名、多服务器、任务恢复、三数据库与清库首次初始化仍待完成;当前仍不满足完整生产放行。
最新实机记录(2026-09-30 20:06,正式证书单台部署成功路径)
范围与发布身份
本轮保留失败现场进行正式升级针对性复测,不是清库首次初始化。复用已有服务器,没有创建重复服务器记录;测试域名和地址仅为本次输入,不硬编码为验收条件。未修改禁止操作的业务域名。修改前检查点 18bfd16 已推送。
- 正式源码:0bb427d5f8e230e7f9b600dda5546ef7fdd59ddb,构建清单 source_dirty=false。
- 发布归档 SHA-256:22b52ce1fb822c4e86ac91d27f207711331eeec820d21452870ea1ed68d39a34。
- 本地与远端主程序 SHA-256:944f2f787089942dd33ffb8b6e1e721b9f624c37cec220c3ca4801ed4e637704。
- 密码 SCP 上传、完整 SHA256SUMS 校验后使用正式安装器;服务、管理入口和就绪检查正常。SSH 严格核对已登记主机指纹,未关闭 TLS 验证。
签发、推送和消费端证据
- 测试域名:scert-20260930.apmmk.cn;域名 ID:dfcd80c0-1c58-4aa2-b156-d558d4d2b9a1;既有服务器 ID:3cfe6b82-6807-421d-88ab-a2034370375b。
- 19:54 第一次申请在权限探测阶段超时,HTTP 504,未进入 ACME;随后正式产品命令的 DNS 写入、读取、清理检查均通过,才执行下一次页面申请。不能把该超时解释成确定的 RAM 权限不足。
- 19:57:21 第二次页面申请返回 200,耗时 23219 毫秒;任务 fbefdb52-7fc0-4942-8512-850b0869c07d 为 success,消息为“证书申请和部署完成”。
- 正式任务部署结果接口返回成功,消息为“证书部署、配置校验并 reload 成功”,尝试 ID 为 538a69d5-b4e9-4ba9-9cbf-6b8db86d242e。
- 托管证书实际路径为 /ssl/scert/scert-20260930.apmmk.cn/single/20260930-V1.0/,不是无版本目录;目标为 /ssl/scert-20260930.apmmk.cn/single/。三个文件逐一 SHA-256 相同,私钥权限为 600。检查未发现残留部署锁或临时文件。
- 证书指纹:9A50D4A0E551EC728D4900E595029C52B4F5EDC9E24B518F123646289101FC53;托管接口、部署文件和实际 HTTPS 返回一致。
- 签发者为 Let's Encrypt YR2;有效期为 2026-09-30 10:58:47 UTC 至 2026-12-29 10:58:46 UTC;SAN 包含本次测试域名。
- Nginx 配置校验通过,11:57:20 UTC 存在 signal process started 重载日志;服务器和外部 Windows 客户端正常域名 HTTPS 均返回 200,没有使用忽略证书校验参数。
- dns21.hichina.com 与 dns22.hichina.com 的权威非递归查询均对本次 _acme-challenge 名称返回带 aa 的 NXDOMAIN;递归缓存的旧 TXT 不作为云端清理失败依据。
尚未通过的门禁
- [~] 正式页面失败回滚及恢复后重复部署。
- 一台服务器多域名、任务恢复、第二台真实服务器、三数据库及清库完整首次初始化。
- [!] DNS 偶发超时仍需评估;本次成功不证明所有网络失败场景通过,也不证明后置 HTTPS 校验失败时服务自动恢复。整体验收仍未放行。
最新实机记录(2026-09-30 19:43,授权探测及测试子域准备)
本轮继续保留现场的升级针对性复测,不是清库首次初始化验收。线上源码仍为 7147532,尚未部署本轮 DNS 修复。
- 19:25:28 页面创建域名失败,HTTP 400,耗时 2661 毫秒,报权限验证超时。
- 19:30:54 产品正式命令 dns check 在 scert-20260930.apmmk.cn 返回 writable/readable/cleanup/verified 均为 true。
- 19:32:01 正式页面创建域名 HTTP 201,耗时 2395 毫秒;域名 ID dfcd80c0-1c58-4aa2-b156-d558d4d2b9a1,关联既有服务器 HTTP 200。
- 实机发现初次请求遗留随机授权 TXT,创建时间与失败请求一致;精确核对后删除该测试记录,不修改其他 TXT。
- 云端实测确认 COMBINATION 按 RR 和类型过滤,EXACT 忽略这两个参数;本地 SDK 文档同样明确该语义。
- 通过阿里云官方 CLI 为新子域新增 A 记录;只修改明确授权测试子域,保留原有泛解析。CLI 来自官方发布并验证校验和,不是自建辅助验收脚本;临时凭据只在会话环境使用。
- [~] 真实证书尚未签发,本轮目录创建、文件推送、Nginx 和公网 HTTPS 未通过,不能标记完整生产验收成功。
最新实机结果(2026-09-30 19:20,SSH 自动部署通过一次复测)
候选身份与部署
- 源码:714753236f584a2bc705e271334c697dc7f9adbd,发布清单 source_dirty=false。
- 本地目录:build/release-ssh-reload-20260930/Scert-20260930-V0.1.0。
- 归档 SHA-256:716c5167bfb2532bc2276c84d1bf087cfd686e1cb736a2e18765a131f6c9855e,本地和远端一致。
- 主程序 SHA-256:a39c8b0beaf2dc31e3bdc3b2aa774651e6d8e934ab956058518b10f71d9daeb2,本地和远端一致。
- 密码 SCP 上传后在 /tmp/scert-ssh-reload-20260930 校验全部 SHA256SUMS,再使用正式 install-linux.sh。第一次因 Scert-storage.socket 仍在监听被安装器拒绝;停止相关服务后安装成功,Scert 与目录服务 socket 已恢复 active。
- 安装器自动保留旧发布文件于 /scert/.install-jD3pl0Pp,没有把该目录作为验收条件,也未擅自删除。未创建独立远端数据备份或辅助验收脚本。
页面、接口与目标机交叉验证
- 管理入口返回 200,healthz=ok、readyz=ready,正常域名 HTTPS 校验未关闭。浏览器忽略缓存刷新并重新登录,编辑既有服务器记录,没有新建重复资源。
- PUT /api/v1/servers/3cfe6b82-6807-421d-88ab-a2034370375b 于 11:18:58.026842 UTC 返回 200,耗时 1844 毫秒。
- GET /api/v1/servers 复读:auth_method=private_key,ssh_key_status=deployed,ssh_key_error 为空,ssh_key_deployed_at 和 ssh_key_tested_at 均为 2026-09-30T11:18:58Z。
- 目标机 SSH 日志:11:18:56.523794 UTC 密码认证成功,11:18:57.519436 UTC 收到重载信号,11:18:57.541562 UTC 恢复监听,11:18:57.890368 UTC 公钥认证成功;对应指纹存在于 authorized_keys。
- sshd -t 通过,公钥认证与密码认证均启用,Scert 与 ssh 均 active。Scert 只有在私钥连接执行 true 成功后才保存 deployed,本次页面结果和目标机日志一致。
验收边界
- 本批后端全量测试、静态检查、构建和三包竞态检查全部通过,不等同于外部数据库矩阵通过。
- 本轮保留现有数据库和失败记录进行针对性修复验证,不是清库首次初始化验收;未重新申请证书、未执行实际证书推送或 Nginx 重载/回滚,不重复沿用历史通过记录。
- 第二台真实服务器、域名服务器多对多生产推送、三数据库和最终生产门禁尚未完成。总体验收仍为 P0-03 完成待复审,不新增整体放行结论。
2026-09-30 19:10 现场证据补充
本地竞态检查已全部通过。远端密码 SSH 读取精确日志显示:SSH 于 10:27:40.559700 UTC 收到重载信号,Scert 于 10:27:40.566606 UTC 私钥连接被拒绝,SSH 于 10:27:40.583273 UTC 恢复监听。该次失败处于监听重建窗口;候选仍需补充公钥安装后有界重试,再构建部署复核。此处仅是历史失败日志的定位证据,不是重新通过生产验收。
最新状态(2026-09-30 19:08,SSH 修复候选本地验证)
- 已用密码 SSH 和严格已登记主机校验连接授权目标;只读执行服务状态及日志查询,Scert 和 SSH 均为 active。
- 本地默认单次协商回归通过;后端全量测试、静态检查及构建通过。
- [~] 竞态检查正在运行;候选尚未重新发布到远端。
- 自动密钥登录、真实证书推送与 Nginx 重载尚未取得本轮通过证据。
- [!] 下方历史记录保留原日期,不代表当前候选的验收状态。本轮未清库、未重启服务、未修改远端文件,不是首次初始化重测,不新增生产放行结论。
当前进展:发布说明修正与入口、依赖审计
2026-09-20 03:12 起接续,03:22 完成本节所列检查。本节为最新状态,下文按各自时间保留历史证据。实际仓库仍为 D:\Desktop\Scert,目标为 45.136.13.241,本次管理域名为 odacm.cn;这些测试参数不硬编码进产品,也不构成验收依据。本轮未登录服务器、上传产物、修改 DNS/Nginx、修改系统信任库或清空共享数据库,完整生产部署验收尚未通过。
需求与任务状态
- [✓] 接回 Windows 与 Linux 目标的两项
govulncheck,均已正常退出;没有重复启动未结束任务。 - [✓] 修改前检查点
71fe48c已推送,暂存区事先为空;旧补丁、二进制、脚本及历史构建目录全部保留。 - [✓] 修正
deploy/README.md:生产探测不再跳过 TLS,分别说明回环上游和正常 DNS 公开入口验证;统一标准443示例,旧8003/8004仅保留为自定义端口示例。 - [✓] 按当前实现修正 PostgreSQL 备份恢复说明,注明官方工具、版本、严格 TLS、同目标同对象清单限制及独立保护的集群资源,不扩大为灾难恢复已验收。
- [✓] 复核 Go/Wails 的
-trimpath和前端禁用源码映射,发布检查及 CLI 定向回归通过,已有 Linux 产物路径扫描再次通过。 - [!] SSH 新指纹尚未通过可信控制台核对;没有发送密码、更新
known_hosts或接受新主机身份。 - [!] 两家 HTTPS DNS 查询仍指向旧地址,当前入口 TLS 检查失败;不可用固定解析探测替代域名生产验收。
- [!] 本机 PowerShell 有效策略仍为
Restricted,没有修改或绕过;最新正式发布脚本、Linux 双层集成与部署流程仍未完成。
入口与主机身份
本机 Resolve-DnsName odacm.cn -Type A -DnsOnly 返回 198.18.1.249。严格 HTTPS DoH 查询 Cloudflare 与 Google 均返回 odacm.cn A 47.108.78.12、TTL 600,不是本次目标 45.136.13.241。这是两个递归解析器的当前观察,不宣称已直接验证权威 DNS;本机普通 DNS 的结果不能替代公共解析结论,也没有据此更改网络或 DNS 设置。
以下三项均已实际执行,无跳过证书验证:
curl.exe --noproxy "*" --fail --silent --show-error --max-time 15 https://odacm.cn/readyz
curl.exe --noproxy "*" --fail --silent --show-error --max-time 15 --resolve odacm.cn:443:45.136.13.241 https://odacm.cn/readyz
curl.exe --noproxy "*" --silent --show-error --max-time 15 --resolve odacm.cn:80:45.136.13.241 -I http://odacm.cn/
前两项返回 curl 错误 35:schannel: failed to receive handshake, SSL/TLS connection failed;第三项返回错误 52:Empty reply from server。只能说明本机所经网络路径上的请求失败,不能证明目标 Nginx 配置、服务状态或证书根因;透明代理等网络因素仍未排除。
03:21 左右,Paramiko 无认证握手读取到 Ed25519 指纹 SHA256:cVoSXsYmhALjAdN2Gso3JvbnvYQCQBFuRv3IZjFvzsE,authenticated=False。它与历史可信值 SHA256:XN9mJ75b4CJsFPZ7fbkAmU1yFxKZ4Tw01z8TN2EJMlk 不同;网络上反复读到同一新公钥不构成可信确认。须在服务商可信控制台执行 ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub 后核对,再决定是否认证。
依赖与回归证据
go mod verify
govulncheck ./...
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 govulncheck ./...
govulncheck -show verbose ./...
npm.cmd audit --omit=dev --json
go test -trimpath -count=1 -p=2 ./internal/releasearchive ./internal/cli
git diff --check
Go 命令在 backend 执行,npm 命令在 frontend 执行;Linux 环境变量一行是目标配置的简写,实际通过 PowerShell 子进程环境设置。go mod verify 返回 all modules verified。两平台漏洞扫描均报告调用路径零项、导入包零项、依赖模块一项;Windows 详细报告将其定位为 GO-2026-5932,涉及 golang.org/x/crypto@v0.56.0 中不再维护的 openpgp 包,无修复版本,当前代码未导入受影响包或调用其符号。没有为消除模块提示而移除仍需要的加密依赖,也不能将本结果描述成所有依赖完全没有已知风险。
前端生产依赖审计报告零漏洞,不包含开发依赖,也不代表未来漏洞保证。发布检查包与 CLI 回归均通过;真实 PostgreSQL 集成入口未提供官方工具和隔离环境参数,本轮不算新增真实数据库演练。部署说明的两个 JSON 配置块通过解析检查,差异检查无错误;没有在 Linux 上执行新文档中的 Nginx 配置或健康探测示例。
本地路径要求与产物边界
重新调用 scert-release --verify-only,对 .runtime/clean-path-artifacts-20260920-0243/ 的三个 Linux 程序与整个资源目录,以及 .runtime/app-integration-20260920-0307/app.test 执行构建标记和路径扫描,均通过。扫描参数包含当前与旧工作区、用户目录、实际 Go 工具链及缓存、Go/Node 安装目录与临时目录;这些参数不写入产物。已有 Web 产物未找到 .map 文件。
这两处是前序已生成的核验产物,本轮没有重新编译完整发布包,也没有把新部署说明复制到旧产物中;此前记录的摘要及源码版本边界继续适用。正式候选必须从最终提交重新运行完整发布脚本,生成清单和校验文件并通过同样检查后再部署。模块导入路径、相对文件名和运行时部署路径不等于本机构建绝对路径,裁剪要求不删除这些运行所需信息。
待解除的验收阻塞
- 通过可信控制台确认当前 SSH 主机身份;确认后先只读检查现场,不能沿用旧服务器 PID、端口或配置结论。
- 核对
odacm.cn的实际 DNS 配置与迁移范围,使其指向授权目标;分别验证权威/公共解析、本机解析及正常 DNS 的严格 HTTPS 入口。 - 在获准的构建环境运行完整发布脚本,并在隔离 Linux 单元执行五个应用与 Nginx 双层场景,确认没有跳过。
- 完成 root 辅助服务/systemd、中断恢复、最新候选部署、管理证书续期、目标推送、通知送达、升级回退与容量验收;未完成前不能宣告生产部署通过。
当前进展:真实应用与 Nginx 双层切换集成用例
2026-09-20 02:54 起接续。本节为最新状态,后续章节保留为历史证据。本轮没有登录服务器、部署程序、修改系统信任库、修改正式 Nginx 或清空共享数据库。完整生产部署验收尚未通过。
需求与任务状态
- [✓] 核对实际仓库
D:\Desktop\Scert,保留旧补丁、未跟踪二进制及历史产物;修改前中文检查点53ed3d6已推送。 - [✓] 延续用户要求,所有本轮 Go 测试及交叉编译均使用
-trimpath;最新 Linux 测试程序通过构建标记及本机构建路径扫描。 - [✓] 新增真实应用重建回归,验证 HTTPS、SQLite 和凭据存储重建后的就绪状态与数据库内容保留。
- 新增五个真实应用与 Nginx 双层集成场景,源码复审、交叉编译及 Linux 目标静态检查通过,等待 Linux 实际运行复审。
- [✓] 测试提交
c7d5344已推送;本节更新前已检查暂存区,仅包含三个新增测试文件。 - [!] SSH 主机身份变化仍未获得可信确认,没有发送密码或接受新指纹;远端部署继续等待身份核对。
- [!] 本机无可用 WSL、Docker 或 Podman;PowerShell 有效执行策略仍为
Restricted,没有修改或绕过策略,完整发布脚本仍待执行。
集成范围与边界
backend/internal/app/management_integration_test.go 复用正式 NewWithConfigPath、HTTP.ListenAndServe、SQLite 迁移和敏感信息存储,使用独立临时目录、随机回环端口和测试证书。跨平台用例关闭并重建应用,严格 TLS 探测 /readyz,同时检查预置数据库记录保留;没有访问真实 DNS 或申请证书。
management_nginx_linux_test.go 与 management_nginx_fixture_linux_test.go 通过正式应用适配器和 Unix IPC 连接独立 Nginx,覆盖以下场景:
- 正常双层切换,证书路径持久化,应用重建后保持已提交候选。
- 暂存已完成但应答丢失,回退代理,应用保持旧证书。
- 提交已完成但应答丢失,通过事务与实际双层证书核验确认成功。
- 暂存后恢复查询不可达,保留
prepared与代理staged,重建应用后恢复旧证书。 - 上游配置持久化并切换后,提交与恢复查询不可达,保留
upstream,重建后完成提交。
故障通过客户端包装层注入,不是真正丢弃网络帧或杀死辅助进程。应用关闭后由配置重建,使用实际恢复工作循环处理持久化事务;不等同于进程强杀、断电、固定生产 socket 或 systemd 服务重启验收。测试辅助服务与应用使用同一隔离 UID,不替代此前不同 UID/root IPC 边界用例。
每个 Linux 场景在独立子进程中通过 SSL_CERT_FILE 加载测试 CA,避免系统根证书缓存影响;没有给生产 API 增加信任注入接口,也没有关闭证书验证。独立 Nginx 开启上游可信链验证,只使用本轮配置、PID、版本目录和回环端口。重建前后均检查真实两层叶证书、协调记录、配置未被无关修改及数据库内容。
本轮执行证据
以下 Windows 本地命令已执行通过:
go test -trimpath -count=1 -p=2 ./...
go vet -p=2 ./...
go test -race -trimpath -count=10 -p=1 -run '^TestApplicationManagementListenerRestartsWithPersistentReadiness$' ./internal/app
go test -race -trimpath -count=1 -p=1 ./internal/app
新增真实应用重建测试首跑通过;连续 10 轮竞态测试包内用时 10.034 秒,应用包全量竞态测试包内用时 19.710 秒。Windows 全量测试不包含 Linux 专用用例。本轮未修改前端,未重复浏览器或前端构建验收。
Linux 目标 go vet -p=2 ./internal/app ./internal/nginxactivation ./cmd/scert-nginx 通过;最终测试源码调整后再次运行应用包 Linux 目标 vet 与交叉编译,均通过。最新测试程序为 .runtime/app-integration-20260920-0307/app.test,Go 1.26.6、GOOS=linux、CGO_ENABLED=0、-trimpath=true,SHA-256:
ce3a89d9450c88ffcdb0802234a757bbe0d8888e88f737a21e9427d5f19fca77
扫描覆盖当前与旧工作区、用户目录(包含实际 Go 工具链、模块缓存、构建缓存与用户临时目录)、常见 Go/Node 安装目录及系统临时目录,结果通过。该文件是测试程序,不是正式安装包,也没有 Linux 执行通过的证据;旧 .runtime/app-nginx-20260920-0303.test 保留,不作为最新用例产物。
下一步验收
- 通过服务商可信控制台核对
45.136.13.241的 SSH 主机公钥,再只读检查实际服务、DNS、端口、数据库和容量。 - 在非特权隔离 Linux 单元中显式指定
SCERT_TEST_NGINX_BINARY,执行应用双层集成测试,确认五个场景均实际运行、没有跳过,并重复执行检查稳定性。 - 验证独立 root 辅助服务初始化与 socket/service 模板,补齐进程强杀及 systemd 恢复证据。
- 执行完整发布脚本,生成具备清单、校验和且路径扫描通过的最新正式候选,再完成管理证书续期、目标推送、通知送达、升级回退与容量验收。
当前进展:辅助服务初始化、真实监听回归与干净源码路径复验
2026-09-20 02:25 至 02:47 接续。本节为最新状态,后续各节保留为历史证据;不把旧服务器记录当作当前环境。本轮仅完成本地修改、交叉构建和测试,没有登录服务器、部署程序、修改 Nginx 或清空数据库。
需求与完成状态
- [✓] 路径裁剪提交
a212401已推送;本轮再次复审发布入口与扫描器,确认 Go/Wails 使用-trimpath,前端关闭源码映射,归档前检查构建信息及本机构建路径。 - [✓] 修改前检查点
aa5d669与辅助服务提交d8b4850已推送。补齐 root 策略、安全初始化入口、systemd socket/service、中文部署说明与打包接线。 - [✓] 新增真实监听回归提交
549d6a832eec0cbc8dfeb01a43eea2eecfdba2fc已推送,远程 main 已核对一致;该提交也是更新本节前的检查点。 - [✓] 使用独立干净克隆重新构建三个 Linux 程序与 Web,全部通过路径扫描,构建标记为
vcs.modified=false。 - [!] 完整 PowerShell 发布脚本仍受有效执行策略
Restricted限制,本轮未改变或绕过执行策略;直接工具构建不等于发布脚本已验收。 - [!] SSH 主机身份变化仍未获可信确认,不能发送 root 密码或继续远端部署。完整生产部署验收尚未通过。
辅助服务与真实监听测试
scert-nginx --initialize 验证输入文件、可信路径、权限、证书链、两层实际 TLS 证书、就绪响应与 nginx -t,只在专用目录生成私有版本及引用。已有状态、链接、不可信路径或宽权限私钥均拒绝;初始化不覆盖、不重载,也不安装服务。普通安装器仍不启用该 root 辅助服务。
新增 socket/service 保持本地 Unix IPC 与唯一允许 UID,不给应用进程增加权限;辅助单元仅保留 CAP_DAC_OVERRIDE CAP_CHOWN,并依赖、跟随 nginx.service。模板与初始化已完成源码和交叉构建检查,尚无本轮目标 Linux/systemd 执行证据。
backend/internal/httpapi/management_session_integration_test.go 通过真实 Server.ListenAndServe()、临时 SQLite 及迁移、受保护凭据存储和严格 HTTPS 就绪探测覆盖三项:
- 独占会话中切换证书,只修改配置中的证书路径;监听器重建后保留新证书与数据库内容。
- 模拟证书配置已落盘而内存快照尚旧的中断窗口,拒绝继续协调;服务重建后从持久化配置恢复候选。
- 数据库关闭后,即使 HTTPS 仍可连接,就绪探测也必须失败。
三项首跑及连续 20 轮通过。HTTP API 全包竞态测试 go test -race -trimpath -count=1 -p=1 ./internal/httpapi 完成并通过,包内用时 67.667 秒。这是 Windows 真实上游监听测试,不是完整 Nginx 双层协调、进程强杀或 systemd 重启验收。
干净源码与产物证据
独立克隆 .runtime/clean-path-20260920-0243/ 对应提交 549d6a8,构建前后 Git 状态均干净。执行以下检查全部通过:
go test -trimpath -count=1 -p=2 ./...
go vet -p=2 ./...
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go vet -p=2 ./internal/app ./internal/nginxactivation ./cmd/scert-nginx
npm test
npm run build -- --outDir <独立新建目录>/web --emptyOutDir false
前两项为 Windows 本地执行;第三项仅为 Linux 目标静态检查。前端 54 项测试通过,生产构建无 .map 文件;本轮未修改页面,也未重复浏览器渲染验收。
.runtime/clean-path-artifacts-20260920-0243/ 保留三个 Linux 程序、Web、安装器、服务模板、Nginx 模板和说明,共 18 个文件。三个程序均由 Go 1.26.6 构建,-trimpath=true、CGO_ENABLED=0、GOOS=linux,内嵌提交为 549d6a8、vcs.modified=false。整目录扫描覆盖当前与旧工作区、干净克隆、产物目录、用户目录、Go/Node 安装目录、Go 缓存和临时目录,结果通过。
| 程序 | SHA-256 |
|---|---|
scert |
aadc2c3d08fc1ab0e466ac7f332dbe024bb17009553901bdb5d91f108d65c038 |
scert-admin |
f41cdc58721231512656bf1a41bc25faa671d7aef6d05955e0553111ff4604f0 |
scert-nginx |
42d957f5f0263419d8c3b0a935b5882b80b6be1ec81e11d2d82c6bdb83c5fca8 |
该目录没有正式发布脚本生成的 manifest.json 和 SHA256SUMS,仅用于核验,禁止当作正式安装包。路径扫描不会删除模块导入路径、相对源码文件名或运行时必需部署路径,也不保证识别源码中手写的任意其他机器路径。
三类 Linux 测试程序从同一干净克隆以 go test -trimpath -c 生成,保留在 .runtime/clean-tests-20260920-0246/:httpapi.test、nginxactivation.test、scert-nginx.test。仅交叉编译通过,尚未在 Linux 运行。前轮 .runtime/path-audit-20260920-0236/ 及其他旧产物全部保留,其 vcs.modified=true 标记不再作为新干净产物的证据。
连接边界与待验收项目
02:47 左右,无认证 SSH 握手取得 45.136.13.241 的 Ed25519 指纹 SHA256:cVoSXsYmhALjAdN2Gso3JvbnvYQCQBFuRv3IZjFvzsE,与历史可信值 SHA256:XN9mJ75b4CJsFPZ7fbkAmU1yFxKZ4Tw01z8TN2EJMlk 不同。Windows 自带 ssh-keyscan 因不支持服务器选择的 KEX 未取得公钥,随后使用 Paramiko 只完成握手与公钥摘要读取;没有认证、写入 known_hosts 或传送业务数据。网络上读取到的公钥不能自证可信,仍须在服务商可信控制台执行 ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub 核对。
- 获准执行完整发布脚本,生成带清单和校验文件的正式候选;不得以核验目录替代。
- 确认主机身份后只读检查现场服务、域名、端口、数据库及容量,不沿用历史部署参数。
- 在隔离 Linux 环境执行应用适配器、真实 Nginx 双层协调、root IPC、systemd、应答丢失及中断恢复测试。
- 完成最新候选部署、真实管理证书续期、目标机推送、通知送达、重启、升级与业务回退及容量验收。
当前进展:路径裁剪与本地发布检查
2026-09-20 接续。本节为最新状态,后文为各阶段历史记录。实际仓库位于 D:\Desktop\Scert,原 D:\Desktop\SSL 已不存在。本次修改前检查点 ba6c6d1 已推送;本节产物来自修改中的工作区,仅用于构建验证,不是正式可部署发布包。
需求与完成状态
- [✓] 按用户最新要求,Go 与 Wails 发布入口均使用
-trimpath,手动构建示例同步补齐;前端明确关闭源码映射。 - [✓] 发布检查读取每个 Go 二进制的构建信息,缺少
-trimpath=true时拒绝归档;扫描发布目录的全部文件,发现本机构建路径时拒绝归档。 - [✓] 扫描覆盖正反斜杠、JSON 转义、UTF-8、UTF-16 和跨读取边界;单元测试覆盖未裁剪二进制、静态资源残留、读取错误与缺失文件。
- [✓] 三处安装器及服务模板测试不再依赖编译时
runtime.Caller路径,支持go test -trimpath。 - [✓] Linux 发布入口补入
scert-nginx,归档可执行权限由实际二进制列表生成;单元测试和实际归档检查通过。普通安装器仍不安装或启用 root 辅助服务。 - [!] 当前主机禁止运行 PowerShell 脚本,完整发布脚本未实际执行通过;没有修改执行策略。语法检查通过,实际构建和扫描通过直接调用工具验证。
- [!] SSH 主机身份变化尚未确认,没有发送密码、上传文件、变更
known_hosts、重载 Nginx 或清空数据库。
本轮验证证据
- Windows 后端
go test -trimpath -count=1 -p=2 ./...全部通过。 - Windows
go test -race -trimpath -count=1 -p=1 ./internal/releasearchive ./internal/admin通过;桌面模块go test -trimpath -count=1 -p=2 ./...通过。 - Windows 与 Linux 目标的发布检查、安装管理包及发布命令
go vet通过;Linux 额外检查cmd/scert-nginx。这是静态检查,不是 Linux 测试运行。 - 前端 54 项测试通过,Vite 生产构建成功,无源码映射文件。
.runtime/path-check-20260920-0151/保留本轮 Linux 的scert、scert-admin、scert-nginx,Windows 的scert.exe、scert-admin.exe、ScertDesktop.exe和 Web 资源。- Wails 2.11.0 使用
-trimpath -nopackage完成 Windows 产物构建。为保留已有生成文件且避免依赖文件改写,本轮先构建前端,再传入-s -skipbindings -m -nosyncgomod;这不是完整发布脚本的桌面步骤验收。 - 六个二进制均通过构建信息检查;包含部署说明、安装器和服务模板的目录通过路径扫描,额外覆盖旧工作区和当前 Go/Node 安装目录。扫描检查本次指定的构建环境路径,不等于识别所有可能手写的任意机器路径。
.runtime/path-check-linux-20260920-0158.tar.gz为直接调用归档工具生成的验证包,确认三个 Linux 程序和安装器均为 0755。该包没有完整发布脚本生成的清单及校验文件,不用于安装。SHA-256:cda83659c0b8a6382efda4907b1adaa26170e35e4232e9bffc8c494407db7f4a。- 新交叉编译的
.runtime/nginx-request-trimpath-20260920-0158.test构建信息包含-trimpath=true,SHA-256 为ecfe71a2562fde94755339270988910e01b0ac76e2e21a2472e7e1484fc972cd。未在 Linux 执行;旧测试程序保留,不作为后续部署产物。
前序交接与下一步
接手时的源码检查点 822e204 已包含请求取消栅栏、请求编号恢复、辅助服务能力检查及应用 HTTPS 监听保护。本轮未重复将交接中的 Linux 交叉编译结果算作真实执行,也未重跑历史服务器夹具。
待从可信控制台核实目标 SSH 主机身份后,先核对现场服务、端口、DNS、数据库和容量,再执行隔离的 Linux/Nginx/Unix IPC 测试。仍需完成辅助服务安装策略与 socket 模板、真实应用配置持久化协调验收、正式候选构建、管理证书续期、目标机推送、通知、重启及升级回滚。当前未达到生产部署验收条件。
当前进展:受限本地激活服务与身份边界验证
2026-09-18 02:20 起接续,修改前检查点 cc94a61 已推送。本轮继续验证独立辅助服务,没有替换正式二进制、安装正式 socket、重载正式 Nginx 或清空共享数据库。代理模式续期仍在申请前拒绝,完整生产验收尚未完成。
已完成的修改
- [✓] 补齐受限 Unix socket 服务、客户端及独立 root 策略的测试;仅开放
ready/state/stage/commit/reconcile,请求不能指定命令或路径。 - [✓] 修复监听器异常关闭被误报为正常退出;请求校验失败也清理已解析的私钥切片,并清理编码、读取持有的帧缓冲。
- [✓] 策略加载增加 socket 父目录信任校验,覆盖非法 UID、地址、域名、权限、符号链接、硬链接、FIFO、超限及错误 JSON。
- [✓] 激活等待改为连续三次新连接的严格 TLS/就绪探测;补测新旧证书交替时需重新累计成功次数。
- [✓] 实际不同 UID 子进程验证授权与拒绝;伪装服务端即使将 socket inode 改为 root 所有,客户端仍通过内核身份拒绝,不发送请求。
- [✓] 继承 FD3 的子进程验证合法 Unix socket、错误 PID、错误 FD 数量、错误路径及 TCP 监听器拒绝,关闭不删除托管 socket。
验证证据
本地 go test -p=2 ./...、go test -race ./internal/nginxactivation -count=1 通过;竞态测试仅覆盖 Windows 通用代码。Linux 目标 go vet ./internal/nginxactivation ./cmd/scert-nginx、辅助命令构建及两类测试程序交叉编译通过。
远端测试程序位于 /scert/acceptance-20260917-1044/,同名本地文件位于 .runtime/;上传前后 SHA-256 一致:
| 文件 | SHA-256 |
|---|---|
nginx-ipc-20260918-0240.test |
0c41d5a0f0fd7990bb33377280af651054198529eef076adeedf7d0a3bd5d497 |
nginx-listener-20260918-0230.test |
c99dc7ef748ec8c6b3219859d7c070935c77312449b4338ce9e8539e28e3ea1e |
scert-nginx-ipc-20260918-0240.service 以 Scert 用户运行,私有网络与临时目录、只读系统、隐藏用户目录、禁止提权,限制 192 MiB 内存、禁用 Swap、CPU 50%、64 个任务。通过 InaccessiblePaths 隐藏 /scert/conf /scert/data /scert/log /scert/backups /ssl-scert-acceptance -/ssl。显式使用 /usr/sbin/nginx,以 -test.timeout=150s -test.count=10 连续十轮通过,退出零,运行 111.123 秒、CPU 7.418 秒、峰值内存 21.9 MiB。不同 UID 用例在非 root 单元中按设计跳过,在下列独立 root 单元中执行。
scert-nginx-listener-20260918-0230.service 使用同类非特权隔离,继承监听器五个场景连续三轮通过,退出零,运行 170 毫秒、峰值内存 6.1 MiB。
scert-nginx-identity-20260918-0242.service 是仅执行身份边界用例的临时 root 隔离单元,保持私有网络、私有临时目录、只读系统和正式数据不可访问,能力限制为 CAP_CHOWN CAP_SETUID CAP_SETGID CAP_DAC_OVERRIDE 并显式设为环境能力。设置 SCERT_TEST_ROOT_IPC=1,以 -test.run=^TestRootPeerIdentity$ -test.count=3 验证实际 UID 65534 的授权请求、UID 65533 的拒绝及非 root 服务身份伪装,全部通过,运行 310 毫秒、峰值内存 32.6 MiB。没有向正式 Scert 服务增加能力。
最终留档单元 scert-nginx-ipc-final-20260918-0244.service 使用相同最终测试程序再运行一轮,31 项顶层测试通过,仅 root 身份用例按设计跳过;该用例已在上面的独立单元通过。最终单元运行 11.094 秒、峰值内存 20.3 MiB,详细日志保存在 systemd journal,可使用 journalctl -u scert-nginx-ipc-final-20260918-0244.service 复核。
2026-09-18 02:42 结束检查:正式 Scert PID 589832、Nginx PID 578671、MySQL PID 589785 均未变化;正式程序 SHA-256 仍为 f5b08bf0fb88f7b19281e91f942aa2995866f96420e422c015890b841bae6366,Nginx 主配置及 Scert 站点摘要与本轮开始一致。最终测试与身份测试单元均已退出,PID 为零。nginx -t 通过,使用管理域名严格验证回环 TLS 后 /readyz 返回 200 和 ready。本轮不包含浏览器或新增公网验收。
失败与修复记录
初始测试单元因误写不存在的 /scert/logs 在执行测试前出现 226/NAMESPACE;核实正式日志目录为 /scert/log 后修正隔离参数。旧测试程序 nginx-ipc-20260918-0230.test 重复运行暴露应答丢失用例的抢锁竞争,以及真实 Nginx 单次探测成功后仍遇到旧工作进程。前者改为先确认暂存已获得锁再模拟应答丢失;后者加强连续探测并增加回归测试,而非简单增加测试超时。旧程序和失败记录均保留。
不同 UID 单元最初只设置能力边界,子进程在执行前报 operation not permitted;独立诊断确认有效能力中缺少 CAP_SETUID,setpriv 同样失败。显式设置所需环境能力后,同一测试程序通过,不将首次未进入校验逻辑的失败计为安全验证。
仍需完成
- 安装 socket/service、专用版本目录和目标站点 include;当前正式站点仍直接引用原证书文件。
- 应用持久化双层协调与启动恢复、完整生命周期串行化、应答丢失及中断恢复;目前不能自动处理任意应用崩溃窗口。
- 最新完整候选构建部署、管理证书续期闭环、目标机真实推送、通知送达、完整灾难恢复和容量验收。
前序进展:Nginx 证书激活事务组件实机验证
2026-09-18 01:45 至 02:03 本轮接续,修改前检查点 10645ea 已推送。本节为最新状态;本轮没有替换正式程序、重载正式 Nginx 或清空正式数据库,组件验证通过不代表完整生产验收完成。
已完成的修改与复审
- [✓] 探测仅允许规范化回环 IP、端口和具体管理域名;每次建立新 TLS 连接,严格验证可信链、域名和预期叶证书,并检查受限大小的 Scert 就绪响应。不使用环境代理,不跟随重定向。
- [✓] 激活器专用目录及父路径检查所有者、权限和符号链接;专用目录要求当前激活器用户所有且权限为 0700。仅例外允许 root 所有、带粘滞位的共享父目录,不允许其他可写父目录。
- [✓] 状态读取使用禁止跟随符号链接的文件打开方式,检查普通文件、文件身份、大小、所有者、写权限及硬链接数。新证书、私钥和事务快照以 0600 写入并同步。
- [✓] 切换前验证代理、上游和专用目录内旧材料一致;候选证书必须符合两侧信任配置、覆盖管理域名、处于有效期内并延长实际有效期。
- [✓] 专用 include 仅接受固定格式和随机版本目录,事务记录验证版本编号、引用和证书。切换、配置检查和就绪探测后重新核对 include,发现外部修改则拒绝覆盖或报告成功。
- [✓] 暂存只切 Nginx;上游切换后双层证书一致才允许提交。取消、检查失败、重载失败和探测失败进行有界回退;未完成事务可恢复,已提交事务不自动回退。日志写入失败不会被误报为成功。
验证证据
本地 go test -p=2 ./... 通过,未变更包使用 Go 缓存;go test -race ./internal/nginxactivation -count=1 通过,Windows 只覆盖通用探测代码。使用 Linux 编译目标执行 go vet ./internal/nginxactivation 通过。Linux 测试覆盖目录、文件、事务和受限命令实现。
最终测试程序为 .runtime/nginx-activation-20260918-0202.test,远端 /scert/acceptance-20260917-1044/nginx-activation-20260918-0202.test;两端 SHA-256 一致:26db07a3ed15f4324af4e742cd252e0e8700253b0543bee3757a13cc5845f796。此前两版测试程序保留,没有覆盖上传。
最终单元 scert-nginx-final-20260918-0202.service 以 Scert 用户运行,私有网络、私有临时目录、只读系统、隐藏用户目录、禁止提权;正式数据、配置、日志、备份及证书目录禁止访问。限制内存 192 MiB、禁用 Swap、CPU 50%、64 个任务和 120 秒运行上限。通过 SCERT_TEST_NGINX_BINARY=/usr/sbin/nginx 显式启用真实 Nginx 用例,执行 -test.v -test.timeout=90s -test.count=3:16 项顶层测试连续三轮通过,无失败、无跳过;运行 4.492 秒,CPU 1.102 秒,峰值内存 13 MiB,Swap 为零。
真实 Nginx 用例使用独立配置、PID、临时目录与随机回环端口,启动独立非特权进程;验证暂存重载、上游切换后提交、下一轮未提交事务恢复及实际入口证书。退出时等待独立 Nginx 正常终止,不操作正式 Nginx 服务。测试还覆盖跨进程锁互斥及释放后重新获取、候选错误、双层不一致、日志失败、模拟重启阶段、外部 include 或材料变更、符号链接、硬链接、FIFO 和可写父目录。
最初单元 scert-nginx-unit-20260918-0155.service 在测试开始前因 /ssl 不存在而出现 systemd 226/NAMESPACE;调整为 InaccessiblePaths 中 -/ssl 后,缺失路径可忽略,而现有正式目录仍强制隔离。后续单元 scert-nginx-unit-20260918-0156.service、scert-nginx-real-20260918-0159.service 及最终单元均退出零。
结束时正式 Scert PID 589832、Nginx 578671、MySQL 589785 与本轮起点一致。正式二进制摘要仍为 f5b08bf0fb88f7b19281e91f942aa2995866f96420e422c015890b841bae6366;Nginx 主配置和 Scert 站点摘要未变。nginx -t 通过,按管理域名严格 TLS 验证的回环 /readyz 返回 200 和 ready。最终隔离单元为 inactive、PID 为零;本轮未进行浏览器或独立公网探测验收。
接线前必须完成
- 独立受限辅助进程、受保护本地 IPC、请求身份鉴别及固定本地策略;不能将 Nginx 重载权限赋予 Scert 主进程,也不能通过 HTTP 接收任意命令或配置路径。
- 安装时将当前证书复制到激活器专用版本目录并生成 include;现有线上配置仍直接引用原证书目录,不满足组件专用目录契约,不能直接切换。
- 应用协调者持久化双层激活状态,处理上游已持久化但代理未提交、提交应答丢失、调用者退出及超时恢复;组件 Recover 只回退 Nginx,不替代上游配置恢复。
- 确认上述接线后再解除代理模式申请前保护,部署最新候选,继续真实目标机推送、通知送达、灾难恢复、容量及完整生产验收。
当前进展:Linux 测试隔离与跨平台路径复验
2026-09-18 本轮修改前检查点 5a96623 已推送。下方旧阶段的“当前进展”和待办按各自记录时间理解,以本节为最新状态;本轮没有替换正式程序,也不表示完整生产验收通过。
问题与修复
- [✓] 定位上一阶段管理任务测试的只读数据库错误:Linux
config.Default固定使用正式安装路径,HTTP 测试辅助函数仅传入临时目录并不能隔离数据库。现显式设置临时安装、配置、数据、日志、证书、备份目录及 SQLite DSN,不改变生产默认路径。 - [✓] 新增路径边界与数据库隔离测试,使用 SQLite
PRAGMA database_list核对实际打开的文件,并验证两个新数据库均为空且可分别写入相同任务 ID。 - [✓] 扩大全量测试后发现设置接口的保存失败用例以 Windows 反斜杠拼接路径,Linux 上未真正制造目录阻塞。该文件的路径拼接已改为
filepath.Join;重新验证了保存失败时凭据回退与令牌不消费。 - [✓] 已提交代码
c8c7121包含独立管理证书续期任务、调度接入、审计及通知;当前仍只接通直连激活,代理模式会在申请前拒绝,不能标记 Nginx 自动续期完成。
本地验证
go test -p=2 ./...
go test -race -p=2 ./internal/httpapi -run 'TestReadyTestConfig|TestTaskAPI|TestManagement|TestTLSCertificate' -count=1
go test -race -p=2 ./internal/httpapi -count=1
go vet -p=2 ./internal/httpapi
以上均通过。后端全量测试在隔离辅助函数修改后执行;随后设置测试路径修改由 HTTP 全量竞态测试覆盖,耗时 63.647 秒。格式检查无待格式化文件。
Linux 实机验证
测试以 Scert 用户运行,不清空或复用正式数据库。开启私有临时目录、私有网络、只读系统、隐藏用户目录和禁止提权;额外将 /scert/data、/scert/conf、/scert/log、/scert/backups、/ssl、/ssl-scert-acceptance 设置为不可访问,防止测试再次读取正式数据。测试只访问独立临时数据和本机隔离网络,不调用真实 DNS 或 ACME。
- 定向复验单元
scert-http-isolation-20260918-0126.service成功退出,覆盖原失败管理任务、任务 API、管理激活、TLS 与新隔离用例。 - 首次全量单元
scert-http-full-20260918-0128.service暴露上述 Windows 路径拼接问题,退出 1,原日志与测试程序保留。 - 修复后的全量单元
scert-http-full-20260918-0132.service退出 0:169 项顶层测试通过、失败零、跳过零。运行 12.976 秒,CPU 时间 6.416 秒,峰值内存 24.1 MiB,Swap 为零;限制为内存 192 MiB、CPU 50%、64 个任务、180 秒运行上限。
最终测试程序为 .runtime/http-isolation-20260918-0130.test,远端路径为 /scert/acceptance-20260917-1044/http-isolation-20260918-0130.test。两端 SHA-256 一致:2af3d17ba5bca2be1dd2052ddab8e5a836777caee1569a471d398f8cec8c1a5e。使用新文件名上传,没有覆盖原失败证据。
结束时测试单元为 inactive、PID 为零。正式 Scert PID 588768、Nginx 578671、MySQL 588722 与本轮检查起点一致;Scert 二进制摘要仍为 f5b08bf0fb88f7b19281e91f942aa2995866f96420e422c015890b841bae6366。这些 PID 与更早阶段不同,不能沿用旧记录声称跨阶段始终未重启。本轮没有执行正式服务重启。
nginx -t 通过,回环地址按管理域名严格验证 TLS 后,/readyz 返回 200、status=ready。Nginx 主配置与 Smail 站点摘要未变。入口仍为 web.apmmk.cn 的 80 跳转 443,443 反代本地 HTTPS 9004;本轮没有浏览器验收。
尚未完成的验收
- [✓] 本轮 HTTP 测试隔离和跨平台路径复审通过,不代表所有包的 Linux 全量测试已通过。
- 受限 Nginx 管理证书激活器、双层 TLS 就绪确认及失败回退。
- 包含管理存储隔离与续期调度的最新候选部署,以及真实目标机证书推送、通知送达、灾难恢复、容量和最终生产验收。
当前进展:管理证书存储隔离
2026-09-18 接续优化,修改前检查点 6d7972f、代码提交 ec432f0 均已推送。已修复同名业务证书更新可能清理管理入口引用目录的问题;正式程序尚未替换,本节不表示整体验收完成。
已验证的存储边界
- [✓] 新申请的管理域名证书存入
<证书根目录>/management-domain/<域名>/<类型>/<版本>,管理备份也使用独立的management-domain子目录;域名来自配置,不写死测试域名。 - [✓] 单域名、泛域名和 SAN 的管理申请与同名业务签发互不覆盖;业务当前证书读取不会选中管理候选。
- [✓] 兼容既有配置:通过服务启动配置中的管理证书或私钥路径保护旧业务目录中的引用,不迁移、不删除已部署的管理证书。
- [✓] 引用保护识别符号链接,不把相同字符串前缀的相邻目录误认为子目录;引用无法解析时,在备份或候选写入之前返回错误。
- [✓] 既有管理引用经过同名业务签发和导入仍保持全部文件字节不变;无管理引用的业务旧版本继续按原单当前版本规则清理。
- [✓] 无效管理存储根目录在凭据读取和外部调用之前被拒绝;阿里云保护域名检查仍优先执行。
验证证据
Windows 工作区执行以下命令全部通过:
go test -p=2 ./...
go test -race ./internal/certificate -run 'TestManagement|TestFileStore|TestServiceIssuesSetup|TestAliyun' -count=1
go vet -p=2 ./internal/certificate ./internal/httpapi ./internal/app ./internal/bootstrap
git diff --cached --check
从提交 ec432f0 对应源码交叉编译 Linux 测试程序,本地 .runtime/certificate-isolation-ec432f0.test 与远端 /scert/acceptance-20260917-1044/certificate-isolation-ec432f0.test 的 SHA-256 均为 e4828059a3deff60d86e4b39c1bc0f310785e395c185cf5c8b9ebf373f9465c8。
在真实 Linux 上,以 Scert 用户运行独立单元 scert-isolation-ec432f0.service:内存上限 128 MiB、禁用 Swap、CPU 50%、最多 48 个任务,开启私有临时目录、隔离网络、只读系统、禁止提权及隐藏用户目录。测试匹配上述定向表达式,包含 Linux 符号链接用例,全部通过且无跳过;单元退出零,运行 1.861 秒,峰值内存 7.8 MiB、Swap 为零。日志可通过 journalctl -u scert-isolation-ec432f0.service 查询。所有测试使用新建临时证书与目录,不访问正式数据库、真实 DNS 或 ACME。
结束时隔离单元 inactive、PID 为零;正式 Scert PID 579364、Nginx 578671、MySQL 549584 均未变。通过本机回环地址访问 Nginx 的管理域名、严格验证 TLS 后,/readyz 返回 200 和 status=ready,nginx -t 通过。此项是部署机回环复核,不替代上一轮独立 Linux 公网探测,也不代表新程序已正式部署。
剩余验收项
- 管理证书存储隔离及旧引用保护已完成本地与 Linux 组件复审,等待包含该提交的正式候选部署验证。
- 将管理证书纳入续期调度,补齐持久化任务、审计及通知;当前调度仍只处理业务域名。
- 在不扩大 Scert 服务权限的前提下接通 Nginx 证书更新,完成双层 TLS 激活、就绪等待和失败回退。
- 最新候选构建与 Linux 部署、真实目标机推送、通知送达、完整灾难恢复及容量验收。
前序进展:管理证书热更新
2026-09-18 接续优化,代码提交 9074d83 已推送;修改前检查点为 230cbaa。本节是续期基础能力的本地和 Linux 隔离验证,不是线上自动续期已完成。
已通过的组件检查
- [✓] HTTPS 服务使用不可变证书快照,新握手可加载更新后的证书,不需要重启 HTTP 服务。
- [✓] 新证书需通过私钥配对、有效期、管理地址覆盖和可信链校验;缺失文件、错误域名、过期、尚未生效及不可信链均拒绝,旧证书继续可用。
- [✓] 先持久化证书配置再切换内存;配置写入失败不修改内存证书和内存配置。
- [✓] 并发握手、无 SNI 的 IP 握手、显式回退和服务重启后读取新证书通过严格 TLS 验证。
- [✓] 管理证书申请保留旧版本目录,重复申请和初始化回退不会破坏先前引用的文件;普通业务证书仍保持原来的单当前版本规则。
- [✓] 修复新增证书解析步骤暴露的关闭顺序回归:已关闭服务再次启动优先返回关闭状态,不能重新监听。
热更新入口仅供进程内部调用,没有增加上传证书、任意路径或远程执行命令的 HTTP 接口。证书读取状态不再依赖业务域名列表,可供后续管理续期调度使用。
验证证据
Windows 工作区与提交内容一致,执行以下命令全部通过:
go test -p=2 ./...
go test -race ./internal/httpapi ./internal/certificate -run 'TestTLSCertificateRotation|TestManagementCertificatePreserves|TestShutdownBeforeStart' -count=1
go vet -p=2 ./internal/httpapi ./internal/certificate ./internal/app ./internal/bootstrap
git diff --cached --check
使用 Go 1.26.6 交叉编译两个 Linux 测试程序,上传前后 SHA-256 一致。远端文件均在 /scert/acceptance-20260917-1044/:
| 文件 | SHA-256 |
|---|---|
httpapi-tls-rotation-9074d83.test |
a3859533e83f7502f711c172481ebfb5f812ef3282c14d3b547e7eaa4b2e377e |
certificate-management-9074d83.test |
bed93ab19132f762ab013d5ca58f9f4354dd4f187f86b8a25df5cb5e3b6bd1a0 |
两个独立 systemd 测试单元以 Scert 用户运行,内存上限 128 MiB、禁用 Swap、CPU 50%、最多 48 个任务,并开启私有临时目录、只读系统保护及禁止提权。TLS 更新与关闭生命周期测试、管理存储与业务存储回归全部退出零;峰值内存分别约 8.7 MiB 和 7.2 MiB。测试使用全新临时证书与配置,不访问真实 DNS、ACME 或业务数据库。
线上 Scert 未替换二进制、未重启,仍运行此前版本。只读复核时 Scert PID 579364、Nginx 578671、MySQL 549584、8002 上的 Smail 574584 均未变化,管理 HTTPS 就绪响应仍正常。未清空共享数据库,未删除既有补丁、构建产物或服务器文件。
继续验收的门槛
- 将管理证书纳入续期调度,并补齐持久化任务、审计及通知;当前仍不是自动续期闭环。
- 管理候选证书与业务存储隔离,防止同名业务证书操作清理管理入口引用的路径。
- 在不扩大 Scert 服务权限的前提下接通 Nginx 更新,完成双层 TLS 激活、就绪校验及失败回退。
- 从最新已验证源码构建候选版本,再进行 Linux 部署、真实目标机推送、通知送达、完整回退与容量验收。
已通过:标准域名入口
2026-09-18 00:01 起,按用户确认改为复用已开放的 80/443,通过 Nginx 域名站点转发。以下结果覆盖旧 8003/8004 方案的公网入口阻塞,不改变管理证书续期等尚未完成事项的结论。
- [✓]
http://web.apmmk.cn返回 308,跳转到https://web.apmmk.cn,保留路径及查询参数。 - [✓]
https://web.apmmk.cn转发到https://127.0.0.1:9004,入口和上游均严格验证证书。 - [✓] 应用
server.proxy_https_port已改为 443;未改变上游监听端口、域名或数据库。 - [✓] 独立 Linux 主机
8.137.23.95通过正常公网 DNS 访问/readyz返回 200、status=ready,HTTP 跳转同样通过。未使用指定解析、隧道或跳过证书验证。 - [✓] 新域名地址的桌面浏览器登录、刷新、退出及 401 检查通过。此项使用独立 SSH 隧道和严格 TLS,证据目录
.runtime/apmmk-browser-20260918-standard/,与上一项公网协议测试分开记录。 - [✓] 原 8003/8004 已无监听;9004 仍仅回环监听。此前 UFW 放行规则暂保留,本轮没有删除规则或文件。
- [✓] 共享 Nginx 主配置和 Smail 站点内容未变;Smail HTTPS 返回 200、TLS 验证结果为零。
备份位于 /var/backups/scert-standard-20260918-0005-v2,含受限配置备份及原站点。只修改 Scert 站点,不新增重复默认站点。首次切换时立即探测收到 SNI 拒绝,脚本自动恢复旧配置;随后加入平滑重载后的有界就绪等待,第二次切换成功。Scert 为加载对外端口配置经过重启,旧会话需重新登录;未重启同机 Smail、MySQL 或 Nginx 主进程。
完成时 Scert PID 579364、重启计数零;Nginx 主进程 578671、Smail 574584、MySQL 549584 均与本轮开始一致。Nginx 配置语法检查通过,1440/1024 桌面测试无横向溢出、损坏图片或页面脚本错误。
Windows 本机直接访问仍出现 HTTPS 握手错误及 HTTP Server: Beaver 403,与独立 Linux 公网测试结果不同;该本地网络路径尚未定位,不宣称所有客户端网络均验证通过。本轮没有更改本机代理设置。
部署模板已改为共用端口的命名虚拟主机,外部完整地址使用 __MANAGEMENT_ORIGIN__ 占位符,默认测试值不再包含 8004。管理证书自动续期与双层 TLS 更新、真实目标机推送及完整故障回退仍需后续完成,本次仅完成用户要求的标准入口调整。
历史结论:管理入口接续验收
以下为 2026-09-17 23:16 至 23:35 的接续结果,覆盖后文早期阶段关于域名未确认、初始化未完成和入口未部署的旧状态。不能将各阶段的通过项混为完整生产验收。
需求与任务状态
已确认管理域名可配置,本次使用 web.apmmk.cn,Nginx HTTP 8003 跳转 HTTPS 8004,上游为 https://127.0.0.1:9004。实际仓库为 D:\Desktop\Scert,不使用已不存在的旧目录。
- [✓] 复核真实初始化与正式证书,上游严格 TLS 校验下就绪。
- [✓] 独立 Nginx 站点部署、主机防火墙放行、未知域名拒绝、HTTP 跳转及双层 TLS 校验。
- [✓] 隧道访问线上站点的桌面浏览器登录、刷新会话、退出及接口鉴权测试。
- [✓] 六组跨域写入拒绝、退出后旧 Cookie 重放拒绝。
- [✓] Scert 开机自启已启用;未重启共享主机,不能视为重启演练通过。
- 通用反代配置样例和部署说明已补充,等待整体生产复审。
- [!] 公网 8003/8004 在独立 Linux 主机访问超时,需核对云安全组或上游网络。
- [!] 管理证书未进入续期队列,且尚无上游 TLS 与 Nginx 的证书更新生效机制。
- 真实目标机证书推送、完整故障回退、通知送达与容量验收仍需完成。
已核对的运行版本
正式程序来自已推送提交 b6d1b96426437df412b508e2bfff06b1dde02871。其阿里云修复使用限定域名及精确 TXT 记录查询,以兼容当前 RAM 权限,同时对 DNS 主机名进行不区分大小写比较,记录 ID 和 TXT 内容仍严格匹配。本阶段没有再次替换正式二进制。
23:30 重新计算正式程序 /scert/scert 的 SHA-256 为 f5b08bf0fb88f7b19281e91f942aa2995866f96420e422c015890b841bae6366;升级前快照 /var/backups/scert-pre-dns-b6d1b96/snapshot.tar.gz 的摘要为 5dae6d9444768243a9440e69dfaf41870cbbc2a85702d2d8923579763ca77715。
当前管理证书为 Let's Encrypt YR2 签发,主题 web.apmmk.cn,有效期截止 2026-12-16 14:14:04 UTC。上游及 Nginx 探测均使用公共 CA 和主机名验证,没有使用跳过证书验证选项。
本阶段延续已完成初始化的独立测试数据集,没有清空数据库或重跑初始化。管理员密码仅保留在管理机 root 可读的受限凭据文件中,不进入代码、报告和截图。
反向代理部署
新增 /etc/nginx/conf.d/scert-apmmk.conf,保留 /etc/nginx/nginx.conf 与 smail.conf,部署前后内容摘要一致。配置备份位于 /var/backups/scert-nginx-20260917-2320-v2。第一次配置因本机参数传递导致空字符串引号损坏,被 nginx -t 拦截并移出有效加载目录,未重载;修正后语法检查成功才平滑重载。
8003 对已配置域名返回 308,示例路径 /login?acceptance=1 正确跳转至 https://web.apmmk.cn:8004/login?acceptance=1;未知域名返回 404。8004 的未知 SNI 拒绝握手。已配置域名通过 proxy_ssl_verify on 和 proxy_ssl_name web.apmmk.cn 验证 9004 上游,保留 Host $http_host 中的外部端口。
UFW 新增 TCP 8003、8004 的 IPv4/IPv6 入站规则;9004 仍只监听回环地址。Scert.service 此前为 disabled,现已执行 enable;Nginx 原已启用。没有重启 Scert、Smail、MySQL 或主机。
23:30 状态:Scert PID 576928、重启零;Nginx 主进程 PID 575746;Smail PID 574584、重启零;MySQL PID 549584、重启一。应用进程均与本阶段开始时一致。
浏览器与安全测试
本轮没有可调用的浏览器 MCP,使用独立 Playwright Chromium 上下文作为替代。新建上下文并禁止 Service Worker,不复用旧缓存。通过本机回环 SSH 隧道连接线上 Nginx 8004,浏览器 URL、TLS SNI 和证书校验仍使用真实管理域名;没有忽略 HTTPS 错误。这是线上应用测试,不是公网入口测试。
通过真实表单登录、页面跳转、刷新后会话保持、设置和用户等只读接口访问、退出、退出后 401 检查。Cookie 为 Secure、HttpOnly、SameSite=Lax、路径 /。1440 和 1024 桌面宽度没有横向溢出、损坏图片或页面脚本错误;截图仅代表这些桌面尺寸,不代表移动端验收或完整视觉复审。
本地证据目录 .runtime/apmmk-browser-20260917-2330/ 含 result.json、login-1440.png、dashboard-1440.png、dashboard-1024.png,保持 Git 忽略。脚本不把管理员密码或 Cookie 写入结果。
远端协议脚本 apmmk_security_acceptance.py 使用严格 TLS 测试三个错误 Origin:异域、缺失外部端口、错误协议。对设置写入及退出各测试一次,共六次均为 403,且原会话仍有效;正常退出后重放原 Cookie 为 401。
100 次就绪请求、并发四,全部返回正常;中位约 28.57 毫秒、P95 约 38.91 毫秒。测试前主机可用内存约 779 MiB、Swap 使用约 155 MiB。这仅是短时只读探测,不替代签发、部署、数据库写入或持续负载的容量测试。
当前阻塞与续期风险
Windows 本机 DNS 返回代理软件虚拟地址 198.18.0.51,默认访问失败,不能据此单独归因服务器。另从目标机 8.137.23.95 只读访问管理机公网,两个端口均连接超时;指定真实 IP 的 HTTPS 再测也超时。同期管理机监听与 UFW 正常,短时抓包未捕获该外部连接。当前证据提示云安全组或其他上游网络限制,尚未读取云安全组规则,不能断言已定位唯一原因。本次在目标机只执行网络探测,没有部署、清库或重启操作。
续期 API 实际返回 checked=0、selected=0;域名列表为空。源码核对表明 IssueForSetup 只保存管理证书,而当前调度器遍历托管域名仓库;HTTP 服务调用静态 ListenAndServeTLS,Nginx 也引用固定版本路径。因此证书有效不等于管理证书能够自动续期。必须补齐续期调度、证书事务切换、双层 TLS 更新、失败保留旧证书和恢复验证后再解除该门槛。
历史阶段记录
范围与任务状态
2026-09-17 在管理机 47.108.78.12 执行当前版本的受控测试。8.137.23.95 仅为推送测试机,本记录不包含对它的操作。不运行固定安装器,不切换正式服务,不清空既有数据库,不修改共享 Nginx 或业务证书。
- [✓] 密码 SSH 登录并通过已有主机密钥校验。
- [✓] 核对管理机服务、工具、空间和健康接口。
- [✓] 独立干净克隆构建 Linux 包,本地与远程归档、测试程序 SHA-256 一致。
- [✓] PostgreSQL 18 第一轮超时后完成资源故障取证、残留集群停止及受限七场景重测。
- [✓] Linux Bootstrap 测试包及服务配置测试通过;修复地址族白名单后,候选程序加固启动、HTTPS 协议及重启失效检查通过。
- [✓] 初始化前三步的桌面浏览器检查、提示修复和 SMTP 输入框裁切复测通过;未完成整个初始化流程。
- [!] 授权 DNS 签发、初始化完成、正式切流和业务推送未验收。
发布来源
候选源码提交:8990710ee145809eb3a937d3b4eb578adbdeb3fe。发布清单 source_dirty=false,两个程序均内嵌相同提交及 vcs.modified=false。构建工具链为 Go 1.26.6,目标 linux/amd64,CGO_ENABLED=0。
本地发布目录:build/linux-production-20260917-1040/。远程独立目录:/scert/acceptance-20260917-1044/。前端 39 项自动化测试通过,依赖安装审计为零漏洞;这些不是浏览器验收。
| 产物 | SHA-256 |
|---|---|
release.tar.gz |
3eee5a62403d6dadcc1f36e105de8cfa1684f65b688af7a1e898c7269e475344 |
cli.test |
7bf731c5dade9ceb24f385dd0bb4c54d1809e3e6a9400c710ecfe871c9de1d1f |
本地发布清单 14 项与包内校验清单 12 项通过。远程两项上传文件哈希及解压后的 12 项校验通过,安装器 bash -n 通过,候选程序返回 Scert 0.1.0。归档成员清单只含相对路径下的普通文件及目录,可执行程序和安装器为 0755。
实机初查
10:43 至 10:44,通过可信 SSH 通道获得:
- Linux
7.0.0-29-generic,x86_64,根分区剩余约 28 GiB。 Scert.service为active/running,用户Scert,PID530794,监听127.0.0.1:9004。- 已有 PostgreSQL
18.6官方工具,既有数据库端口5432不作为测试目标。 /healthz为 HTTP200;/readyz为 HTTP503,原因setup_incomplete。- 正式 ACME 目录正常 TLS 校验下为 HTTP
200,TCP 约0.206秒、TLS 约0.484秒。此前网络超时本次未复现,但目录可达不代表签发通过。 - 在用
/scert/scertSHA-256:ce2438fdddb1e471184d42ec98374abe1e96f74d3687ec60ad493eb659d5eb43。
测试执行与异常
远程测试命令先在新目录解压,执行包内校验、安装器语法检查、版本检查,然后以 Scert 用户运行 TestPostgresRealBackupRestore。测试使用 /usr/lib/postgresql/18/bin,产物根目录为 /scert/acceptance-20260917-1044/postgres-artifacts,测试超时为五分钟。
该测试自行创建回环随机端口集群、每场景全新数据库、SCRAM 密码和严格 TLS;不接受业务 DSN,完成时停止自己的集群并保留产物。
10:50 左右尚未收到测试命令结果,另建 SSH 连接在协议 banner 阶段超时。约 10:53 原连接收到测试退出码 2:成功恢复与证书失败回滚场景打印检查通过;第三个 cancel 场景尚在初始备份清单检查时触发总超时,栈位于 validateBackupManifest 的 Lstat,还未进入取消注入阶段。其余四场景未执行。不能将该结果归因为取消回滚逻辑故障,也不能报告整轮通过。
测试产物:/scert/acceptance-20260917-1044/postgres-artifacts/scert-postgres-integration-2406225956/。总超时导致测试清理回调不保证执行,随后只读检查请求也出现 Timeout opening channel。已请求仅停止该目录中的隔离集群,停止结果仍待确认。未向既有 PostgreSQL 服务或正式 Scert 发送停止命令。
恢复连接后必须先核对本轮测试进程、postmaster.pid、端口、系统负载及原服务状态,再决定是否重试。保留所有产物,不重跑解压命令覆盖已有目录,不在连接不稳定时继续启动额外测试负载。
资源故障恢复与受限重测
以下为 11:04 之后的续测结果,补充并更新上节当时尚未确认的状态。
- 主机约 1607 MiB 内存、无 Swap。内核在 11:00:20 记录全局 OOM,MySQL 被杀死;同时存在 journald、logind watchdog 超时。该证据确认系统发生内存故障,但不能仅凭受害进程或单次堆栈认定某个测试是唯一来源。
- MySQL 自动恢复为 PID
549584,重启计数为 1;正式 Scert PID530794未变。未重启这些服务,未调整 Swap、MySQL 配置或其他项目的资源设置。 - 核对首轮隔离集群目录、PID
549227及端口44387后,使用该集群的pg_ctl -m fast -w -t 30 stop正常停止;数据库与测试产物保留。既有 PostgreSQL 端口5432未操作。 - 测试辅助配置降低至
shared_buffers=16MB、work_mem=1MB、maintenance_work_mem=16MB、max_connections=32,禁用并行 worker。该变更只作用于新建隔离集群,不调整业务 PostgreSQL。 - 使用独立 systemd 临时单元串行运行:
MemoryMax=180M、MemorySwapMax=0、CPUQuota=50%、TasksMax=64、RuntimeMaxSec=300、KillMode=control-group、OOMPolicy=stop,并设置GOMEMLIMIT=32MiB、GOMAXPROCS=1。这些是本轮小数据演练参数,不是生产容量建议。 - 11:08:00 至 11:08:07,七个真实场景全部通过,用时 7.23 秒,单元退出码为 0。产物目录为
postgres-bounded/scert-postgres-integration-710949348;测试程序 SHA-256 为634666af045474b7dcec8f4b6c9eb325ef3fd95a28b628a2c388bbd304472f2e。 - 此后内核另有其他项目测试单元的
CONSTRAINT_MEMCGOOM,不能记为本轮 Scert 测试或新的全局 OOM。共享机器仍需协调测试负载,不能因本轮通过就认为容量问题已消失。
加固启动缺陷与新候选
旧候选在保留地址族白名单的真实 systemd 环境中启动失败:route ip+net: netlinkrib: address family not supported by protocol。原因是初始化临时证书读取网卡地址需要 AF_NETLINK,原 unit 只允许 AF_UNIX AF_INET AF_INET6。此前单元测试只校验原有文本,未发现实际系统调用受限。
修复提交 5573c64b209eae391c77f2a476ccc6784fd5b2e2 同步更新生成式 unit 和 deploy/systemd/Scert.service,仅增加 AF_NETLINK;新增发布 unit 的安全属性断言。主服务仍为 Scert 用户,capability 集为空,保留 NoNewPrivileges 和其他加固;超级管理员恢复服务仍限制为本地 IPC,未增加网络地址族。
新候选从独立干净克隆构建:
- 本地:
build/linux-netlink-20260917-1119/Scert-20260917-V0.1.0-linux-amd64.tar.gz。 - 远程:
/scert/acceptance-20260917-1044/release-netlink/。 - 归档 SHA-256:
d592bf5753e88326de9b7ab7986338f07e92028743e75f4c1a9e9e2eb2f8a544。 - 清单
source_dirty=false,程序内嵌vcs.modified=false和上述提交;本地清单、远程上传哈希及包内 12 项校验通过,安装器语法检查通过。 - 本地 CLI 与 servicehost 回归通过;Linux 原 Bootstrap 测试包通过,峰值内存约 16 MiB。新增 servicehost Linux 测试(含发布 unit 断言)也全部通过。Bootstrap 测试内部的 DNS/签发替身不代表真实外部签发。
- 11:22:21 至 11:22:27,使用新候选 CLI 再跑七个 PostgreSQL 真实场景,全部通过,用时 6.91 秒,退出码 0;新产物为
postgres-bounded/scert-postgres-integration-1008171600。取消场景仍采用测试程序进程内确定性注入,其他 CLI 场景使用新包中的可执行文件。 - 本地追加执行 Bootstrap、servicehost、管理员恢复和归档模块回归,全部通过;
git diff --check无格式错误。
候选程序实际协议检查
使用新候选程序、全新隔离配置和 SQLite,监听 127.0.0.1:19017,保持非 root 与系统加固。由于 Linux 初始化地址固定写入 /run/scert/bootstrap-url,测试单元使用私有 /run 及 BindPaths 将独立目录映射到该路径,不写正式运行目录。不运行固定安装器、不替换 /scert/scert。
通过项目:
- 从可信 SSH 日志取得当前启动证书指纹,与实际 TLS 证书匹配;之后所有业务请求严格验证证书及 IP。探测证书时不发送令牌、Cookie 或业务请求。
- 初始化页面和构建 JS/CSS 返回有效内容;这只是协议与资源检查,不是浏览器渲染验收。
- 未登录的设置接口返回 401;跨域令牌兑换返回 403;正确令牌兑换成功后重复兑换返回 401。
- Cookie 具有
Secure、HttpOnly、SameSite=Strict,路径限定为/api/v1/bootstrap;令牌文件为0600,URL 查询参数不携带令牌。 - SQLite 写权限验证通过;缺少 DNS 令牌返回 400,随机无效 DNS 令牌返回 422;配置字节不变,不伪造初始化完成。
- 重启本轮候选单元后,临时证书和一次性令牌均轮换,旧令牌及旧 Cookie 返回 401,新令牌可兑换。
- 停止本轮候选单元后,端口不再监听,程序正常清理自己的初始化地址文件。隔离配置、密钥及测试产物保留在受限目录,禁止提交 Git。
协议检查脚本保留在远程 bootstrap_protocol_netlink_v2.py,不含固定密码或 Token;测试使用的临时令牌和随机管理员密码仅在内存中处理。第一次脚本把缺少 DNS 参数的预期码误写为 422,修正为 400 并单独增加无效令牌 422 检查后整轮通过,未因此修改应用校验规则。
11:24 收尾确认:没有本轮 PostgreSQL 进程残留,19017 无监听;正式 Scert 仍为 PID 530794、重启次数 0,MySQL 仍为 PID 549584、重启次数 1;正式程序 SHA-256 与初查一致。正式就绪接口仍报告 setup_incomplete。当时 MemAvailable 约 215 MiB,主机容量风险仍需持续监控。
桌面浏览器修复与最终候选复测
11:36 起继续使用独立本地配置和远端隔离目录验证,未清空业务数据库。浏览器测试连接本机 Windows 候选,Linux 实机测试通过 SSH 执行真实协议请求;二者不能混称为远程浏览器全流程验收。
修复与证据:
4993199:邮箱每 250 毫秒自动同步会清除全局错误,导致数据库未验证提示一闪即逝。自动同步现在保留错误,手动编辑仍可清除;新增回归先失败后通过。同步修复用户名与邮箱输入框上边缘错位,补齐数据库字段标识。f0c735a:SMTP 固定四列在窄桌面裁切密码框,改用自适应网格,并补齐 DNS 明文复选框标识。1024×768 与 1440×900 的控件边界测量、实际截图检查通过。0bee64c:真实浏览器发现数据库验证成功后仍显示此前的数据库步骤错误。只在验证成功时清除两类数据库提示,不清除密码等其他错误。新增三项回归后前端共 44 项全部通过;真实浏览器确认验证前错误持续显示、成功后错误消失且成功提示保留。
最终候选源码为 0bee64ce8607831d025df8ea1ef52e39b57d026f,从独立干净克隆构建,清单 source_dirty=false。本地归档为 build/linux-db-message-20260917-1220/Scert-20260917-V0.1.0-linux-amd64.tar.gz,SHA-256 为 5a0b74167961cae3cbab9f7e47052df61ecf47c2c96584255c7c3842e470cb2a。新 JS 为 index-DYAdDhBP.js,CSS 为 index-B53m06GR.css。
最终本地浏览器使用全新配置、数据库路径和 Chrome profile,监听 https://127.0.0.1:19027。先核对日志证书 SHA-256,再仅允许匹配 SPKI 的临时证书;没有全局忽略证书错误。页面实际加载新 JS,SQLite 在线写权限验证通过。两种桌面宽度下所有 SMTP 输入和下拉框均在标签与面板内,无整页横向溢出。截图保留于 .runtime/browser-20260917-1223/smtp-1024.png 和 smtp-1440.png,均已实际查看。此前版本的 SMTP/HTTP 必填提示与 DNS 缺凭据阻断也已检查;没有提交真实 DNS 凭据或发起 ACME 签发。浏览器另记录一条表单字段缺少标识的非阻断提示,未将其宣称为已解决。
最终 Linux 归档上传至 /scert/acceptance-20260917-1044/release-message-0bee64c.tar.gz,解压到独立 message-0bee64c/release。归档哈希、包内 12 项校验、安装器语法和程序版本检查通过。候选单元 scert-message-0bee64c.service 保留发布加固,限定 MemoryMax=96M、MemorySwapMax=0、CPUQuota=25%、GOMEMLIMIT=48MiB、GOMAXPROCS=1、RuntimeMaxSec=900,使用私有 /run 映射,不替换正式程序。
首次紧接启动执行协议脚本时未及时读到证书指纹而退出;候选就绪后重跑全部通过,没有为此放宽证书校验。通过项包括当前构建资源、严格 TLS 指纹、未登录 401、跨域兑换 403、一次性令牌不可复用、安全 Cookie、SQLite 写权限、重启证书与令牌轮换、旧会话失效及配置字节不变。脚本分别保留为远端 linux_message_candidate.py 和 linux_message_protocol.py。
约 12:22 收尾确认:最终 Linux 候选已停止、PID 为 0、19017 无监听;正式 Scert PID 仍为 530794、重启次数 0,MySQL PID 仍为 549584、重启次数 1;正式程序哈希不变。MemAvailable 约 320 MiB。正式 /readyz 仍为 setup_incomplete,共享机器的历史 OOM 和容量风险尚未解除。
尚未满足的生产准入条件
桌面浏览器前三步已部分验收,但合法授权域名与 RAM 的 DNS 写入清理、ACME 签发、初始化完成到正式入口的切换、登录与多用户、升级回退、目标机证书推送及最终业务访问仍未完成。本轮没有操作 8.137.23.95,没有改动 pcux.cn 及其子域。继续外部签发前需明确可写测试域名与凭据授权范围,SSH 密码不等同于 DNS 授权。正式服务仍返回 setup_incomplete 时不可正式切流;受控隔离测试通过不能替代上述验收。
账户边界修复与续测
12:30 至 12:50 继续审查用户管理、登录和修改密码,完成以下项目:
- [✓]
60b00f1修复用户管理可修改主超级管理员数据库行却不更新配置的问题。新增回归先复现用户名、邮箱、密码修改返回 200,以及新增第二个超级管理员返回 201,修复后均拒绝。 - [✓] 按已确认的单超级管理员需求,禁止通过用户管理新增或提权为超级管理员;禁止通过该接口修改主账号。既有历史账号不自动删除,不修改正式数据库。
- [✓] 主账号登录只接受配置凭据,数据库残留凭据不能取得随后立即失效的会话。保留持当前密码的自助改密;真实 SQLite 回归检查配置与数据库摘要一致、旧会话失效、旧密码拒绝、新密码登录及重建服务后的会话有效。
- [✓] 本地后端 HTTP API、仓库、认证、CLI、归档五个包回归通过;前端共 47 项测试通过。
- [✓] Linux 执行账户相关 9 个顶层测试及 5 个字段子场景全部通过,退出码 0。独立 systemd 单元限制 96 MiB、CPU 25%、无交换、单 Go 线程配额;运行 5.556 秒,峰值内存 17.7 MiB。测试程序 SHA-256 为
24e779f320228b2c4afe2abcc5c781c2bcc0a490f502a6c49371d2a53a9226dd。这是实机运行的自动化测试,不是生产账号全流程验收。 - [✓] 真实浏览器发现用户管理依赖父组件的作用域样式,弹窗实际落在普通文档流中且按钮无样式。
a3d0f6c在用户管理自己的 CSS 中补齐遮罩定位、表单、按钮和响应式约束。 - [✓] 最终发布资源使用本地只读界面夹具、独立 Chrome profile、端口 19028 验证。1024×768 和 1440×900 下弹窗为 620×439,8 个控件和按钮均在弹窗边界内;主账号没有编辑、禁用和删除按钮,新增角色没有超级管理员选项。两张修复后截图均已查看:
.runtime/users-browser-20260917/create-fixed-1024.png、create-fixed-1440.png。夹具不是正式后端,不能据此宣称浏览器完整登录或写入通过。
最终候选从独立干净克隆构建,源码为 a3d0f6c,清单 source_dirty=false。本地归档 build/linux-users-ui-20260917-1245/Scert-20260917-V0.1.0-linux-amd64.tar.gz,SHA-256 为 92b5d22b44a1b1a91ef6ba62eea9d48faebace26cc04e892aa230368e32f30ec;资源为 index-DsUM7ZTg.js 和 index-C7wT0wtw.css。远程归档及包内 12 项校验通过,独立目录为 /scert/acceptance-20260917-1044/users-ui-a3d0f6c/release。
最终候选在发布 systemd 加固基础上使用私有运行目录、96 MiB 内存上限和 CPU 25% 配额,实际启动通过。严格 TLS 指纹、新构建资源、未登录 401、跨域 403、一次性令牌、安全 Cookie、SQLite 写权限、重启证书及令牌轮换、旧会话拒绝、配置字节不变全部通过。未发起 DNS 或 ACME 操作。辅助脚本为远端 linux_users_ui_candidate.py 和 linux_users_ui_protocol.py。
12:50 收尾确认:本轮两个 Linux 候选单元已停止,19017 无监听;本地夹具及专用 Chrome MCP 已停止,SSH 已关闭。正式 Scert PID 530794、重启次数 0,MySQL PID 549584、重启次数 1,正式程序哈希未变;正式 /readyz 仍为 setup_incomplete,可用内存约 313 MiB。升级回退、真实 DNS 签发、完整初始化与切流、目标机推送及业务验收仍未完成。原有测试产物全部保留。
安装失败回退修复与发布包续测
12:54 至 13:11 审查安装升级流程,修复提交为 8c3d8786808cd142229af4b1c6422e9d638aa0c0。修改前检查点 9d3bd50 和修复提交均已推送。没有在宿主机直接运行固定路径安装器,没有停止或替换正式服务。
缺陷与修复
旧包在真实 Linux 文件系统上复现四类问题:既有 Web 符号链接在二进制已经替换后才拒绝;二进制目标为目录时错误返回安装成功;第二个 unit 写入失败与 daemon-reload 失败均留下新旧发布文件混用。旧包四场景测试整体退出码为 1,不是成功验收。
新安装器提前检查文件和目录类型,保留 root 所有、0700 的 /scert/.install-* 副本;捕获安装失败后恢复发布文件并重新加载 systemd,不启动服务。Web 改为整目录替换,旧文件和失败现场只移动保留、不删除。回退自身失败时明确提示禁止启动服务。业务目录权限规范化、用户创建、断电和 SIGKILL 不在自动回退保证内,安装成功后的数据库迁移也不由此机制恢复,详见运维说明 4.2。
隔离方法与结果
使用仓库 deploy/tests/install-linux-test.py,在私有挂载命名空间中将新建测试目录映射到固定的 /scert、/etc/systemd/system 和本机既有 /ssl-scert-acceptance。源码以只读挂载保留,执行前核对挂载 inode。systemctl 被限定为测试桩,只允许状态检查和 daemon-reload,不能操作宿主服务。使用已有 Scert 用户,不创建新的宿主账号。
第一版脚本因宿主 /ssl 不存在在预检阶段退出,未执行安装器;随后显式指定已有证书挂载点,并把产物放在被覆盖路径以外的 /var/tmp/scert-installer-20260917-1303。所有产物保留。受控单元限制 MemoryMax=96M、MemorySwapMax=0、CPUQuota=25%、TasksMax=32、RuntimeMaxSec=180,与候选服务顺序执行。
最终发布包八场景均通过,整体退出码 0:
| 场景 | 安装器预期退出码 | 最终产物子目录 |
|---|---|---|
| Web 符号链接拒绝 | 1 | web-link-y4ivfj_n |
| 二进制目标目录拒绝 | 1 | binary-directory-o3gvmqpe |
| unit 写入失败后恢复旧版 | 43 | unit-failure-4c4c8ou_ |
| reload 失败后恢复旧版 | 42 | reload-failure-bffej3sp |
| 回退 reload 再失败,明确禁止启动 | 42 | rollback-reload-failure-qrwm_v37 |
| 升级成功,旧 Web 资源退出生效目录 | 0 | success-cgz9m71a |
| 首次安装失败,发布文件回到缺失状态 | 43 | fresh-failure-y_2axidy |
| 首次安装成功 | 0 | fresh-success-e7foazs_ |
每场景检查业务文件内容与证书文件不变、旧发布文件恢复、服务文件恢复或缺失状态、升级副本权限及服务操作白名单;各目录包含 report.json 和 output.txt。这是隔离文件安装与故障注入回归,不能等同于真实 systemd 升级、正式数据库迁移或完整业务回退验收。
新包与通用检查
- 独立干净克隆:
C:/Users/ikun/AppData/Local/Temp/scert-installer-20260917-1306,源码8c3d878,清单source_dirty=false。 - 发布包:
build/linux-installer-20260917-1306/Scert-20260917-V0.1.0-linux-amd64.tar.gz。 - SHA-256:
9c89140467264ee620bcd1ab4ba4fcea6a43430a4ea87fa6c7f91fa3be97c6ea。 - 远程:
/scert/acceptance-20260917-1044/installer-8c3d878/release;归档哈希、包内 12 项校验、安装器语法及版本检查通过。 - Windows 本地执行
go test ./...、go test -race ./...、go vet ./...、go mod verify全部通过;前端 47 项测试通过。不能将这些表述为 Linux 全量测试。 govulncheck ./...及详细扫描退出码 0:调用符号和导入包无已知漏洞,依赖模块包含GO-2026-5932,涉及未维护的golang.org/x/crypto/openpgp,当前代码没有导入或调用该漏洞包,公告没有可用修复版本。不能写成依赖模块零漏洞。- 新候选
scert-installer-8c3d878.service使用发布加固、私有运行目录和 96 MiB 限制启动;严格证书指纹、当前资源、未登录 401、跨域兑换 403、令牌不可复用、安全 Cookie、SQLite 验证、重启证书与令牌轮换、旧会话失效和配置字节不变均通过。没有 DNS 或 ACME 操作。本轮不涉及页面修改,未重复浏览器渲染测试。
13:09 收尾检查:候选服务 inactive、PID 0、19017 无监听;正式 Scert PID 530794、重启次数 0,MySQL PID 549584、重启次数 1,正式程序 SHA-256 未变。可用内存约 314 MiB。正式回环端口 9004 使用 HTTP,先用 HTTPS 探测返回协议错误,改用实际 HTTP 后 /readyz 明确返回 setup_incomplete;这不是正式 TLS 验收。SSH 已关闭,所有测试进程结束。
- [✓] 安装器缺陷复现、修复、新发布包八场景复测及受限候选协议检查。
- [✓] 本地全量测试、race、vet、模块完整性及漏洞调用路径扫描。
- [!] 真实 systemd 升级与业务回退、DNS 签发、完整初始化、正式切流和目标机推送仍未完成。继续外部签发需要用户明确授权测试域名及 DNS 凭据范围,当前不可宣称具备正式切流条件。
安装前停服状态核验补充(2026-09-17)
现场恢复与需求
- [✓] 原工作目录
D:/Desktop/SSL已不存在;当前项目在D:/Desktop/Scert,起始提交仍为cf1fe15,已跟踪文件无改动。未移动、删除或覆盖既有未跟踪产物。 - [✓] 修改前创建并推送中文检查点
f04f873。 - [✓] 管理机只读复核:正式 Scert PID
530794、重启次数零;MySQL PID549584、重启次数一;候选服务停止;正式程序摘要与前轮一致。 - [!] 正式
/readyz仍为 HTTP 503、setup_incomplete。管理机 443 由 Smail 占用,最终入口方案需要协调,不可直接占用或停止该服务。
缺陷与复现
旧安装器将 systemctl is-active 的所有非零退出都当成已停服;不能区分过渡状态和查询故障。使用旧包 8c3d878 在私有挂载命名空间注入启动中、停止中、主服务查询失败和管理服务查询失败,四个场景都错误返回零并替换隔离目录中的发布文件。
首次测试因产物目录不存在在预检阶段退出,没有执行安装器;创建全新产物目录后完成上述四场景复现。证据目录 /var/tmp/scert-install-state-before-20260917-1530,测试整体退出码一。路径中的时间后缀仅为标识,不代表实际执行时刻。
修复与验证
安装器改为显式检查六个 systemd 属性,未知状态和查询失败均拒绝。回归覆盖原八场景以及 active、activating、deactivating、reloading、failed 但仍有进程、排队任务、masked、首次不存在、failed 且已停服、查询失败、空输出、缺失字段和管理服务拒绝分支,共 22 场景。
- [✓] 本地
go test -count=1 ./internal/admin通过,git diff --check通过。 - [✓] 使用旧发布文件的独立副本加上新安装器,Linux 22 场景全部通过;退出码零,运行约 33.6 秒。
- [✓] 拒绝路径对整个安装目录快照(内容、类型、权限、所有者)不产生变化,unit 和证书保持不变,未执行 daemon-reload。
- [✓] 其余场景继续验证首次安装、旧资源退出生效目录、失败发布文件恢复、回退失败提示以及业务文件保护。
产物 /var/tmp/scert-install-state-after-20260917-1535。测试通过 systemd 临时单元限制内存 96 MiB、无 Swap、CPU 25%、32 任务、240 秒;systemctl 在安装器命名空间内仍为状态/故障注入桩。宿主 systemd 仅管理测试资源,正式 Scert、MySQL 和 Smail 不停止、不重启。
这证明安装器的状态分支和文件行为,不证明完整真实 systemd 升级、业务回退或最终发布包已验收;最终包验证需单独补记。未使用 DNS、ACME 或业务数据库。
发布与收尾
- [✓] 修复提交
6b6fc126868731003e70e1225f6ae455f26fb235已推送,远程 main 已核对一致;本地go test -race -count=1 ./internal/admin通过。 - [✓] 本地与远程实测安装器 SHA-256 一致:
08b7b04411b9250414d0429b10e99a4642c750163febf3da65281b445eb7fa57。 - [!] 干净克隆位于
C:/Users/ikun/AppData/Local/Temp/scert-state-20260917-1532。调用仓库发布脚本时被 PowerShell 执行策略拒绝,未绕过策略,未生成或上传本次新发布包。此前8c3d878发布包不包含本次停服检查修复,不能用于宣称最新版本验收。 - [✓] 15:32 收尾核查:测试 unit 为 inactive、PID 零、结果 success;正式 Scert PID
530794、重启次数零,MySQL PID549584、重启次数一,正式程序摘要未变。可用内存约 320 MiB,19017 无监听,SSH 随后关闭。 - [!] 正式初始化、维护窗口内停服升级、业务回退、DNS 与 ACME、目标机业务推送及最终入口仍未验收。继续需要发布脚本按本机管理策略获准执行,并确认维护窗口、域名及 DNS 操作范围、与既有 Smail 不冲突的入口方案。
初始化探针修复与正式升级复验(2026-09-17 晚间)
需求与结论
- [✓] 接续升级后的在用服务,核对 HTTPS 身份、健康与就绪状态。
- [✓] 修复首次初始化阶段健康探针缺失,保持未初始化就绪门禁。
- [✓] 干净提交构建、发布包校验、Linux 隔离协议及正式停服升级。
- [✓] 升级前后受保护文件一致性、完整快照及独立目录解包验证。
- [!] 正式初始化、公共信任证书、外部入口、业务推送与真实故障回退仍未通过,不能正式切流。
缺陷与本地验证
接手时正式进程 PID 为 570938,监听 127.0.0.1:9004,处于新的 Bootstrap HTTPS 模式。通过当前 systemd 启动日志取得指纹,核对网络证书后,再使用该证书作为专用信任根检查证书名称和有效期。页面与状态接口返回 200,设置接口返回 401,但 /healthz 和 /readyz 均为 404。旧记录中的 HTTP 503 不适用于这个新启动链路。
修改前检查点 48c2996 已推送;首次推送认证失败,重试成功。修复提交 c1ac3e91c07447243ead56fb0d8eca0b6ca8a938 已推送,仅修改 Bootstrap 处理器及测试。新增回归先复现两个 404,再验证健康返回 200、就绪返回 503 和 setup_incomplete,拒绝错误方法,不缓存、不创建会话,也不提前打开业务数据库。
以下本地验证均通过:
go test -p 1 -count=1 -timeout=3m ./...
go test -count=1 -timeout=3m ./internal/bootstrap ./internal/httpapi
go test -race -count=1 -timeout=3m ./internal/bootstrap
go vet -p=1 ./internal/bootstrap ./internal/httpapi
npm test
git diff --check
前端共 47 项通过。本轮没有修改前端,也没有重新进行浏览器渲染验收;没有执行新的全量竞态检查或漏洞扫描。
发布与隔离实机
从独立干净克隆构建,发布清单为 source_dirty=false,工具链 Go 1.26.6。首次因克隆缺少前端依赖而构建失败,保留失败目录;执行锁定依赖安装后改用全新输出目录构建成功。
- 本地归档:
build/linux-health-20260917-2205/Scert-20260917-V0.1.0-linux-amd64.tar.gz。 - 归档 SHA-256:
b44f5b2a1125af08fd15356477f25ea4e17f8cf3a29d4f07ccbe8d63467d76b0。 - 主程序 SHA-256:
b91c1a88382b29b6016488e340087cb25a205f684273c0d10d473803b10b9a41。 - 本地清单 14 项、远端包内 12 项均核对通过。目录时间后缀是标识,不代表实际执行时间。
远端脚本及包位于 /scert/acceptance-20260917-1044/,最终隔离目录为 health-c1ac3e9-v2。候选限制内存 96 MiB、无 Swap、CPU 25%、32 任务,使用全新 SQLite 路径与私有运行目录,监听回环 19017。通过项包括 HTTPS 指纹与完整验证、新探针、构建资源、未登录拒绝、跨域拒绝、一次性令牌、安全 Cookie、SQLite 写权限、缺少 DNS 验证拒绝提交、重启证书及令牌轮换、旧会话失效、配置字节不变。
第一次协议检查通过后,附加断言错误地要求 SQLite 文件不存在。实际写权限测试会留下空数据库,现场查询无业务表且完整性正常;修正测试断言后,在新目录重跑全部通过,退出码零。没有为通过测试而修改业务实现,也没有删除第一轮产物。
同一源码交叉编译的 Bootstrap 测试程序在 Linux 执行,探针、路由隔离和取消清理通过。另执行 TestHTTPSBootstrapCompletesSQLiteAndStartsApplication 的两个场景,严格 TLS、SQLite 初始化、正式服务切换、登录、用户接口及夹具 /readyz=200 全部通过。两组受限测试峰值内存分别约 52.4 MiB 和 53.4 MiB。该集成夹具不执行真实云端 DNS 或 ACME,不能替代在用服务初始化。
备份与正式升级
21:50 左右核验此前快照 /var/backups/scert-pre-upgrade-20260917-211804/snapshot.tar.gz,SHA-256 为 a9ba56f7e7e9dd3f6ac2ae2b13d11f00a3ae5ff7a749493aa09d52f99a198288。配置、凭据、密钥和 SQLite 与快照逐项一致,业务数据库只读完整性检查为 ok。之后解包至全新 0700 目录 /var/backups/scert-restore-check-c1ac3e9,29 个文件与归档逐项一致,恢复副本 SQLite 完整性正常。未启动恢复副本,不把文件恢复验证称为完整业务回退。
约 22:00 正式更新到 c1ac3e9 前,再次停止 Scert 并创建完整快照 /var/backups/scert-pre-health-c1ac3e9/snapshot.tar.gz,逐文件核对通过,SHA-256 为 7d6c39afbd43cb22ae95a98f94b5a2a4042aa86057b7ce7623698569c1e1bac9。快照目录权限 0700,文件按 0600 创建。安装器退出码零,主程序摘要与新包一致,随后启动正式服务。
升级脚本检查以下结果全部通过:
- 正式 Scert 为 active/running,PID
572525,重启次数零。 - 当前进程证书与可信 SSH 日志指纹一致,随后完整 TLS 验证下
/healthz=200、/readyz=503 setup_incomplete。 - Bootstrap 状态与页面 200,未登录设置 401,业务用户接口 404。
- 配置、数据库、密钥及证书文件的内容、权限、UID/GID 升级前后完全一致。
- MySQL PID
549584、重启次数一,与升级前一致;443 的 Smail PID570415不变。 - 所有本轮候选测试已停止,没有清空正式数据库、修改 DNS 或操作推送目标机。
剩余生产门槛
本轮正常 TLS 连接正式 ACME 目录已返回 HTTP 200,证书验证结果为零,旧的出站超时暂未复现;这仅证明当时目录连接成功,不代表签发成功或网络长期稳定。
在用配置仍是 setup_ready=false,后台域名仍为 scert-accept-20260914.epwn.uno,未对其发起签发。下一步需要用户明确管理域名、对应 DNS 写入和精确清理授权,以及不影响 Smail 443 的入口与维护范围,才能继续正式初始化、生产签发、外部 HTTPS/SNI、浏览器登录及真实业务推送。真实故障回退仍未完成,机器可用内存约 300 MiB,容量风险也未解除。
22:17 最终只读复核:Scert PID 仍为 572525、重启次数零,MySQL 状态不变;四个本轮测试单元均 inactive、PID 零,19017 无监听。备份摘要及 0700/0600 权限再次通过。此时 Smail 的 443 进程已经变为 PID 571735,系统有 4095 MiB Swap、可用内存约 634 MiB,与升级时状态不同;本轮未操作 Smail 或 Swap,变更来源尚未核查,不能把升级时的“保持不变”延伸为整个时段。容量风险需依据新环境另做负载验证。
双 Linux 正式候选健康复核(2026-09-30 21:12)
本轮使用密码 SSH 进行只读检查,未创建辅助验收脚本,未清理或修改远端业务数据库,未操作 Smail。检查目标为正式候选安装后的服务恢复状态,不替代完整生产业务验收。
| 检查项 | 8.137.23.95(ikun1) |
45.136.13.241(yc) |
|---|---|---|
Scert systemd 状态 |
active |
active |
nginx systemd 状态 |
active |
active |
Scert-storage.socket 状态 |
active |
active |
https://127.0.0.1:8443/readyz |
HTTP 200 |
HTTP 200 |
| Nginx 监听 | 80/443 |
80/443 |
| Scert 内部 HTTPS 监听 | *:8443 |
127.0.0.1:8443 |
两台服务器均未发现候选安装覆盖 Nginx 80/443 监听端口。第二台的 8443 仅绑定回环地址仍可由本机 Nginx 代理使用,但证书推送和业务流量尚未通过管理页面完成真实验证,不能据此记录多服务器部署验收通过。
管理域名只读检查
https://odacm.cn/返回 HTTP200,能够读取 Scert Web 首页。- 当前本机 DNS 将
odacm.cn解析为198.18.0.109,不是本轮两台测试服务器地址。 - 因此本轮不把首页 200 记录为公网 DNS、HTTPS/SNI、ACME 或生产入口验收通过;仍需确认真实 DNS 目标、入口归属和证书链路。
当前结论
- 双 Linux 正式候选服务安装后健康状态复核通过。
- [~] 一域名多服务器、单服务器多域名、证书推送、Nginx reload、失败回滚、恢复接管和重试幂等仍在复核中。
- 三数据库生产矩阵、Windows 服务、清库首次初始化、备份恢复、公网 DNS/ACME 和最终生产门禁尚未完成。
- [!] 本轮不新增
[✓],不以/readyz=200或首页 200 替代完整生产部署验收。
代码整改复核记录(2026-09-30)
- 证书部署工作流已改为按目标服务器逐台执行 HTTPS 基线、部署后证书指纹和恢复校验。
- 生产应用已接入目标服务器地址拨号,域名仍作为 TLS SNI 和证书校验名称。
- 已移除远端 HTTPS 校验的跳过证书验证配置,改用受信任根证书进行严格 TLS 校验。
go test ./...、go vet ./...、git diff --check通过;新增指定地址与域名 SNI 回归测试。- [~] 尚未重新部署本轮最新候选包;因此本节代码结果不能替代两台服务器的实机业务验收。
- [!] 第一台服务器仍需确认并通过真实 Nginx 站点配置、证书加载和独立 HTTPS 指纹校验;完整生产门禁继续未通过。
2026-10-01 部署锁获取失败事务终态修复记录
本轮结果
- 修复
deployOne在创建部署事务后、锁获取阶段提前返回而未写入最终状态的问题。 - 锁获取失败、锁归属写入失败、锁阶段持久化失败现在都会执行锁清理并写入
rolled_back;若锁释放无法证明或发生释放失败,则写入recovery_required并保留人工核查现场。 - 新增两类真实代码回归测试:无锁持有时的锁冲突、部分锁持有时的锁冲突。
go test ./...:通过。- 代码提交:
1fad8db;测试提交:d315179。
当前限制
- 本轮尚未使用最新提交重新构建并部署两台 Linux 服务器,因此本轮本地测试不能替代实机验收。
8.137.23.95的recovery_required现场仍需重启候选服务后复核;45.136.13.241的历史空锁目录只有在再次确认无 owner、无活动进程且属于历史测试现场后才允许清理。- 双服务器真实业务部署、失败恢复、重试幂等、三数据库、Windows、公网 DNS/ACME、SMTP、备份恢复和最终生产门禁仍未完成。
下一步
- 构建包含本轮修复的最新 Linux amd64 候选包。
- 使用密码 SSH 部署到
8.137.23.95和45.136.13.241。 - 重启服务并复核恢复事务、锁 owner、Nginx 校验、reload 和 HTTPS。
- 通过正式页面重新执行一域名多服务器、多域名单服务器部署验证。
- 更新实机证据后再决定是否推进总体验收位置。
本轮未创建辅助验收脚本,未以辅助脚本作为验收条件。
最新实机复核(2026-10-01,最新候选包双服务器业务部署)
本轮使用密码 SSH 和正式管理接口复核,未创建辅助验收脚本,未修改远端数据库内容,未关闭 TLS 校验。Windows 环境按当前上线范围暂不处理。
- 最新候选包已安装到
8.137.23.95和45.136.13.241;两台服务器的Scert、Scert-storage.socket、Nginx 均为active。 - 两台服务器的
https://127.0.0.1:8443/readyz均返回 HTTP200。 - 已验证域名
scert-multi-20260930.apmmk.cn同时绑定两台服务器;服务器端反向查询也能看到该域名。 - 已验证服务器
45.136.13.241同时托管scert-20260930.apmmk.cn和scert-multi-20260930.apmmk.cn;满足一台服务器多个域名的关系模型要求。 - 使用最新候选服务重新执行证书部署,返回
total=2、success=2、failed=0,两台服务器均报告“证书部署、配置校验并 reload 成功”,verification_status=success。 - 两台服务器目标证书文件均已写入
/ssl/scert-multi-20260930.apmmk.cn/single/,证书 SHA-256 指纹均为43:06:3C:07:26:D3:43:62:B2:54:CE:28:B6:6D:7E:B6:37:E0:0B:16:5F:68:EC:0D:07:FC:ED:0D:F2:C6:4A:D2的同一证书(记录中保留冒号格式时以 OpenSSL 输出为准)。 - 两台服务器均执行
nginx -t成功,并通过本机 SNI HTTPS 请求返回 HTTP200。 - 已确认历史失败部署任务的失败结果持久化了各服务器状态和备份标识;最新候选服务启动后未再产生新的空归属
acquiring事务。 - [!] 现有历史
recovery_required事务仍缺少可信恢复证据,未直接改库伪造成功;相关现场保留人工核查状态。 - [~] 失败回滚的真实双服务器故障注入、任务级重试幂等、真实公网 DNS/ACME、Smail 系统账户 SMTP、三数据库矩阵和备份恢复仍需继续。
当前任务看板
- T1 主清单、执行清单和 Linux 实机记录已同步。
- T2 部署锁获取失败、空锁恢复和事务终态修复已完成并部署复核。
- T3 最新 Linux amd64 候选包双服务器安装及基础健康检查完成。
- T4 一域名多服务器、单服务器多域名关系和最新候选证书部署成功。
- [~] T5 真实失败回滚、重试幂等和历史恢复证据统一复审。
- [~] T6 公网 DNS/ACME、Smail SMTP、数据库生产矩阵和备份恢复。
- T7 最终生产门禁和上线结论。
总体验收位置仍为 P0-03:完成,待复审,本轮不得标记全量生产验收通过。
2026-10-01 反向代理端口收敛记录
本节补充当前部署要求,不覆盖历史记录。当前仅处理 Linux;本轮是保留数据的端口配置复核,不代表清库首次初始化验收。
- 已完成,等待复审:两台服务器通过密码 SSH 核验,Scert 均仅监听
127.0.0.1:8443;没有0.0.0.0:8443或[::]:8443监听。 - 已完成,等待复审:Nginx 对外监听
80/443,两台服务器的nginx -t均通过;未修改邮件及其他既有站点。 - 已完成,等待复审:第二台管理入口
odacm.cn的 HTTP 请求返回 301 并跳转 HTTPS,反代/readyz和回环上游/readyz均返回 200;上游启用 SNI 和证书校验。 - 已完成,等待复审:从第二台服务器按正常 DNS 访问管理域名,连接地址为
45.136.13.241,HTTPS 就绪检查返回 200;该结果不是独立外部客户端的完整生产验收。 - 已完成,等待复审:静态 systemd 模板已提交并推送
48d10fe;动态生成的 Linux unit 同步回环监听约束,并补充模板与生成器回归断言。 - 已完成,等待复审:本地后端
go test ./...、go vet ./...和git diff --check通过;本机 Windows 测试不代替 Linux 专属用例执行。 - [~] 进行中:使用干净提交构建 Linux 候选包,核对安装后的默认 unit 和动态生成配置,并补充 Linux 专属用例证据。
- [!] 暂缓或存在阻塞:历史恢复事务、双服务器真实失败回滚与重试幂等、Smail SMTP、数据库生产矩阵、备份恢复及最终生产门禁仍未完成。
端口边界:不新增公网业务端口,不为内部 8443 添加防火墙或安全组放行规则。SSH 运维端口与其他已有服务不属于本次端口收敛的修改范围。总体验收保持 P0-03:完成,待复审,不新增全量验收通过结论。
反向代理端口收敛复核结果(2026-10-01 16:35,北京时间)
- 已完成,等待复审:构建提交
51f7f3e55cee16d3b747bea30e0382fca4b25dd1,发布清单source_dirty=false;Linux 包位于build/release-20261001-loopback/Scert-20261001-V0.1.0-linux-amd64.tar.gz。 - 已完成,等待复审:包 SHA-256 为
2953f52d252194fda7865e1ee06e548204fdfdb818dab28ce10611087ba94443;两台服务器上传后校验一致,包内SHA256SUMS全部通过。 - 已完成,等待复审:两台服务器均经官方安装器安装成功并启动,安装退出码均为 0;主服务、存储 socket 和 Nginx 均正常,主服务重启计数为 0。
- 已完成,等待复审:两台服务器
/scert/scert的 SHA-256 均为beeade4c38e1be7f8af29b42d08896ca4f9efcb782c3f0a278f58fd0abc9baae,与本地候选二进制一致;已安装的主 unit 自身包含回环监听设置,不再仅依赖 drop-in。 - 已完成,等待复审:在第二台 Linux 上执行仓库
internal/servicehost的编译测试程序,9 项全部通过,覆盖动态 unit 和发布模板回环约束;没有创建辅助验收脚本,此结果仅作为代码回归证据。 - 已完成,等待复审:本地前端 241 项测试通过,正式前端及 Linux 后端构建通过。
- 已完成,等待复审:升级后两台 Scert 均监听
127.0.0.1:8443,Nginx 仍对外监听80/443,nginx -t通过;未改动已有站点或新增公网放行规则。 - 已完成,等待复审:第二台回环上游按管理域名 SNI 和系统 CA 严格验证返回 200;第一台作为独立客户端按正常 DNS 访问
https://odacm.cn/readyz返回 200,连接地址为45.136.13.241。 - 已完成,等待复审:两台服务器交叉探测对方公网
8443均超时;结合实际监听地址确认该内部端口未对外监听,未据此声称其他已有服务端口全部关闭。 - [!] 边界说明:第一台内部管理服务沿用原有 IP 自签证书,使用测试域名和系统 CA 直连会失败;通过密码 SSH 核查证书及 IP SAN 后,以该证书作为显式信任文件访问回环上游返回 200,未关闭 TLS 校验。这仅是该机内部健康核验,不是第一台管理入口的公网受信 TLS 验收。
- [!] 边界说明:本轮保留数据库,没有执行清库首次流程;未额外制作数据备份,官方安装器自身保留升级前发布文件以支持失败回退。完整生产验收仍为 P0-03:完成,待复审。
部署重试阻塞修复进度(2026-10-01 16:51,北京时间)
本节为本轮当前状态说明,前文保留为历史记录。P0-03 的局部代码复审状态不代表整个项目的生产验收状态;本轮上线范围仅 Linux,不将 Windows 列为阻塞。
- [✓] 复审通过:双机服务保持回环监听 127.0.0.1:8443,由 Nginx 80/443 对外提供服务;本轮未新增公网业务端口。
- 已完成,等待复审:通过正式部署接口制造第一台 Nginx 校验命令失败,两台部署报告整体失败,恢复报告为 success;随后已恢复正常校验命令,双机 nginx -t 通过。该验证使用同一证书重部署,不代表不同新旧证书切换验收。
- 已完成,等待复审:定位部署重试自冲突。HTTP 重试已创建尝试并标记原任务运行,但应用装配再次调用创建任务的工作流,将自身判为同类活动任务。新增真实应用登录与路由装配回归,修复前稳定返回 502。
- 已完成,等待复审:拆分普通部署与已有任务执行回调,普通部署继续创建任务,重试只执行原始证书部署流程,保留权限、审计、尝试记录与事务关联。
- 已完成,等待复审:定向回归验证唯一父任务、失败后成功的两次尝试、原任务事务关联、并发重试 409、成功后重复重试 409;后端 go test ./... 与 go vet ./... 通过。
- [~] 进行中:竞态测试、干净提交构建、双机升级和真实失败任务重试复核。当前尚未取得修复后的实机成功证据。
- [!] 暂缓或存在阻塞:历史恢复事务、Smail SMTP、数据库生产矩阵、备份恢复与最终清库首次部署门禁仍未闭环,不宣称生产验收通过,不给缺乏依据的完成百分比。
现场失败任务标识:683ef23a-c912-4f46-b2a6-3ec11908808e。本轮保留其数据用于复现与修复验证,不属于清库首次流程;没有直接改库伪造状态,也没有创建辅助验收脚本。
本轮补充回归:应用装配测试同时核对双服务器结果归属于第二次尝试,以及开始和成功审计的操作者关联;缺少已有任务执行器时返回 501,不回退到创建任务入口,不改变原任务状态。后端全量测试与 vet 再次通过;app/httpapi/repository 竞态测试通过,补充用例的定向竞态测试通过;前端 241 项通过。实机复测尚待新包部署。
部署重试双机实测复核结果(2026-10-01 17:02,北京时间)
以下为本轮最新结果,更新前述“尚待实机复测”的状态;只关闭部署重试自冲突这一子项,不等同于完成全部生产门禁。
- [✓] 复审通过:修复提交
302111c8af已推送,发布清单 source_dirty=false;使用正式构建流程生成 Linux 包,并通过官方安装器升级两台测试服务器,安装及启动退出码均为 0。 - [✓] 复审通过:发布包 build/release-20261001-deploy-retry/Scert-20261001-V0.1.0-linux-amd64.tar.gz,SHA-256 为 0ad94de03e625eb5fd6789e1fa84f8cad8298e2487876f55d34e36f14df7c878;双机上传和包内 SHA256SUMS 校验均通过。
- [✓] 复审通过:两台 /scert/scert 的 SHA-256 均为 393ae5a1cfaf8e4442ec30e47950f020e6ab47adb47af7fdca45a36eb9486ed2;Scert 与 Nginx active,NRestarts=0。
- [✓] 复审通过:复用真实失败任务 683ef23a-c912-4f46-b2a6-3ec11908808e,通过正式重试接口同时提交两次请求,一个返回 200、双服务器部署成功并通过 HTTPS 校验;另一个返回 409,没有执行第二次部署。成功后再重试返回 409。
- [✓] 复审通过:原任务保留,未产生嵌套父任务;尝试记录只从 3 增加到 4,第 4 次为 success,两台部署结果均关联该次尝试 b9ca3a51-30af-4d2c-9655-758509140f5e。旧失败记录保留用于追溯。
- [✓] 复审通过:只读核对数据库,首次失败的两个事务均为 rolled_back;本次两个事务 20261001-085936.117414575-5eecfbb86709、20261001-085940.320149826-09d1cf34f629 均为 committed;开始及成功审计均关联原任务和实际操作者。没有直接修改数据库状态。
- [✓] 复审通过:两台证书目录均无残留锁及 scert-tmp 文件;nginx -t 通过,证书和证书链文件哈希一致。第一台通过带 SNI 和主机名校验的 TLS 连接核对第二台站点证书指纹,仍与部署前同一正式证书一致。
- [✓] 复审通过:升级后 Scert 仍仅监听 127.0.0.1:8443,Nginx 通过 80/443 提供 Web 服务;管理入口前端与 readyz 返回 200,第二台回环上游仍使用系统 CA 严格校验。没有开放额外公网业务端口,未关闭 TLS 或 SSH 主机校验。
- [!] 仍需处理:历史事务 20260930-231310.231207974-5bf9d1e37542、20260930-231313.144123222-ce71b1dfe14e 的恢复证据字段为 null,服务保留 recovery_required 并拒绝自动接管;本轮没有伪造历史证据或强改终态。
- 未开始:本轮修复后的最终清库首次部署验收。Smail SMTP、数据库矩阵及备份恢复等其余上线门禁仍需按原任务清单验证。
本轮运维使用密码 SSH,没有新建辅助验收脚本;没有额外制作远端数据备份。安装器自行保留升级前发布文件,未擅自删除。以上域名、服务器及凭据仅用于测试,不作为产品验收规则。
真实进程崩溃恢复与原任务重试(2026-10-01 17:15,北京时间)
范围与操作边界
沿用已部署的源码提交 302111c8af 及正式候选包,本轮没有修改产品代码或重新构建。双机二进制版本沿用上一节证据,第二台再次核对 SHA-256 为 393ae5a1cfaf8e4442ec30e47950f020e6ab47adb47af7fdca45a36eb9486ed2。本轮保留数据连续复测,不代表最终清库首次流程。
使用已有正式证书重部署,未重新签发;测试域名 scert-multi-20260930.apmmk.cn。人工操作使用密码 SSH,产品部署仍使用其托管密钥并校验主机指纹。未创建辅助脚本、未直接写库、未手工删锁、未额外备份远端数据。
崩溃注入及自动恢复
- 正式域名部署接口创建任务 72f4222a-3706-419c-847c-0fcb55b436f2。为得到可控中断窗口,通过正式服务器 API 将第一台重载命令临时设置为 nginx 重载后延迟 18 秒,校验命令始终为 nginx -t。
- 只读确认两个事务均为 reload_attempted/pending 后,于 UTC 09:07:09 对第二台 Scert.service 主进程发送 SIGKILL;未停止 Nginx。
- 原进程 PID 112721,systemd 自动启动新进程 PID 113012,NRestarts=1。
- UTC 09:07:29 第二台事务已回滚,第一台仍恢复中;此时管理 readyz 暂时返回 502,第一台业务站点本机严格 HTTPS 仍为 200。此管理短暂不可用如实保留,不宣称零中断。
- UTC 09:07:42 两条事务均 rolled_back,消息为“服务启动已完成中断部署事务回滚”;原任务为 failed/service_restart,管理 readyz 已恢复 ready。
- 第一次尝试 a680e853-2d2b-40c6-a68f-2dea91b36a79 保留 failed。对应事务:20261001-090648.928412564-d8bedbb5d1d1、20261001-090653.896206069-a567d37db475,均为 rolled_back。
- 浏览器中原同步请求最终返回 Nginx 502,符合主进程被杀后的连接中断;没有将该响应伪报为成功。
配置恢复和正式重试
- 重新登录后,通过正式服务器 API 将第一台 reload_command 恢复为 ["nginx","-s","reload"],PUT 返回 200,随后 GET 再次核对一致。
- 正式接口 POST /api/v1/tasks/72f4222a-3706-419c-847c-0fcb55b436f2/retry 返回 200,双机 total=2、success=2、failed=0,verification_status=success;结束时间 UTC 09:12:11。
- 原任务更新为 success,第二次尝试 e52b6717-46b8-4072-9931-eafc7f8fa817 为 success;双机部署结果均关联此次尝试,没有新建嵌套父任务。
- 第二次尝试的事务 20261001-091153.272958781-00baba19c6a9、20261001-091159.467779056-dc1f13c75a80 均为 committed。
- 只读审计依次存在 certificate_deploy/running、task_recovery/failed、certificate_deploy_retry/running、certificate_deploy_retry/success,均关联原任务和 primary-super-admin 操作者。
- 成功后再调用正式重试接口返回 409。
文件、服务与网络复核
- 双机 nginx -t 成功,证书目录使用不限制文件类型的 find 检查,无名称包含 lock 或 scert-tmp 的残留。
- 恢复后双机 cert.pem 和 fullchain.pem 的 SHA-256 均为 ecf815ca6ba91abb43985663f7ff2df4ee7987362131e068b6ff32e4657f90bc。
- 双机本机 SNI 严格 HTTPS 请求均为 200;第一台访问第二台公网严格 HTTPS 为 200。第一台本机和第二台公网证书指纹均为 43:06:3C:07:26:D3:43:62:B2:54:CE:28:B6:6D:7E:B6:37:E0:0B:16:5F:68:EC:0D:07:FC:ED:0D:F2:C6:4A:D2。
- 双机 Scert 均仅监听 127.0.0.1:8443,Nginx 对外监听 80/443;第二台管理 HTTP 返回 301,跳转 HTTPS,readyz 正常。没有开放额外公网业务端口。
- 单独发现的公网限制:第二台多次访问第一台公网测试域名 HTTPS 均为连接重置,本地 Windows 客户端同样握手失败。第一台抓包看到 TCP 建连后入站 RST;公网 HTTP 返回 Server: Beaver、403,正文标题为 Non-compliance ICP Filing,并指向阿里云拦截页面。第一台本机同域名 HTTPS 仍为 200;不把本机成功代替公网通过,也不通过开放其他端口或关闭证书校验绕过此限制。
- 无 SNI 的公网握手仅用于定位网络差异,返回其他默认站点证书;该诊断不计入测试域名 TLS 验收,未修改产品校验策略。
结论
- [✓] 该崩溃窗口的可信事务自动回滚、原任务正式重试和重试后状态关联复审通过。
- [!] 第一台该测试域名公网 HTTP 有明确拦截页面,公网 HTTPS 失败,公网访问验收不通过;第二台管理及测试站点正常。
- [~] 仅同证书重部署,其他负向窗口、新旧证书切换和历史证据缺失事务尚未全部闭环。
- 最终清库首次流程及其他原清单生产门禁未完成;不宣称整体生产部署验收通过。
数据库实机矩阵与新阻塞(2026-10-01 17:45,北京时间)
范围与环境
- 沿用第二台 Linux 测试机,正式运行主程序仍为
302111c对应产物,SHA-256 为 393ae5a1cfaf8e4442ec30e47950f020e6ab47adb47af7fdca45a36eb9486ed2。 - 测试使用项目原有 Go 集成测试及正式 CLI,不使用新建辅助脚本。非 root 测试进程由 systemd 临时单元以 mysql 用户启动,隔离数据库仅监听回环地址。
- 测试根目录 /var/tmp/scert-db-matrix-20261001-1720;MySQL 数据根目录 /var/lib/mysql-files/scert-20261001。保留 AppArmor 策略,不放宽 /scert 权限。
- 未重建或清空业务库,未额外备份业务数据;当前不是最终清库首次部署验收。
已结束结果
| 测试 | 单元或日志 | 结果 |
|---|---|---|
| 原 MySQL 数据库矩阵 | scert-mysql-matrix-20261001-1722 / mysql-database.log | 退出 1;模式 15 中断后 1、2 条语句及模式 16、17 建表后中断,共四个边界因表已存在失败 |
| MySQL 8.0.46 仓储 | scert-mysql-repository-20261001-1732 / mysql-repository.log | 退出 0;9 个主测试、92 个子场景通过,无失败或跳过 |
| PostgreSQL 14.24 首次尝试 | scert-postgres-matrix-20261001-1723 / postgres-cli.log | 七场景均因备份工具版本不满足要求失败;不计通过 |
| PostgreSQL 16.15 | scert-postgres16-matrix-20261001-1727 / postgres16-cli.log | 退出 0;七场景全部通过,无跳过;总耗时 14.52 秒 |
| SQLite 旧断言 | scert-sqlite-matrix-20261001-1726 / sqlite-cli.log | 失败,测试将当前迁移版本写死为 14,实际已为 18 |
| SQLite 修正断言及历史样本 | scert-sqlite-history-20261001-1740 / sqlite-history-cli.log | 退出 0;historical_backup、upgraded_backup 全部通过;总耗时 0.79 秒 |
PostgreSQL 的 success、certificate、permission、inventory、authentication、tls 使用独立正式 CLI;cancel 使用进程内确定性取消和真实工具回退,仅据实记录该范围。16.15 工具位于 /var/tmp/scert-pg16-tools-20261001/extracted,包来自经官方公钥签名验证的独立 PGDG 索引。测试后无残留 PostgreSQL 服务进程。
SQLite 新测试程序 SHA-256:4c81656fae63a2eebad999d58e6a79e63e6f441810e02ce29b2a9ce3706ae7f6;上传后核对一致。新增样本覆盖 task_idempotency、task_attempts、task_deployment_results、deployment_transactions 及 recovery_evidence_json;恢复前实际修改样本,恢复后全表快照核验。
当前修复与边界
- [~] 原 MySQL 15~17 迁移使用非事务建表,已落盘后再次执行报表已存在。不能简单忽略冲突:模式 15 的历史幂等回填还需避免重复写入,同时拒绝内容不一致的数据。
- [~] 正在实测可重入建表、字段和索引校验、回填与版本标记同事务提交,以及部分回填、冲突数据、异常结构负向场景。待后续结果更新,不能根据运行中的单元 Result=success 提前判定通过。
- [✓] 双机端口复核符合 Nginx 80/443 反代要求;Scert 与 MySQL 均未新增公网监听。
- [!] 第一台测试域名公网平台拦截、无可信证据的历史事务及此前剩余生产门禁继续保留,不以数据库子项通过替代。
MySQL 中断修复、正式构建与双机升级复核(2026-10-01 18:02,北京时间)
修复和实库证据
- 修复提交:c6982ab827038c2cb16bc1432fb393f68a5296e2,已推送。首次推送遇到认证失败,重试成功;没有修改远程认证设置。
- 第一轮修复测试单元 scert-mysql-reentry-20261001-1743 退出 0,106 个子场景通过;此后补充默认空字符串、排序规则和大小写冲突保护,没有用第一轮结果替代最终代码验证。
- 最终单元 scert-mysql-reentry-guards-20261001-1751:inactive、Result=success、ExecMainStatus=0。日志 /var/tmp/scert-db-matrix-20261001-1720/mysql-reentry-guards.log。
- TestMySQLRealDeploymentMigrationRecovery:18 个子场景通过,92.25 秒;覆盖建表前后、部分及完整回填、重复历史任务、不同域名相同键、空键排除、错误任务及时间、孤立映射、大小写冲突、错误列类型或默认值、允许空值、缺失唯一约束、缺失或逆序索引、额外字段、排序规则和非 InnoDB 表。
- TestMySQLRealMigrations:91 个子场景通过,385.84 秒;覆盖 0~18 版升级、各语句中断边界、现有数据、作用域账户、非法迁移历史和重启持久化。总计 109 个子场景,无失败或跳过。
- 最终测试程序 SHA-256:243a42a3826d5e77547346bb95ed56394ca67bab7334568d3202b193a3c31019,上传后核对一致。
本地门禁与正式包
- go test -count=1 ./...、go vet ./... 退出 0;go test -race -count=1 ./internal/database ./internal/cli 退出 0;前端 241 项通过、0 失败、0 跳过。未启用的本地外部数据库场景不计实库通过。
- 正式入口 build/build-release.ps1 -Target linux-amd64,包目录 build/release-20261001-mysql-reentry,manifest 标记 source_commit=c6982ab827038c2cb16bc1432fb393f68a5296e2、source_dirty=false。23 项产物大小及哈希核验一致。
- 归档 SHA-256:c075297e9f8f76f4ebb8fa28d43a4099ca853a3619212d5e7f51e78d4b0e9e4d。
- 主程序 SHA-256:39b70a1a11148982baeb699bae749f7e2988a2fba02b001c0da740ba8b86f36d。
- 新正式程序用于 SQLite 再测:scert-sqlite-release-20261001-1754,两个子场景通过,1.34 秒,退出 0。
- 新正式程序用于 PostgreSQL 16.15 再测:scert-postgres16-release-20261001-1754,七场景通过,14.49 秒,退出 0;六场景独立正式 CLI,取消场景为进程内入口,不扩大证明范围。
双机升级与健康复核
- 运维通过密码 SSH 连接,保留严格主机指纹检查。发布包上传双机后,归档哈希及包内 21 项 SHA256SUMS 全部通过。
- 发布目录 /var/tmp/scert-release-mysql-reentry-20261001;安装日志 /var/tmp/scert-install-mysql-reentry-20261001.log。
- 两台首次运行安装器时主服务仍在运行,被保护检查拒绝;停止主服务后仍因 Scert-storage.socket 在监听再次被拒绝。随后完整停止 Scert、Scert-admin、Scert-storage.service、Scert-storage.socket,官方安装成功,再启动目录 socket 和主服务,最终退出 0。所有失败记录保留在同一追加日志中;未将拒绝事件计为成功安装。
- Nginx 未停止;管理上游在停服窗口不可用,本次不宣称零停机。安装器按自身事务流程保留发布文件,没有额外制作业务数据备份,也没有手工删除历史文件。
- 两台 /scert/scert 哈希均与上述新正式包一致;第一台 PID 2091132,第二台 PID 158279,均 active、NRestarts=0,目录 socket active。
- 双机 nginx -t 成功。第二台管理首页 HTTP 200,readyz 返回 ready,HTTP 入口 301;第一台测试域名本机带 SNI 且严格校验证书的 HTTPS 为 200,不能代替其公网访问通过。
- 双机 Scert 均仍监听 127.0.0.1:8443,MySQL 监听 127.0.0.1:3306;第二台 MySQL X 协议也仅监听 127.0.0.1:33060。Web 仍由 Nginx 80/443 对外,未添加公网规则。
- 只读核查双机迁移版本均为 18,升级前后任务及事务状态计数一致,没有活动任务被中断。第二台两条 recovery_required 历史事务保留,不伪造证据,不强改状态。
下一项正在运行
- 单元 scert-mysql-cli-20261001-1801,日志 mysql-cli-release.log,运行项目现有 TestMySQLReal 维护测试。测试程序 SHA-256:73cd220dfcb898d452ca9de752c2e19b40d5951c693d6fab28e2e6c00c9ea7b9。
- 官方 mysqld、mysql、mysqldump 在系统中位于不同目录;仅在隔离目录 mysql-tools 创建指向原程序的符号链接,以满足夹具同目录要求,没有编写包装或辅助验收脚本,没有修改系统程序。
- 当前运行中,不提前判定通过。该套测试包含进程内正式命令入口及实际工具互操作,不等同于所有独立发行 CLI、完整 Web 和最终生产流程通过。
最新接续状态与任务确认(2026-10-01 18:15,北京时间)
本节更新前文历史快照;旧章节中“当前有效”仅指其记录时点,不代表本轮状态。沿用原始四十四项需求,本次仅验收 Linux,Windows 不在本轮范围;不以历史 P0-03 局部状态代表全部生产门禁。
- 已完成,等待复审:MySQL 8.0.46 备份恢复矩阵单元
scert-mysql-cli-20261001-1801已真实结束,退出零;日志mysql-cli-release.log中二十一个主测试、一百三十六个子场景通过,零失败、零跳过。服务器日志开始时间为北京时间 18:01:26,结束为 18:06:49。 - 已完成,等待复审:本批矩阵覆盖备份快照、官方导入导出互操作、视图、触发器、例程、事件、权限和失败回退。主要调用进程内正式实现,不冒充独立发行程序全量验收。
- 已完成,等待复审:双机服务正常;Scert 仅监听回环 8443,MySQL 仅监听回环 3306;第二台的 33060 同样仅监听回环。Web 对外使用 Nginx 80/443,不新增公网业务端口,不修改第一台现有邮件端口。
- [!] 暂缓或存在阻塞:只读检查确认双机 Scert 均未启用 SMTP,主机、系统通知用户名、凭据引用均为空;缺少可用系统通知配置,不能宣称真实发信与邮件密码重置通过,不使用普通邮箱替代。
- [~] 进行中:复用仓库现有 MySQL 隔离实库测试,增加独立正式发行程序调用;保留严格 TLS、凭据加密存储、成功恢复及 SQL/证书失败回退断言,不创建辅助验收脚本,不接触业务数据库。
- 未开始:将新增测试编译到 Linux,在第二台隔离数据库中验证当前正式发行程序,再记录实际通过或失败结果。
- [!] 暂缓或存在阻塞:MySQL 5.7、完整三库 Web 流程、Linux 原生构建、其余部署负向场景、历史事务核查、系统发信与最终清库首次部署等仍未闭环;整体生产验收未放行。
MySQL 独立发行程序验收结果(2026-10-01 18:22,北京时间)
- 已完成,等待复审:新增仓库测试
TestMySQLRealReleaseBackupRestoreCommands,复用现有成功、SQL 失败、证书恢复失败场景;通过独立进程调用正式发行程序,不再依赖测试进程的 TLS 注册表。未创建辅助验收脚本。 - 已完成,等待复审:第二台 Linux 上单元
scert-mysql-release-cli-20261001-1818真实结束,退出零;三个子场景全部通过,耗时 33.85 秒,日志为/var/tmp/scert-db-matrix-20261001-1720/mysql-release-cli.log。 - 已完成,等待复审:验证对象为已部署候选同源的正式发行程序
/var/tmp/scert-release-mysql-reentry-20261001/scert,SHA-256 为39b70a1a11148982baeb699bae749f7e2988a2fba02b001c0da740ba8b86f36d;测试程序 SHA-256 为88ff0fec3f2ab9a14f89dd52f384a677ecfb450f679b077ec47e83649644eb09。 - 已完成,等待复审:隔离 MySQL 8.0.46 仅监听回环,使用严格 TLS;只在子进程中信任隔离证书,数据库密码通过加密凭据引用读取,未更改系统信任库。断言覆盖业务数据、审计数据、配置、主密钥、加密凭据、证书及失败后恢复前快照。
- 已完成,等待复审:本地后端全量测试、全量静态检查、CLI 竞态测试和差异检查通过。本地条件跳过不计实库通过;本批只修改测试,没有更换线上程序。
- [~] 进行中:准备在隔离目录使用固定工具链执行 Linux 原生正式构建,避免将 Windows 交叉编译包冒充 Linux 原生证据;不新增公网监听,不更改生产工具链或业务配置。
- [!] 暂缓或存在阻塞:上述三个独立 CLI 场景不代表全部数据库、Web 或生产流程验收通过;既有 SMTP 配置缺失、历史事务核查及其他未完成门禁继续保留。
Linux 原生包双机升级与 Nginx 端口门禁(2026-10-01 19:27,北京时间)
- 构建单元:
scert-linux-native-release-20261001-1852,结果为 success;原生工具链为 Go 1.26.6、Node.js 24.19.0、npm 11.17.0,目标为linux/amd64。 - 发布清单:源码提交
be6e2059f4ce949f7e1b6c0dacb3ff0bdea9ea52,source_dirty=false;归档Scert-20261001-V0.1.0-linux-amd64.tar.gzSHA-256 为08ba7769bf9225b88ea84f104720fb166b583a494737627523179c0527e83130。 - 第二台
45.136.13.241:使用官方安装器完成停服升级后启动Scert.service和Scert-storage.socket;Nginx 未停止;https://odacm.cn/readyz返回 ready,首页和 HTTP 到 HTTPS 跳转正常。 - 第一台
8.137.23.95:使用同一归档和官方安装器完成停服升级后启动Scert.service和Scert-storage.socket;Nginx 未停止;既有站点配置和证书保持不变。 - 端口检查:双机 Scert 仅绑定回环
8443;MySQL 仅绑定回环3306;第二台33060仅绑定回环。绕过本机代理直连公网时,三个内部端口均超时;对外项目入口仅为 Nginx80/443。未关闭或修改第一台现有邮件业务端口。 - 结果:双机原生包部署和 Nginx 反代端口门禁完成,等待复审;不代表整体生产部署验收通过。SMTP、密码重置、完整 Web 流程、历史事务、DNS/ACME 和最终清库首次部署仍未闭环。