Smail/docs/云端全项目测试报告.md
smail c7ecf473c4
Some checks are pending
Security Checks / security (push) Waiting to run
记录云端内置DNS续期换证及配置加载修复验收
2026-09-20 05:40:33 +08:00

23 KiB
Raw Blame History

云端全项目测试报告

测试日期:2026-09-20,时区 Asia/Shanghai。工作区:D:\Desktop\Smail。服务器:47.108.78.12,页面:https://web.solit.cn/。

结论与任务状态

已完成一轮全项目自动化测试、发现问题的修复、Linux 构建和云端部署,并完成核心账号安全及邮件协议实机验证。接续补齐了内置 AliDNS 挑战、生产续期入口和 Nginx 自动换证同步,新增修改完成受影响包回归。当前没有未解决的自动化测试失败;真实外部邮箱收件、外部客户端网络路径和自然到期长期调度等仍未验收,不能宣布整个项目最终验收通过。

  • [✓] 已按授权备份、清理 Smail 相关环境,重新初始化测试数据库。接续测试复用本轮数据库,没有重复清库。
  • [✓] 修复测试发现的问题,相关包完成复测;最新程序已部署,云端和本地摘要一致。
  • [✓] 续期补全前的业务代码完成一次独立的 Linux 后端全量复测,66 个包均退出成功;测试程序摘要、逐包日志与汇总已交叉核对。后续续期及配置校验修改按受影响包复测,不混称最新版重新完成 66 包全量。
  • [✓] 三类账号登录、TOTP 选择、提醒行为、邮件验证码跨场景消费、密码重置和客户端凭据撤销完成相应实机验证。
  • [✓] 项目部署包只包含三个程序与四个运行目录,没有加入 Python、部署或续期脚本。
  • [✓] 本轮临时 TOTP、外部邮箱绑定均已停用,账号密码保持用户指定值。
  • [✓] 实时 DNS 控制面、两个权威 DNS 和公共 DNS 均确认泛解析生效;邮件记录保留,DKIM 与运行密钥匹配。
  • [✓] Web 及已启用邮件 TLS、STARTTLS 入口返回同一张覆盖根域名的泛域名证书。
  • [!] 三个指定的 163 邮箱尚未完成真实收件和绑定验证。
  • [!] 当前客户端到公网邮件端口的连接路径未通过,不能声称外网邮件客户端收发通过。
  • [✓] 内置 AliDNS 在真实 staging CA 完成根域名及泛域名挑战、签发、记录清理;生产续期入口成功,配置变化自动触发 Nginx 同步与平滑重载。
  • [!] 尚未等待证书自然进入续期窗口,未完成内置定时调度的长期运行验收。
  • [!] Windows 提权 Named Pipe、依赖外部服务的插件业务等不在本轮 Linux 实机通过范围内。

本轮修复

提交 问题与结果
c82be24 修复全量测试的密码容量竞态,更新与现有行为不一致的审查夹具及前端说明。
b062ca6 项目 DNS 签发同时覆盖主域名及泛域名,保留两条同名 TXT 挑战。
65e61a3 修复真实数据库迁移中对文本主键错误处理序列的问题,校正日志测试。
b515186 公网地址探测支持失败回退,限制并发请求的总等待时间。
7aec99d 密码重置同步撤销旧客户端授权码,补充事务回滚及用户隔离回归。
e0baf27 未认证 POP3 的 QUIT 立即回复并关闭连接,不提交邮箱更新。
310ad01 停用的外部邮箱允许所属用户重新绑定、切换用途;清除旧验证状态并要求重新验证。停用同时失效绑定和变更挑战,保留跨用户隔离及主要邮箱数量限制。
747f79a、951fdc0、1790e1f 加入内置 AliDNS 凭据配置、受控证书导出与同步;修复只读沙箱权限检查,并拒绝硬链接私钥。
62ed09f 修复 Nginx 配置检查在只读沙箱中无法打开 PID 文件的问题。
87cd28f DNS 清理改用受限凭据已有授权的记录列表接口,分页后精确核对 ID、名称、类型和值,只删除本轮创建的记录。
6920bff 续期后上一张证书的引用格式校验不再依赖当前工作目录权限,实际证书路径、权限及密钥匹配校验保留。

每轮代码修改前均保存中文 Git 基线并推送。一次文档基线推送出现认证失败,重试后成功。没有使用宽泛暂存或提交测试凭据。

自动化测试证据

前期云端原始日志根目录:/var/tmp/smail-cloud-tests-20260920/。最新一次全量复测位于 /var/tmp/scf20/final-results/;完整本地副本位于 test-log/cloud-final-20260920/。

范围 结果 证据
Linux 后端单次全量 66 个包均退出成功,1955 个 PASS 标记、0 个 FAIL 标记、5 个 SKIP 标记 /var/tmp/scf20/final-results/summary.json、results.json 及逐包日志
最新前端 200 项通过,0 失败、0 跳过 本地 test-log/run-2026-09-19T21-11-24-986Z-25484/frontend.log
Windows 构建互斥与测试入口 4 项通过;Linux 专用项在 Windows 跳过 本地 test-log/run-2026-09-19T16-13-15-667Z-3920/deployment.log
Linux 资源策略 15 项通过 云端 resource-policy.log
实际服务资源只读预检 通过,无失败项;不替代业务验收 云端 final-resource-check.json
邮箱重新绑定修复的本地受影响包 externalemail、controllers、recovery、verification 均通过 本地 test-log/run-2026-09-19T19-10-20-850Z-26796/backend.log
邮箱重新绑定修复的 Linux 复测 externalemail、controllers 均 EXIT=0 云端 rebind/externalemail.log、rebind/controllers.log
续期及配置校验最终本地回归 config、ssl、controllers、cron_server 通过;smail-config 编译通过,无测试文件 本地 test-log/run-2026-09-19T21-23-32-547Z-34536/backend.log
最终 Linux 配置包 非特权 nobody 用户执行,413 个 PASS 标记、0 FAIL、0 SKIP,退出码 0 /var/tmp/smail-tls-20260920/runtime/config-cwd-full.log
最终 Linux 证书包 非特权 nobody 用户执行,50 个 PASS 标记、0 FAIL、4 SKIP,退出码 0 同目录 ssl-cwd-full.log

上述 66 包全量运行时间为 03:58:42—04:05:54,systemd 记录耗时约 7 分 12 秒、内存峰值 256.5 MiB,结果为成功。66 个包来自同一源码快照,顺序执行,没有合并旧结果或以旧成功替换失败。PASS 标记包含父测试和子测试,不能表述为 1955 个独立案例;主包只有显式跳过的旧集成入口,退出成功不代表该入口已执行。

该次全量的测试源码快照为 418435cb94f62a11e0f5de7fbd913a20f05f7c24,与当时部署源码 310ad01 的后端、前端、对应测试、部署及插件目录无差异。实际测试子进程使用 nobody(UID/GID 65534),每包使用独立临时运行目录,没有指向 Smail 运行数据库。真实 MySQL、PostgreSQL 及跨库迁移集成用例全部执行通过。04:45 后新增续期实现及修复的验证范围为上表中的受影响包,最终部署源码为 6920bff。

已将云端原始证据下载到本地,核对 66 个包的集合无遗漏或重复、退出码全部为 0、每个测试程序 SHA-256 与本地构建收据一致、逐包日志计数与汇总一致。源码归档摘要也与构建收据一致。

  • 构建收据:test-log/cloud-final-20260920/build-receipt.json。
  • 源码归档 SHA-256:8b5475f0dc2e3036c819bcdf70b2fa44d3ab3e99246d7cc1c444d51a00da8c8d。
  • 证据归档:test-log/cloud-final-20260920/final-evidence.tar.gz。
  • 证据归档 SHA-256:3675c8f5a61a9af5373d0a6dfe3b952e53a068259a321d41cda2d49f9ccf3fe5。

此前 latest-summary.json、latest-packages.json 的 1953 个 PASS 是首轮全量与受影响包复测合并的历史统计,仍保留用于追溯;当前结论以本次 1955 个 PASS 的单次全量结果为准。

五个后端跳过项:

  1. TestProductionPluginIsolationPolicy:Windows 专用。
  2. TestSecuritySetupBrowserFixture:需要显式启用的长期浏览器夹具。
  3. TestSystemdResultPrompt:需要隔离的 systemd 人工交互。
  4. TestSystemdCancelledInputResult:同上。
  5. TestMaster:旧集成入口,需显式启用,不能直接指向运行库。

本轮另行完成真实 smail-admin 启动、安全验证、成功提示及 stop 取消操作;自动化跳过项仍按跳过记录。Windows 未提权环境未完成 Named Pipe 验收,不列为通过。

云端业务验证

账号与登录

  • xuans 为超级管理员,testadmin 为管理员,testuser 为普通用户。最终均保留用户指定密码;本文不记录密码、验证码、恢复令牌或 TOTP 密钥。
  • 未配置安全验证的超级管理员登录后,页面强制要求至少启用一种方式。最终浏览器重新加载后可见该中文弹窗,没有跳过保护。
  • 普通用户点击“我知道了”后可继续,注销并重新登录会再次提醒未完成的安全设置。
  • 三类账号均具备用户可选的 TOTP 功能。普通用户实测绑定、登录和停用;密码阶段约 473 毫秒、TOTP 验证约 83 毫秒。其他两类账号本轮早期测试完成后也已停用测试 TOTP。
  • 登录密码正确后,有主要外部邮箱的账号返回验证选择,delivery_status=idle,没有自动发邮件;只有主动发送才进入 sending。

邮件验证码与公开密码恢复

使用普通测试用户的真实站内收件箱临时验证管理员,邮件经项目正常投递与邮件 API 读取,没有改数据库伪造验证结果。此闭环证明应用链路,不替代 163 外部收件验收。

步骤 最后一次实测耗时 结果
停用邮箱重新绑定为主要邮箱 3190 毫秒 成功,仍须邮件验证
确认重新绑定 84 毫秒 成功
管理员密码阶段 341 毫秒 返回 email 选择,邮件 idle
主动发送登录验证码 71 毫秒 返回 sending,后台完成真实投递
邮件码完成登录 103 毫秒 成功
立即发起公开恢复 143 毫秒 识别管理员及 email 方式
紧接着发送恢复邮件 2628 毫秒 成功,没有被登录验证码冷却阻塞
邮件码验证恢复身份 74 毫秒 发放一次性重置凭证
设置密码 307 毫秒 重置成功
重置后密码登录 365 毫秒 成功进入验证选择
再次主动发送登录码 89 毫秒 成功

以上为当次单请求观测,不是负载压测或全网延迟保证。公开恢复请求未携带登录 Cookie 或 CSRF 头。测试完成后通过正式接口停用临时邮箱;管理员再次直接登录约 430 毫秒,超级管理员约 307 毫秒。

邮件协议与重置撤销

  • 服务器本机经域名校验的 TLS 完成 SMTP 投递、IMAP 查询读取和 POP3 收取,数据库收件归属核对正常。证据:protocol-acceptance.json。
  • 真实密码重置后,旧客户端授权码在 SMTP、IMAP、POP3 均被拒绝。证据:revoke/live-revocation.json。
  • 未认证、输入 USER 后及错误密码后的 POP3 QUIT 均立即回应并关闭连接;相关包回归通过。证据:revoke/live-pop3-quit.json。
  • 超级管理员登录页恢复通道保持拒绝;本机重置使用受保护 Unix Domain Socket。最终 /run/smail/admin-control.sock 权限为 0600,所属用户/组为 smail,未增加公网重置 TCP 监听。
  • smail-admin 仅显式 start 进入交互,stop 取消;restart、reload 及变体不能开启新的重置交互。systemd 的 restart 仍可能先停止原交互,这一系统行为边界详见《管理员重置命令限制验收》。

证书与网络限制

真实证书签发者为 Let's Encrypt YR1,SAN 为 solit.cn 和 *.solit.cn,有效期从 2026-09-19 16:44:26 UTC 至 2026-12-18 16:44:25 UTC。服务器通过回环和公网地址连接 443、465、993、995,使用实际域名 SNI、系统 CA 进行校验,均通过 TLS 1.3。浏览器 HTTPS 页面可访问。

本机系统 DNS 将三个邮件子域名解析到 198.18.2.x;本机 Python 不论域名连接还是强制公网 IP,连 443 也发生 TLS EOF。现有证据只能说明客户端网络路径未通过,不能归因为云端证书错误,也不能声称公网邮件客户端收发正常。本轮没有修改本机网络设置。

Google 公共 DNS 已查到 DKIM;对 1.1.1.1 的 UDP 查询超时,未计为通过。本轮 ACME TXT 清理仅针对新建的两个记录 ID,核对剩余为零,既有记录保留。

03:32—03:44 补充实测

以下为接续时重新采集的实时证据,不依赖测试参数或历史快照判定通过。云端证据位于 /var/tmp/smail-cloud-tests-20260920/;本地副本位于忽略目录 test-log/cloud-audit-20260920/。

核验项 结果 证据
DNS 控制面 阿里云当前返回 16 条记录,* A 47.108.78.12 已启用 本地 test-log/cloud-dns-current-20260920.json
权威及公共解析 dns13.hichina.com、dns14.hichina.com、8.8.8.8 共 33 次查询均返回 NOERROR;随机一级子域名、Web 和邮件服务地址均指向服务器 live-dns-audit.json
邮件记录保留 MX、SPF、DKIM、DMARC 均可查到;与清理前快照相比,没有删除原有记录,只新增泛解析并更新 Smail 的 default._domainkey 公钥 同上及本地清理前快照
DKIM 密钥匹配 三个 DNS 查询源中的公钥均与 /opt/smail/ssl/dkim/dkim.priv 推导出的公钥一致;只比较公开材料,不输出私钥 live-dkim-match.json
运行域名 邮件主域名为 solit.cn,后台为 web.solit.cn,公开 HTTPS 端口为 443;域名来自部署配置 live-domain-configuration.json
统一证书 回环 443、8002、465、993、995,以及服务器经公网 IP 访问 443、465、993、995,全部通过系统信任链校验且指纹一致;443、8002 额外使用根域名 SNI 校验通过 live-certificate-unification.json
STARTTLS 证书 回环 SMTP 25/587、POP3 110 升级为 TLS 1.3,证书指纹与上述入口一致 live-starttls-certificates.json
浏览器状态 实际 HTTPS 页面为安全上下文,/api/ping 两次返回 200,约 314 和 164 毫秒,超级管理员强制安全设置弹窗可见 本地 live-browser-check.json 保存最后一次结果

统一证书 DER SHA-256:f369937771b4b3bd4fc1ea624a8eed30e1451c8bcefdcd1c9c15043a33113018。

DKIM 公钥 DER SHA-256:df9958f7e8c20c7d7f8735bb062f7bd7485bbee3bbd254930d7ae8d68ae6731c。

上述 TLS 连接共 14 次,其中服务器经公网 IP 访问内部 8002 的两次连接超时,不列为通过;回环 8002 校验通过,公开后台仍从 443 访问。本轮没有开放内部端口。IMAP 当前使用 993 隐式 TLS,源码和现行默认端口策略一致;143 未启用,连接被拒绝,没有将其计为 STARTTLS 通过。

本机系统 DNS 此次将 Web 解析到 198.18.1.254,邮件地址仍解析到 198.18.2.x。本机 curl 和经本地 HTTP 代理的 Python TLS 连接仍在握手阶段失败;浏览器 HTTPS 正常。没有因此修改系统 DNS、代理或防火墙,也没有将服务器自身访问公网 IP 等同于外部客户端验收。

另发现既有 aliyun-cn-hangzhou._domainkey 同名 TXT 有两条,其中一条公钥明显截断。该记录属于既有阿里云邮件链路,本轮未删除或修改;Smail 的 default 选择器公钥匹配已单独通过。保留 DNS 记录不代表既有阿里云邮件链路也已验收。

仍未通过的项目

项目托管启用内置续期检查,手动及代理托管不触发 ACME,策略测试通过。04:45 后已补齐 AliDNS 自动管理 TXT 及 Nginx 自动同步,实测结果如下。尚未验证自然到期后的长期调度。服务器不依赖外部部署或续期脚本,没有新增外部 ACME 定时器。

指定的三个 163 地址尚未完成真实收件及绑定验证,本轮没有向这些外部收件箱发送测试邮件。后续需由各邮箱持有人接收真实验证码,再通过正式绑定流程完成验证。

04:45—05:40 内置续期与换证补充验收

实际 DNS 挑战与记录保留

通过正式配置接口、超级管理员重新认证及临时 TOTP,保存 management=project、challenge=dns、dnsProvider=alidns、dnsZone=solit.cn。两项凭据加密保存在配置中,公开接口不回填密文或明文。测试后已通过正式接口停用临时 TOTP。

第一次 staging 签发后的清理失败,原因是受限凭据无权调用 DescribeDomainRecordInfo,返回 Forbidden.RAM。该轮明确计为失败,原始日志保留;核对并清理该轮两个记录 ID 后,改用已获授权的 DescribeDomainRecords 分页精确查询,无须扩大云账号权限。

修复后第二次 staging 实测 33.39 秒完成 solit.cn 和 *.solit.cn 的新挑战、签发及清理。staging 证书只保留在测试内存,没有安装至线上。修复前后的四次最终库存均与原始 16 条记录逐条一致,既有记录全部保留,本轮新增挑战没有残留。原本已有的一条 _acme-challenge TXT 同样保留,不将“本轮无残留”描述为所有挑战 TXT 数量为零。

生产续期与 Nginx 自动同步

显式云端测试调用项目生产入口 GenSSL(true),3.90 秒成功保存新证书,配置代次 3→4。生产 CA 复用了有效授权并跳过 DNS 挑战,不能声称该轮重新验证 TXT;真实新挑战由前述 staging 独立证明。为避免两个配置管理器并发,此次测试入口执行前短暂停止 Smail,完成后自动恢复,因此不作为邮件连接连续性或自然到期调度证明。

配置更新自动触发 smail-tls-sync.path;该原生 systemd 单元调用程序本体 smail-config --export-project-tls,原子更新 /etc/nginx/smail/tls.pem,再执行 nginx -t 和平滑 reload。没有 Python 或 shell 续期程序。Nginx 主 PID 始终为 578671,未停止或重启;本轮没有验证重载期间其他站点的长期连接连续性。

同步程序只接受项目受控平铺证书,拒绝符号链接、硬链接及不安全权限;相同内容不重复写入,失败保留原文件。同步服务的只读沙箱仅放行 /etc/nginx/smail、Nginx 日志及 /run/nginx.pid。之前只读目录 chmod 和 Nginx PID 文件访问失败均已修复并实机复测,日志保留失败与成功过程。

当前证书覆盖 solit.cn、*.solit.cn,到期时间 2026-12-18T20:12:03Z;DER SHA-256 为 117d6f2b5b147ea7b98f84d44b22cd1580ffd489eddfdb680d8372f60bc6f2ba。项目新旧两套证书均保留,Nginx 合并文件为 0600 root:root。Nginx 仍使用 HTTPS 8002 上游、web.solit.cn SNI 和系统 CA 校验。

续期后配置加载问题

库存复查发现 config.Init() 报 invalid SSL configuration。在相同配置下,旧测试程序从 /opt/smail、/tmp 成功,从 /root 切换为 smail 用户后失败。原因是上一张证书引用的格式校验调用当前目录绝对路径解析,受到无权访问的工作目录影响,凭据和证书本身未损坏。

新增非特权 Linux 回归先证明旧代码失败,再改为纯引用格式检查,保留平铺名称、成对 token、路径边界及实际文件校验。修复后受限目录场景、路径逃逸/错配拒绝、配置及证书全包回归均通过;相同线上配置从 /root 以 smail 身份读取库存也成功。原始失败日志 dns-final.log 与 runtime/cwd-before.log 均保留。

浏览器与证据归档

05:31 实际桌面浏览器检查 SSL 配置页:项目托管、DNS 验证、阿里云自动续期、托管域名正确显示。两项凭据输入框为空并显示“已设置”,公开接口没有密钥内容。视口 1277×613,无横向溢出、无 HTTP 4xx/5xx 资源;配置读取 67 毫秒。检查后停用临时 TOTP,05:32 确认强制安全设置提示恢复,/api/ping 200、155 毫秒。这是单次观测,不代表负载测试。

05:39 使用当前正式浏览器会话注销后,以用户指定的 xuans 账号密码重新登录:注销 162 毫秒、登录 465 毫秒,HTTP 200、业务错误码 0;认证成功后仍要求至少启用一种安全验证。测试开始时在未注销的强制设置会话内直接调用登录接口,被安全设置中间件拒绝,不能把该拒绝误判为密码错误;随后按完整注销、登录流程验证通过。没有修改账号密码。

云端原始证据:/var/tmp/smail-tls-20260920/live/ 和 runtime/。本地归档:test-log/tls-acceptance/evidence.tar.gz,SHA-256 4990b3502df57fe7af33593ed4c532c39cda208e30e7bce35e2026b493d3c6a2,与云端一致。归档已下载,逐项核对 DNS 集合、失败/成功标记、数据库状态及程序摘要;核对结果为 verified-evidence.json,浏览器结果为 browser-ssl-evidence.json。

最终证书包的四项 SKIP 是需显式启用的真实云端入口;staging、生产续期及库存已在独立日志中执行,不因全包运行时跳过而冒充该次全包已执行真实签发。自然到期长期调度、外部邮箱和外部邮件客户端等剩余边界不变。

最新交付与运行状态

源码提交:6920bff39007c9a2305bb57c47bd27614e17a83c。运行版本:test-222651378aff。后续仅文档和基线提交,不改变部署程序。

发布包:out/release/Smail_linux_amd64.tar.gz。文件结构:

smail/
├── smail
├── smail-admin
├── smail-config
├── config/
├── data/
├── log/
└── ssl/
文件 SHA-256
发布包 c93c621911fa70e5b98ce8853d9e4019c2289748a218c8ccc3d696ebc01fb991
smail e7b6524f148ef01922e628802020c9288ee7b0f0a384c0192c9bd6a988907b96
smail-admin 1c78e5635d1e7fa4680db47d51d5293e2993b357627d56dbc633597f3f49996e
smail-config 044d9d5b34901c4f6a756b9105ca181fd0767d8e664d222e23ee33ecec79816b

本地构建收据:out/release-receipts/Smail_linux_amd64.json。三个云端文件均与收据一致。前端和内置插件构建完成;编辑器分块大于 500 KB 的既有构建提示仍存在,没有构建失败。

05:27:58 完成最后一次人工安装和启动。05:32 复核 Smail PID 为 719778,自动重启次数为 0,Nginx PID 578671、active。回环 443(Web 和主域名 SNI)、8002、465、993、995 六次连接均通过系统信任链与主机名校验,使用 TLS 1.3,证书指纹一致。两个数据库 integrity_check 均为 ok;启用的 TOTP 数量为 0,未停用的外部邮箱绑定数量为 0。最后一次启动后的 systemd warning 级日志查询无记录。本机恢复 socket 保持 0600 smail:smail。

最后一次部署前备份:/var/backups/smail-full-test-20260920/pre-cwd-fix/,含三个旧程序及停服时的配置、数据、证书归档。同级 pre-auto-dns/、pre-renewal/、pre-rebind/ 保留前序状态。测试日志和测试二进制保留在 /var/tmp/smail-cloud-tests-20260920/、/var/tmp/smail-tls-20260920/,不属于运行依赖;没有擅自删除验收证据。FDM、Scert、MySQL 和 PostgreSQL 未因最后一次 Smail 更新而停启;Nginx 在真实换证时平滑重载,最终程序更新没有再次重载。

公网恢复入口已通过正式配置流程设置 http.publicHttpsPort=443;/public-password-recovery 跳转到 https://web.solit.cn/rest/,不再暴露内部 8002 端口,恢复页面返回 200。