44 KiB
云端全项目测试报告
测试日期:2026-09-20,时区 Asia/Shanghai。工作区:D:\Desktop\Smail。服务器:47.108.78.12,页面:https://web.solit.cn/。
结论与任务状态
已完成全项目自动化测试、发现问题的修复、Linux 构建和云端部署,并完成核心账号安全、公网邮件协议和浏览器网页收发实机验证。含内置 AliDNS 挑战、生产续期入口及配置校验修复的源码完成了 66 包云端全量;后续 IMAP 搜索、邮件详情错误状态和插件密钥保存问题均已修复并完成对应回归。当前部署源码为 54396ab,最新前端 210 项通过;插件修复对应三个后端包在云端通过,361 个 PASS 标记、0 FAIL、1 SKIP,未将该版本表述为重新执行过 66 包全量。三个指定 163 邮箱的验证码已取得对端 accepted 记录,仍须邮箱持有人确认收件并完成绑定。当前没有未解决的自动化测试失败;外部邮箱最终收件、自然到期长期调度等仍未验收,不能宣布整个项目最终验收通过。
- [✓] 已按授权备份、清理 Smail 相关环境,重新初始化测试数据库。接续测试复用本轮数据库,没有重复清库。
- [✓] 修复测试发现的问题,相关包完成复测;最新程序已部署,云端和本地摘要一致。
- [✓] 含续期及配置校验修复的源码
88649c8完成独立 Linux 后端全量,66 包成功、1971 个 PASS 标记、0 FAIL、5 SKIP。后续 IMAP 搜索、邮件详情及插件密钥保存分别完成受影响范围回归,版本和日志独立记录。 - [✓] 插件密钥独立保存、加密存储、版本冲突、权限拒绝和操作日志通过验证;临时密钥及管理员测试安全码已撤销,三个插件保持停用。
- [✓] 三类账号登录、TOTP 选择、提醒行为、邮件验证码跨场景消费、密码重置和客户端凭据撤销完成相应实机验证。
- [✓] 项目部署包只包含三个程序与四个运行目录,没有加入 Python、部署或续期脚本。
- [✓] 前期测试的临时 TOTP、站内外部邮箱绑定均已停用,账号密码保持用户指定值;07:19 后申请的三个指定 163 邮箱仍为待验证状态。
- [✓] 实时 DNS 控制面、两个权威 DNS 和公共 DNS 均确认泛解析生效;邮件记录保留,DKIM 与运行密钥匹配。
- [✓] Web 及已启用邮件 TLS、STARTTLS 入口返回同一张覆盖根域名的泛域名证书。
- [✓] 三个指定的 163 邮箱验证码发送均取得对端接收记录,发送接口实测为 2.30—3.23 秒,没有出现 504。
- [!] 三个指定的 163 邮箱尚待持有人确认最终收件并完成绑定验证。
- [✓] 本机 Node 客户端通过公网域名完成 SMTP 认证发信、IMAP 按 Message-ID 查询及读取、POP3 读取同一邮件正文;三个入口均正常校验 TLS 信任链与域名。
- [✓] 真实浏览器完成写信、发送成功、发件及收件阅读、中文附件内容校验;跨账号访问拒绝、失败重试和返回列表通过。系统文件选择器受工具限制未验收,具体边界见末节。
- [✓] 内置 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 |
续期后上一张证书的引用格式校验不再依赖当前工作目录权限,实际证书路径、权限及密钥匹配校验保留。 |
eb5063a |
修复 IMAP SEARCH HEADER Message-ID 总是返回空的问题;支持完整标识、子串、大小写及旧邮件备用标识,回归验证用户隔离。 |
ff13d39 |
邮件详情增加加载、业务错误、网络失败及重试状态,失败时隐藏空元数据和删除按钮;切换邮件清除旧内容,并阻止旧请求覆盖当前页面。 |
54396ab |
Telegram 与微信插件密钥改用独立状态及保存接口,复用权限、安全码、近期认证、加密和版本冲突保护;前端独立保存、清空已保存输入,操作日志不记录密钥载荷。 |
每轮代码修改前均保存中文 Git 基线并推送。一次文档基线推送出现认证失败,重试后成功。没有使用宽泛暂存或提交测试凭据。
自动化测试证据
前期云端原始日志根目录:/var/tmp/smail-cloud-tests-20260920/。续期修复前全量位于 /var/tmp/scf20/final-results/,本地副本 test-log/cloud-final-20260920/。最新全量位于 /var/tmp/scl20/results/,本地证据与校验结果位于 test-log/cloud-latest-20260920/。
| 范围 | 结果 | 证据 |
|---|---|---|
| Linux 后端最新单次全量 | 66 个包均退出成功,1971 个 PASS 标记、0 个 FAIL 标记、5 个 SKIP 标记 | /var/tmp/scl20/results/summary.json、results.json 及逐包日志 |
| 续期修复前单次全量 | 66 包成功,1955 PASS、0 FAIL、5 SKIP,作为历史结果保留 | /var/tmp/scf20/final-results/ |
| 公网搜索修复后的 Linux 回归 | list 9 个 PASS 标记、IMAP 40 个 PASS 标记,两包退出码 0、无失败或跳过 | /var/tmp/smail-public-fix20/list.log、imap.log |
| 最新前端 | 210 项通过,0 失败、0 跳过;含邮件详情与插件密钥回归 | 本地 test-log/plugin-secret-fix-20260920/frontend-latest.log |
| 插件密钥修复的 Linux 回归 | controllers、services/plugin、http_server 三包成功,361 PASS、0 FAIL、1 SKIP;源码 54396ab |
云端 /var/tmp/spi20/results/;本地 test-log/plugin-secret-fix-20260920/cloud-verified/ |
| 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 |
历史 1955 PASS 的全量运行时间为 03:58:42—04:05:54,systemd 记录耗时约 7 分 12 秒、内存峰值 256.5 MiB,结果为成功。66 个包来自同一源码快照,顺序执行,没有合并旧结果或以旧成功替换失败。PASS 标记包含父测试和子测试,不能表述为同等数量的独立案例;主包只有显式跳过的旧集成入口,退出成功不代表该入口已执行。最新 1971 PASS 的独立全量及版本边界见末尾补充记录。
该次全量的测试源码快照为 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 和最新 1971 个 PASS 分别来自两次独立全量,不累加统计。
五个后端跳过项:
TestProductionPluginIsolationPolicy:Windows 专用。TestSecuritySetupBrowserFixture:需要显式启用的长期浏览器夹具。TestSystemdResultPrompt:需要隔离的 systemd 人工交互。TestSystemdCancelledInputResult:同上。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。该失败保留,不据此归因为云端证书错误。05:59 后 Node 使用默认信任链成功连接,06:21 完成真实公网收发,更新了此前“公网路径未通过”的结论。本机 DNS 仍返回现有网络路径地址,没有修改网络设置,也没有声称定位或修复了 Python 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 地址尚未发送测试邮件。07:19—07:23 已通过正式绑定流程分别发送一次验证码,详见末节;最终收件和绑定仍须由各邮箱持有人完成。
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、生产续期及库存已在独立日志中执行,不因全包运行时跳过而冒充该次全包已执行真实签发。自然到期长期调度、指定外部邮箱的边界保留;外部邮件客户端在后续 06:21 记录中通过。
最新交付与运行状态
最新部署源码:ff13d39bd5b72dc295b3ac87b8b68ae83eff30c2。运行版本:test-ed82dfd9e632。06:59:54 完成邮件详情前端修复的云端安装。此前 eb5063a、test-59ee0bb94881 为 06:19:47 的 IMAP 搜索修复版本;6920bff、test-222651378aff 为续期修复部署版本。
发布包:out/release/Smail_linux_amd64.tar.gz。文件结构:
smail/
├── smail
├── smail-admin
├── smail-config
├── config/
├── data/
├── log/
└── ssl/
| 文件 | SHA-256 |
|---|---|
| 发布包 | 28d9a90eb54b3d733ec3eb8f101f00f36d321ebc379266e43bb0d58447a0bf4c |
| smail | 4f6cdb0390007dadda12c13844b39f21a4d07e9d5d7c5d0d5f612978fc84c038 |
| smail-admin | ef25801c19b32c801919667f82a9074bc9578358a9a47e916ac88c87635aee53 |
| smail-config | c22df08b3ab97badd3a1818ee7a896564ecaf9b2961201a89b81e9c4427d25da |
本地构建收据: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。06:19 的更新部署及其最终复核见末节。
最新部署前备份:/var/backups/smail-full-test-20260920/pre-detail-fix/,含三个旧程序及停服时的配置、数据、证书归档。同级 pre-public-search/、pre-cwd-fix/、pre-auto-dns/、pre-renewal/、pre-rebind/ 保留前序状态。测试日志和测试二进制保留在各轮 /var/tmp/ 测试目录,不属于运行依赖;没有擅自删除验收证据。FDM、Scert、MySQL 和 PostgreSQL 未因最后一次 Smail 更新而停启;Nginx 在真实换证时平滑重载,最终程序更新没有再次重载。
公网恢复入口已通过正式配置流程设置 http.publicHttpsPort=443;/public-password-recovery 跳转到 https://web.solit.cn/rest/,不再暴露内部 8002 端口,恢复页面返回 200。
05:51 最终只读复核
本次接续复核没有再次清库、重启服务或签发证书。最初清理前的旧运行目录仍保存在 /var/backups/smail-full-test-20260920/smail/smail/,包含原配置、数据、日志、插件和证书。当前测试库复用本轮初始化结果。
- [✓] 当前配置为
ready,代次为 4;邮件主域名solit.cn、后台web.solit.cn、公开 HTTPS 端口 443。SSL 为项目托管、DNS 挑战、内置 AliDNS,凭据仍为加密存储。 - [✓] 三个运行程序的摘要与最新构建收据逐项一致;两库完整性检查均为
ok。账号xuans、testadmin、testuser的角色及启用状态正确。 - [✓] DNS 控制面当前 16 条记录与续期前库存逐条一致。两个权威 DNS 和 Google 公共 DNS 的 33 次查询全部成功;新随机一级子域名及 Web、邮件地址均指向服务器,MX、SPF、DKIM、DMARC 可正常查询。
- [✓] 三个 DNS 查询源中的 Smail DKIM 公钥均与运行私钥推导出的公钥一致,只输出公钥摘要。
- [✓] 通过系统 CA 和实际域名校验的 9 次回环连接全部使用 TLS 1.3、同一证书指纹及根域名与泛域名 SAN:443 的 Web 和根域名、8002、465、993、995,以及 SMTP 25/587 STARTTLS、POP3 110 STLS。证书指纹为
117d6f2b5b147ea7b98f84d44b22cd1580ffd489eddfdb680d8372f60bc6f2ba,到期时间为2026-12-18T20:12:03Z。 - [✓] Smail、Nginx 及证书同步监听正常,Smail 自动重启次数为 0,最后启动后的 warning 级日志无记录。本机恢复 socket 为
0600 smail:smail。 - [✓] 实际浏览器仍为
https://web.solit.cn/#/安全上下文,/api/ping返回 HTTP 200、业务错误码 0、耗时 150 毫秒;超级管理员强制安全设置提示可见,无横向溢出。 - [✓] 发布压缩包重新列出目录,只有三个程序和四个运行目录,没有部署或续期脚本。
原始复核结果保存在本地 test-log/tls-acceptance/final-audit.json;辅助程序仅经 SSH 在内存中执行只读核验,不是服务器部署或运行依赖。浏览器复核时间为 2026-09-20T05:51:46+08:00。本节没有扩大先前的通过范围:三个外部邮箱的真实收件与绑定、外部邮件客户端网络路径、自然到期长期调度、Windows 提权 IPC 和外部插件业务仍需另行验收。
06:02—06:25 最新全量与公网邮件闭环
独立云端全量
源码 88649c8d130d5dbc0325904285c208581da4d316 的 66 个 Linux amd64 测试程序,在服务器 /var/tmp/scl20 独立执行,06:12:26 完成。systemd 记录墙钟耗时 6 分 10.700 秒、CPU 时间 3 分 1.976 秒、内存峰值 384 MiB,退出成功。所有测试子进程使用非特权 UID/GID 65534,每包独立临时目录;沙箱禁止访问运行目录、恢复 socket 目录和原始备份。MySQL/PostgreSQL 使用专用测试凭据,没有清空运行库。
结果为 66 包退出成功、1971 个 PASS 标记、0 FAIL、5 SKIP。前述五个跳过项不变。已逐包核对清单、二进制摘要、源码归档摘要、退出码及日志计数;真实 MySQL、PostgreSQL、两者间迁移及日志数据库集成均有实际 PASS 记录。
本地 test-log/cloud-latest-20260920/verified.json 保存复核结果;证据归档 evidence.tar.gz 的 SHA-256 为 3118e86306a7a3212c02f332459a8a66fe63ca32f1dea9cb237e8e5520652c0c。本次全量含之前续期及配置修复。后续 eb5063a 只修改 IMAP 搜索及其测试,完成两个受影响包回归,不表述为该提交又重跑 66 包。
公网路径与修复
05:59 本机 Node TLS 客户端对 Web 443、SMTP 465、IMAP 993、POP3 995 分别使用域名和公网 IP 加正确 SNI 连接,共 8 次成功,均启用默认信任链和域名校验,TLS 1.3,证书指纹与线上一致。证据:test-log/public-tls-latest.json。系统 DNS 仍为现有网络路径,未修改 DNS、代理或防火墙。
06:09 首次真实 SMTP 发送成功,但 IMAP 按 Message-ID 查询为空。只读数据库确认邮件已入收件箱,排除只入队未投递。源码 matchesHeader 缺少 message-id 分支;新增回归在旧代码失败,补齐分支后通过,覆盖完整值、大小写、子串、旧邮件备用标识和跨用户隔离。云端 list 包 9 个 PASS 标记、IMAP 包 40 个 PASS 标记,均无失败和跳过。
修复构建于 06:19:47 部署。测试客户端曾因缺少 Origin 头被同源保护拒绝,补齐后正常;首次正文校验未解码 MIME Base64 也曾失败,修正客户端解码后通过。这两项属于测试客户端问题,未削弱服务端保护或更改邮件内容。失败证据保留。
06:21:34—06:21:41,从 Windows 本机通过公网域名完成新邮件闭环,账号为本轮普通测试用户,邮件只投递到其自有站内邮箱:
| 步骤 | 耗时 | 结果 |
|---|---|---|
| 正式 API 密码登录 | 463 毫秒 | 成功 |
| 临时开启协议并创建客户端授权 | 640 毫秒 | 成功 |
| SMTP 465 认证及发信 | 3602 毫秒 | 认证成功,DATA 接受 |
| IMAP 993 查询及读取 | 616 毫秒 | Message-ID 匹配,解码正文匹配 |
| POP3 995 读取 | 840 毫秒 | 同一 Message-ID、正文匹配 |
| 撤销后重试 SMTP 认证 | 538 毫秒 | 返回 535,旧授权不可用 |
三个邮件入口均使用 TLS 1.3、默认 CA 和域名验证,证书 DER SHA-256 为 117d6f2b5b147ea7b98f84d44b22cd1580ffd489eddfdb680d8372f60bc6f2ba。最终邮件 Message-ID:<public-b5529d78-68a3-44f0-9cec-242d73a268c6@solit.cn>。数据库同时存在发件成功记录和收件箱记录;没有删除测试邮件。
闭环证据:test-log/public-mail-bdc12c69-9fc2-4d36-a1cf-2b1cb3eb34e0.json。云端回归与安装证据本地副本:test-log/public-mail-fix-build/evidence.tar.gz,SHA-256 bf2bb8e5be83a984ea12b671db300b3d67bdbdd80020a9a1ab6c757987b8822b。临时授权只在内存使用,已撤销;测试协议开关全部恢复,测试会话已注销。本次是自有域内邮箱的公网客户端收发,不能替代 163 等外部邮件运营商的投递验收。
最新运行及浏览器复核
06:23:58 只读复核:Smail PID 723515、active、自动重启 0,Nginx PID 仍为 578671,证书同步监听 active;三个程序摘要与收据完全一致,两库完整性均为 ok,有效客户端授权数量为 0,普通测试用户三个协议开关均关闭。本机恢复 socket 为 0600 smail:smail,本次启动后的 warning 日志无记录。六次回环证书验证全部通过。证据:test-log/public-mail-fix-build/runtime-audit.json。
06:22:51 实际浏览器页面 HTTPS 安全上下文正常,ping 200、301 毫秒,强制安全设置提示可见,无横向溢出。06:24:59 在同一正式浏览器会话中注销后,用用户指定的超级管理员账号密码重新登录:注销 146 毫秒,登录 317 毫秒,HTTP 200、业务错误码 0、角色 super_admin。未修改账号密码。06:29:45 清理该页 Cache Storage 并重新加载后,ping 200、290 毫秒,强制提示仍可见,无横向溢出,浏览器可见资源状态没有 4xx/5xx。
仍需另行完成:三个指定 163 邮箱真实收件及绑定、自然进入证书续期窗口后的长期调度、Windows 提权 Named Pipe、依赖外部服务的插件业务。本轮没有把这些项目标记为通过。
06:31—07:06 浏览器网页收发与详情修复
本次沿用同一轮已经清理和初始化的云端数据库,没有重复清库。实际桌面浏览器始终复用独立上下文内的 Smail 页面,测试前检查云端服务;部署后清理该页 Cache Storage 并重新加载,实际加载了新版 EmailDetail-ecbfb4cc.js 和对应样式。
写信、投递与附件
普通测试账号 testuser 在真实写信页面向自己的 testuser@solit.cn 发送中文邮件,主题为“云端网页收发验收 20260920-0638”,正文标识 web-mail-20260920-0638。发送请求 HTTP 200、85 毫秒,页面先显示“邮件已提交,正在投递”,发件箱刷新后显示“发送成功”。发件 ID 14、收件 ID 15,共用 Message-ID 6994a5f544999fbf9711ac26d88e637b.1789857759152323508@solit.cn,数据库归属均为 testuser;发送创建于 06:42:39,收件创建于 06:42:43。唯一投递队列项为 accepted、尝试 1 次、无错误,不能仅用发送 API 的 200 代替投递成功。
中文正文及附件名称在发件、收件详情均正常显示。附件 中文附件.txt 为 139 字节,SHA-256 为 0d94d22e10ea07cb478932fec4e8ec701646574911a08c1f637c2ccab2a372ff;本地原件、两份数据库附件及下载内容一致。首次发件、收件下载分别为 66 和 67 毫秒,均 HTTP 200;部署后 07:02 再次下载仍匹配,响应头保留 UTF-8 中文文件名。测试邮件保留,没有删除。
工具边界:MCP 上传工具拒绝项目目录路径,未能操作系统文件选择器。随后在页面创建相同内容的 File,通过现有文件输入框的 change 事件进入产品 FileReader 和发送流程。因此附件处理、投递和下载已经验证,系统文件选择器仍未验证。编辑器初次 fill 没有正确更新内容,刷新后用键盘输入并确认正文再发送,没有把辅助工具错误视为产品缺陷。
账号隔离与错误页
正式注销普通用户后登录 testadmin。对 ID 14、15 的邮件详情均返回 HTTP 200、业务码 500、“读取邮件失败”;对应附件均返回 HTTP 200、业务码 100、“附件不可用”。四个响应数据为空,没有邮件正文或附件内容,跨账号隔离通过。补采证据首次遗漏 CSRF 头,被来源校验拒绝;补齐后得到上述业务拒绝结果,前者没有作为隔离验收依据。
此时页面仍显示 ?、<>、空收件人模板。原因是详情逻辑没有检查业务错误码,也没有加载和错误视图。ff13d39 补齐中文状态、重试及明确返回邮件列表,错误状态不显示邮件元数据和删除按钮;切换路由立即清空旧内容,旧请求完成或失败不会覆盖新邮件,离开页面后也不会继续更新状态。后台权限逻辑没有修改。
前端新增六项回归覆盖业务拒绝后重试成功、网络失败、无效编号及异常响应、异常地址与附件字段、切换路由后的迟到响应、离开页面的未完成请求。全量前端为 206 项通过、0 失败、0 跳过。本次没有后端源码改动,后端全量与 IMAP 回归范围仍以前述记录为准。
06:59:54 部署后实际浏览器验证:管理员看到“邮件暂时无法查看/读取邮件失败”;点击重试仍正确拒绝,点击返回进入 #/list。普通用户从收件箱打开 ID 15,可见完整中文正文和附件,下载摘要匹配。随后同一详情组件切到 ID 14,附件地址同步变为 /attachments/download/14/0;切到不存在的 ID 999999999,显示失败且旧正文和删除按钮消失;再回 ID 15,正文正常恢复。没有横向溢出,控制台无 error 或 warning。云端页面验证的是实际业务拒绝和正常恢复;网络异常由自动化回归覆盖,没有人为中断线上服务。
最终运行与证据
07:05:01 只读核对:两个 SQLite 数据库完整性均为 ok;Smail PID 725122、active、自动重启 0;Nginx PID 578671、active;证书同步监听 active。三个程序 SHA-256 与最新发布收据完全一致,本机恢复 socket 仍为 0600 smail:smail,此次启动后的 warning 级日志无记录。
普通测试用户正式注销后,通过页面使用用户指定密码恢复 xuans 登录,登录请求耗时 358 毫秒;正式用户信息接口业务码 0、角色 super_admin。07:05:51 确认可见“请至少启用一种安全验证后继续”强制弹窗。页面 ping 147 毫秒、业务码 0,没有可见 HTTP 4xx/5xx 资源。这些时延仅为本次观测,不是负载保证。
本地证据目录:test-log/web-mail-20260920/,含 browser-evidence.json、isolation-before.json、detail-after.json、部署收据 install-result.json、构建日志 build.log、更新前后的 server-before-detail-fix.json 与 server-evidence.json。临时 SSH 辅助文件仅用于本次测试,不进入发布包,也未安装为服务依赖。首次辅助断言误将队列状态写为 delivered,核对产品实现后改为真实的 accepted 并复核,没有改动产品投递状态。
- [✓] 网页写信、投递状态、收发详情及中文附件校验。
- [✓] 跨账号邮件和附件隔离、详情失败展示、重试和返回列表。
- [✓] 最新前端回归、Linux 打包、备份部署、程序摘要与数据库核对。
- [✓] 恢复超级管理员登录及强制安全设置提示。
- [!] 三个外部邮箱真实收件和绑定、证书自然续期长期调度、Windows 提权 IPC、外部插件业务、系统文件选择器仍未纳入通过范围。
07:12—07:24 外部邮箱实际投递
本次接续沿用现有云端环境,未清库、重启、修改程序或网络规则。账号密码保持用户指定值,没有把验证码、邮件正文或会话凭据写入报告及证据。测试辅助操作没有进入发布包。
网络诊断与实际结果
当前 SMTP 中继的主机、账号和密码均未配置,验证码使用项目自身投递。首次配置探测将非空密码结构误判为已配置,随后按密文字段重新核对,实际未配置;保留两次原始证据,结论以字段核对为准。
163 的四个 MX 名称均解析成功,本次解析指向 111.124.203.43、111.124.203.50。四个主机的 25 端口探测以及两个 IP 的直接 25 端口探测均超时。QQ MX 的 25 端口也未连通;服务器 UFW 默认允许出站,当前 IPv4 filter OUTPUT 链未见拒绝规则。尚未定位限制发生的网络环节,不能仅据此断言云平台封禁。
smtp.163.com 的 465、587 端口连接成功。进一步探测 163mx01.mxmail.netease.com 和 163mx03.mxmail.netease.com 的 465 端口,默认 CA 与主机名校验通过,均使用 TLS 1.3,EHLO 返回 250。以上探测没有发送 DATA 邮件。现有投递实现支持 MX 的 25、465、587 备用路径,因此 25 端口超时不等于整条外发链路不可用;下述正式业务请求实际投递成功。
三类账号验证码发送
| 账号 | 指定邮箱 | 操作与耗时 | 云端结果 |
|---|---|---|---|
xuans |
likb_blue@163.com |
真实浏览器点击发送,最近认证要求先确认密码;重新认证 383 毫秒,之后绑定请求 3233 毫秒 | 验证事件 success,投递 accepted,绑定 ID 2 为 pending |
testadmin |
xuanspark@163.com |
公网正式 API 登录 437 毫秒,绑定发送 2299 毫秒 | 验证事件 success,投递 accepted,绑定 ID 3 为 pending |
testuser |
gfxezc@163.com |
等冷却后重新登录 583 毫秒,绑定发送 2308 毫秒 | 验证事件 success,投递 accepted,绑定 ID 5 为 pending |
三个成功绑定请求均 HTTP 200、业务码 0,并返回真实绑定和挑战信息。服务器分别在 07:19:12、07:21:43、07:22:59 记录系统安全验证邮件 accepted、acceptedCount 为 1,验证事件均为 issue/success。日志只记录发送元数据;accepted 表示对端服务器接收,不代表邮件已进入收件箱,更不代表持有人完成验证。
普通用户第一次在管理员发送后立即提交,99 毫秒返回业务码 100、“验证码发送过于频繁,请稍后再试”,对应事件为 blocked。源码确认同一来源的发送冷却为一分钟;等待超过一分钟后正式重试成功,没有清理限流状态或调整规则。失败请求创建的待验证记录由产品自身回滚,因此最终普通用户绑定 ID 为 5。这次是尚未使用验证码时的正常发送冷却,不是已完成业务后冷却没有释放;验证码消费后的跨场景释放已在前期闭环中验证。
管理员和普通用户的辅助 API 会话均已正式注销。超管浏览器保留在邮箱验证码输入步骤,显示脱敏地址及倒计时;07:23:31 页面 ping 为 139 毫秒、HTTP 200,无横向溢出。上述均为当次请求观测,不是负载测试或所有投递路径均小于五秒的保证。外部绑定仍同步等待投递,本次没有复现 504,也没有修改同步流程。
待人工收件与运行复核
三个指定邮箱均为 primary、pending,verified_at 为空。没有读取外部收件箱,没有伪造验证码或直接修改验证状态,超管的安全验证要求仍有效。下一步由邮箱持有人查看收件箱及垃圾邮件,通过正式页面输入验证码;过期后重新发送即可。管理员、普通用户需要重新进入各自账号的绑定窗口,使用原指定地址申请新验证码。
07:24:28 复核:Smail PID 725122、Nginx PID 578671 均 active,Smail 自动重启次数仍为 0,证书同步监听 active。两个数据库完整性均为 ok,三个程序摘要与发布收据一致,三类账号启用状态正确。本机恢复 socket 保持 0600 smail:smail。此次只有测试报告更新,没有新产品修改,也不重复宣称重新执行全量构建和回归。
本地证据目录为 test-log/external-mail-20260920/:configuration-network-before.json、network-probes.json、network-differential.json、superadmin-delivery.json、other-accounts-delivery.json、testuser-delivery-retry.json、delivery-metadata-before-retry.json、final-server-evidence.json、browser-evidence.json。早期邮件日志查询按字符串 ID 排序未取到最新记录,最终证据按 created_at 排序核对三条新投递,不以早期查询缺少记录判定投递失败。
- [✓] 三个指定外部地址各一次实际验证码投递,对端接收及失败冷却重试证据齐全。
- [✓] 最终数据库、程序摘要、服务状态及本机恢复边界核对。
- [!] 外部邮箱最终入箱和持有人验证码验证尚未完成;其余长期调度、Windows 提权 IPC、外部插件及系统文件选择器边界保持不变。