Smail/docs/DNS签名参数隔离补充验收.md
smail d6b74bcaad
Some checks are pending
Security Checks / security (push) Waiting to run
修复DNS签名参数复用并完成云端回归与安全复扫
2026-09-21 21:55:02 +08:00

96 lines
6.2 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# DNS 签名参数隔离补充验收
## 结论与范围
2026 年 9 月 21 日,基于已推送的 `33eab66` 继续复核 DNS 签名。
发现并修复请求函数改写调用者参数、复用参数时旧签名参与新签名计算的缺陷。
本地竞态回归及云端 SSL 包隔离回归通过,**不构成真实 DNS 续期、服务商认证、全协议换证或全项目生产验收通过。**
当前 `Present`、记录查询及 `CleanUp` 每次都新建请求参数,没有证据表明现有线上调用正在触发复用缺陷。
本批是对私有请求函数的健壮性整改,不能反推历史证书问题的根因。
## 任务状态
- [✓] 独立签名验证器及固定向量复核。
- [✓] 干净参数连续复用、已有旧签名参数两组失败反例。
- [✓] 请求参数深复制,签名前排除旧签名,不回写调用者对象。
- [✓] 请求方法、编码、随机数、时间戳、签名及密钥不明文发送的回归断言。
- [✓] Windows SSL 包竞态回归,明确保留三项平台权限跳过。
- [✓] 云端 Linux SSL 包全量测试及独立只读证据复核,零跳过。
- [!] G505 的协议迁移、风险评估与可审计排除尚未关闭。
- [!] 真实云凭据轮换、服务商 API 实测、真实续期及全协议换证尚未完成。
## 修复与反例
原请求函数直接向传入的 `url.Values` 写入公共字段和签名。
第一次请求结束后,参数对象残留 `Signature`;再次使用它时,签名原文把旧值也包含进去。
预先带有旧签名的参数会从第一次调用开始不匹配。
现在为每次请求复制参数及其切片,复制时排除 `Signature`,之后只修改独立副本。
随机数仍由密码学随机源生成,每次请求重新生成时间戳;没有改动签名算法、TLS 校验、超时或跳转策略。
原始失败日志:
- `dns-signature-before-20260921.log`:带旧签名参数的三次请求均不匹配,且调用者参数被改写。
- `dns-signature-before-v2-20260921.log`:增加干净参数复用反例,第二次起签名不匹配;两组反例均失败。
原始日志没有删除或覆盖。验证器按 UTF-8 字节独立编码,不调用生产的百分号编码函数。
固定输入由独立 Python 标准库计算,向量文件为 `dns-signature-vector-20260921.json`。
向量中的密钥、签名都是公开测试样本,不是真实云凭据;它不是服务商发布的官方测试向量。
## 协议参考与告警边界
从阿里云官方 Go SDK 仓库的 `sdk/auth/rpc_signature_composer.go` 取得参考实现,核对 RPC 签名字段、签名前移除旧签名及编码流程。
这仅证明该 SDK 实现使用相应签名方式,不证明当前 API 必须使用该算法,也不代表服务商禁止迁移其他签名协议。
本轮没有擅自把 HMAC-SHA1 替换为其他算法,亦不将其作为密码存储或证书签名算法使用。
G505 继续保留,没有添加忽略标记,也没有把“协议使用”自动认定为安全风险已消除。
参考地址:
```text
https://raw.githubusercontent.com/aliyun/alibaba-cloud-sdk-go/master/sdk/auth/rpc_signature_composer.go
```
下载快照为 `alidns-sdk-signature-20260921.go`,SHA-256 为 `e1b4f41a66e86f5bb6e5601c3f12fb7375f8a2b19df988bb6a3754cd81c3f333`。
初次访问帮助中心旧地址得到 HTTP 200,但内容实际为错误页;该页面不作为协议依据,保留快照 `alidns-signature-official-20260921.html`。
## 本地与云端结果
| 范围 | 实际结果 | 未覆盖内容 |
| --- | --- | --- |
| Windows SSL 包竞态回归 | 25 个顶层测试及 26 个子测试通过,3 个顶层测试跳过,零失败 | Windows 当前身份无法创建符号链接 |
| Linux SSL 包全量隔离回归 | 28 个顶层测试及 26 个子测试通过,零跳过、零失败 | 不是整个后端全量测试,不是真实 DNS 服务商联调 |
| 新签名专项 | 两组复用场景各连续三次验证,固定向量通过 | 随机数有限样本不等于数学上的唯一性证明 |
| 收尾复核 | 程序、日志与源码摘要匹配,六个保护服务及正式程序不变 | 正式实例没有升级 |
云端目录:`/var/tmp/smail-review-ssl-apex-20260921/20260921-210920-dns-signature`。
测试使用非特权用户、私有网络与私有临时目录,内存上限 256 MiB,CPU 配额 50%,禁用交换,禁止访问正式 `/opt/smail`。
测试中的请求由受控模拟传输层处理,没有使用真实云凭据、修改公网 DNS 或访问 ACME 服务商。
临时单元已被系统回收,状态为 `LoadState=not-found`、inactive、PID 为零;清理停止命令返回 5 表示单元已不存在,不冒充该命令返回零。
测试程序 SHA-256:`4b374cd7a8f0e4516336a868a9797db7d7803feabbfc8b055ce229da70b7e1bd`。
云端日志 SHA-256:`0fb5619ab93cd6c23b804eb267845489d2dfe5eafd8ae5cd3ac736c24e6bd06b`。
21:20 完成独立只读复核,本包源码与编译前记录一致,正式六服务与程序保持原状。
证据位于 `test-log/production-remediation-20260921/`:
- `dns-signature-after-race-20260921.log`
- `dns-signature-sources-20260921.json`
- `dns-signature-build-20260921.log`
- `ssl-apex-dns-signature/test.log`
- `ssl-apex-dns-signature/result.json`
- `dns-signature-independent-recheck-20260921.json`
## 当前候选完整静态复扫
包含本批 DNS 修复及上一批发布回滚修复的后端已完成 Linux 目标全项目扫描:84 个包、348 个非测试源码文件,无包加载错误,38 条告警,退出 1。
规则分布为 G115 两条、G202 五条、G304 二十条、G302 八条、G306 两条、G505 一条。
忽略标记仍为原有的五个;告警规则、文件和归一化代码片段与此前报告相同,没有通过屏蔽规则降低数量。
619 份后端 Go 源码摘要未漂移。详见 `静态安全告警复核记录.md` 和 `gosec-release-dns-final-linux-20260921.json`。
本次扫描完成不等于扫描通过,更不等于生产放行。
## 后续门禁
仍需补齐签名协议的当前服务商支持范围与迁移评估、历史云凭据处置、真实续期及全协议换证。
浏览器、外部投递、迁移中断临界点、长时容量、异机灾备与最终统一候选验收也不能由本批替代。