diff --git a/docs/Nginx反代与证书部署说明.md b/docs/Nginx反代与证书部署说明.md index 8daa880..0fbfda7 100644 --- a/docs/Nginx反代与证书部署说明.md +++ b/docs/Nginx反代与证书部署说明.md @@ -40,6 +40,8 @@ lego 固定为项目同版本 v4.34.0,官方发布包 SHA256 为 `c681c09d3f2a 续期会暂停 Nginx 使用公网 443。执行上限 150 秒,服务总超时 240 秒,正常异常路径使用 `finally` 恢复,systemd `ExecStopPost` 额外覆盖任务终止后的恢复。邮件服务不随 Nginx 停止。此方案存在短暂 Web 维护窗口,不是无中断续期。 +2026-09-17 23:30 复核发现,同一个 Nginx 已加载 `scert-apmmk.conf`,同时承载 Scert 的 8003/8004 入口。当前续期脚本执行的是整个 `nginx.service` 的停止,因此到期续期也会中断这些入口。六项模拟回归通过不能消除该跨项目影响;在明确共用服务维护窗口或完成不中断其他站点的挑战方案前,不得把自动续期列为生产验收通过。本轮没有停止或重载 Nginx,没有触发真实到期续期,也没有修改 Scert 配置。 + 续期服务预算为 MemoryHigh 96 MiB、MemoryMax 128 MiB、SwapMax 0、CPUQuota 100%、TasksMax 64。仅演练了未到期真实任务和模拟失败/超时恢复,尚未在此预算内执行真正到期续期;实际申请成功不等于到期续期故障演练完成。 同步脚本先检查系统信任链、五个域名、至少七天有效期与密钥匹配,再保存回退副本并更新运行文件。失败返回非零,不静默忽略。安装的 Certbot 保留,但其自动定时器已停用,避免双重续期管理。 diff --git a/docs/晚间验收复测记录.md b/docs/晚间验收复测记录.md new file mode 100644 index 0000000..5b4053d --- /dev/null +++ b/docs/晚间验收复测记录.md @@ -0,0 +1,69 @@ +# 晚间验收复测记录 + +## 范围与基线 + +- 日期:2026-09-17,远程检查开始于北京时间 23:30。 +- 目标:47.108.78.12,主机名 `ikun2`。所有应用与回归测试仅在该服务器执行。 +- 本轮基线提交:`a0e373d`,已推送。仅复测现有部署,不修改应用源码,不重新编译或替换线上程序。 +- 测试对象仍为 `review-2263779`,主程序和管理程序摘要与上一轮相同。 +- 本轮只读检查线上状态,续期回归使用模拟依赖和独立网络,不登录、不发信、不写业务数据库。因此未清库、未进行首次安装,不计入最新构建清洁部署验收。 +- 证据目录:`/var/tmp/smail-review-night-20260917-233135`,权限 0700。保留失败日志与重试结果,不删除历史证据。 + +## 任务清单 + +- [✓] 核实当前工作树、程序摘要及服务状态。 +- [✓] 可信 TLS、内部 25/587 STARTTLS、HTTP 跳转及未知 Host/SNI 拒绝复测。 +- [✓] 六项隔离续期回归及线上脚本摘要核对。 +- [✓] 备份摘要、证书有效期、私钥权限与本地恢复 socket 权限检查。 +- [✓] 非特权用户实际连接本地恢复 socket 被拒绝。 +- [✓] 五分钟资源采样与结束时服务复核,共 11 次采样通过;仅覆盖本轮短时观察。 +- [!] 真实远程浏览器业务验收、首次安装及发信闭环未执行。 +- [!] Nginx 共用后的续期维护影响待处理,未触发真实续期。 + +## 已取得证据 + +| 检查 | 结果与边界 | +| --- | --- | +| 443、8002、465、993、995 | 系统信任链与主机名校验通过,使用同一叶证书 | +| 内部 25、587 | STARTTLS 通过,明文阶段不公布 AUTH,未执行邮件投递 | +| 80、8001 | HTTP 跳转通过,公网 80 不泄露内部 8002 | +| 未知 Host/SNI | HTTP 拒绝、TLS 握手拒绝通过 | +| Nginx 配置 | `nginx -t` 通过,未重载服务 | +| 续期脚本回归 | 六项通过;验证未到期、到期失败及超时恢复、成功路径、权限、证书信任和密钥匹配相关行为 | +| 线上脚本一致性 | 两个续期部署脚本分别与本轮上传副本 SHA256 一致 | +| 已有一致性备份 | `smail-state.tar.gz` 摘要仍为 `29bd3deb4b498ee873d83cd5986cfd37b2c2c3cf08347a6b913e0c9ea8b41965`,未执行恢复 | +| 证书 | 五域名 SAN 完整,有效期至 2026-12-16 13:54:39 UTC,超过 30 天 | +| 私钥与恢复入口 | 应用私钥 0600、ACME 目录 0700、ACME 私钥 0600、恢复 socket 0600;不代表完整恢复撤销通过 | +| 本地 IPC 访问边界 | 以 `nobody` 用户、UID 65534 连接恢复 socket,得到预期 `EACCES`;没有发送业务请求或修改账户,证据为 `ipc-access-boundary.json` | +| UFW | IPv4/IPv6 的 8001:8002 优先拒绝规则存在,未执行独立外网扫描 | + +续期回归使用 systemd 独立网络、私有临时目录、只读系统和脚本挂载;禁止访问生产应用、恢复 socket、ACME 目录及备份。限制为 64 MiB 内存、零交换、25% CPU、32 个任务和 90 秒运行时间。 + +首次启动时,`PrivateTmp` 隐藏了 `/var/tmp` 中的脚本,Python 以退出码 2 结束,尚未运行任何用例。随后将本轮脚本目录只读挂载至 `/opt/smail-night-code` 后重试成功;没有关闭隔离或扩大资源上限。失败日志为 `renewal-regression.log`,成功日志为 `renewal-regression-retry.log`。 + +成功回归的 systemd 输出记录运行时间 485 ms、峰值内存约 15 MiB;结束后再次查询 `MemoryPeak` 为未设置,因此不能将后一次空值解释为零内存。 + +## 资源与结束复核 + +资源采样时间为北京时间 23:32:30 至 23:37:31,共 11 次,跨度约 301.49 秒,每次均按原 128 MiB 保留预算通过。 + +| 指标 | 实测结果 | +| --- | --- | +| 主机可用内存 | 772,050,944 至 813,060,096 字节 | +| Smail 当前内存采样峰值 | 35,913,728 字节,约 34.3 MiB | +| Smail 增长至硬上限后的最小主机余量 | 270,471,168 字节,约 258 MiB,大于 128 MiB 保留预算 | +| 进程与 OOM | 同一 InvocationID,OOM 和 OOM kill 均为零 | +| 结束时 Smail | active,PID 574584,NRestarts 0 | +| 结束时 Nginx | active,PID 575746,NRestarts 0 | +| 同机服务 | Scert、MySQL、PostgreSQL 的进程与监听在结束复核时仍存在,PID 与本轮开始一致 | +| 结束时传输层 | `transport-final.json` 再次通过 | + +逐次证据为 `resource-00.json` 至 `resource-10.json`,汇总为 `resource-summary-retry.json`,服务状态为 `service-final.txt`。首次汇总将 `resource-summary.json` 自身匹配为样本,误报缺少样本并退出;重试改为显式读取 11 个编号文件后通过,空的首次汇总文件保留,原始采样没有被覆盖。 + +此观察期间没有持续业务负载,不能据此推导并发用户数、邮件吞吐量或长期稳定性,汇总中的 `productionApproved` 保持 `false`。 + +## 新发现与剩余阻塞 + +当前 `/etc/nginx/conf.d/scert-apmmk.conf` 为 Scert 提供 8003/8004 入口,与 Smail 共用同一个 Nginx。现有续期脚本会停止整个 Nginx 服务,因而存在跨项目中断风险。此结论来自现场配置与续期源码核对,没有通过停止服务制造故障。需要明确共用服务维护窗口或调整挑战部署方式,并完成对应远程演练。 + +服务器未检测到 Chromium、Chrome 或 Node/npm 可执行文件,本轮没有启动本机浏览器代替远程浏览器验收。代理客户端 IP、恢复公网端口、管理员恢复与撤销、凭据轮换、持久投递故障恢复、真实续期告警、容量和异机恢复仍未通过。本轮结果不能用于签署整体生产放行。 diff --git a/docs/生产整改验收清单.md b/docs/生产整改验收清单.md index 38eb925..1444fb4 100644 --- a/docs/生产整改验收清单.md +++ b/docs/生产整改验收清单.md @@ -2,7 +2,19 @@ ## 范围与结论 -### 最新复核:2026 年 9 月 17 日 22:02 主机清理 +### 当前状态:2026 年 9 月 17 日晚间复测 + +本节与《晚间验收复测记录》作为当前状态入口;下方带时间的旧记录保留追溯,不应把早期 SSH 失败、自签名或单次资源失败当作当前结论。已部署程序仍为 `review-2263779`,本轮没有编译或替换应用。 + +- [✓] SSH 可用;8001/8002 与 Nginx 反代、正式可信证书、七个 TLS/STARTTLS 入口复测通过。 +- [✓] 六项远程隔离续期回归通过;备份摘要、证书有效期与关键文件权限复核通过。 +- [✓] 原 128 MiB 保留预算的资源预检五分钟共 11 次采样通过,同一进程、无 OOM;不代表持续负载或生产容量验收,PROD-013 整体仍待完成。 +- [!] Nginx 现已同时承载 Scert 8003/8004;当前到期续期停止整个 Nginx,会影响其他项目,需要明确共用维护窗口或调整方案后演练。 +- [!] 代理客户端 IP、公网恢复端口、远程浏览器业务闭环、管理员恢复撤销、凭据轮换、故障恢复、续期告警、容量与异机恢复仍待验收。 + +结论:维持“不满足整体生产放行”。本轮为无业务写入的部署复测,不冒充清库、最新构建或浏览器首次安装验收。 + +### 历史复核:2026 年 9 月 17 日 22:02 主机清理 本节更新下方 21:51 的资源失败状态。经用户授权清理 47 主机,发现 `/tmp` 为 tmpfs,旧发布及验收文件实际占用物理内存。6 项无进程引用的 Smail、Scert 临时发布文件已完整归档到磁盘,并保留原路径链接;业务数据、证书、已有备份和服务配置未改动。 @@ -13,7 +25,7 @@ 归档及完整清单:`/var/backups/host-tmp-archive-20260917T215952/manifest.json`;五次原始预检:同目录 `resource-samples.json`。未来构建或测试产物应放在磁盘上的项目专用 `/var/tmp` 目录,避免大包再次占用 tmpfs;未改全局临时目录或删除失败测试证据。 -### 最新复核:2026 年 9 月 17 日 21:51 +### 历史复核:2026 年 9 月 17 日 21:51 本节优先于下方早期状态。已使用本次提供的访问凭据恢复受信任主机密钥校验的 SSH 连接,不再将 SSH 认证列为当前阻塞。凭据轮换、历史清理和访问审计仍未完成。 @@ -122,7 +134,7 @@ SSH 脚本复用 `test/tools/remote_ssh.py`,强制核对已知主机密钥。 ## 资源与测试隔离 -47 服务器约 1.6 GiB 内存,无交换空间,另有 MySQL、Scert 等服务。首轮测试仅设置 Go 软内存上限,不能防止全机内存耗尽。新工具通过 systemd 设置 CPU、内存、进程数和最长运行时间上限,使用独立网络、私有临时目录,并禁止访问线上 `/opt/smail`、`/run/smail`。可用内存不足时拒绝开始测试,不自动放宽限制、不停止其他项目。 +47 服务器约 1.6 GiB 内存,晚间复核已有约 4 GiB 主机交换空间,Smail 的 `MemorySwapMax` 仍为零;同机另有 MySQL、Scert 等服务。首轮测试仅设置 Go 软内存上限,不能防止全机内存耗尽。新工具通过 systemd 设置 CPU、内存、进程数和最长运行时间上限,使用独立网络、私有临时目录,并禁止访问线上 `/opt/smail`、`/run/smail`。可用内存不足时拒绝开始测试,不自动放宽限制、不停止其他项目。 `GOMEMLIMIT` 是 Go 回收目标,不是进程或主机硬限制。本轮协议测试以 128 MiB cgroup 上限、25% CPU 配额和 64 MiB Go 回收目标完成,不能据此推导生产容量。生产仍需确定同机服务预算、并发认证开销、邮件大小与吞吐上限、告警和故障恢复指标。