Scert/doc/首次IP初始化开发记录.md

163 lines
19 KiB
Markdown
Raw 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.

# 首次 IP 初始化开发记录
## 已确认需求
- 无 GUI 的 Linux 首次启动允许通过服务器 IP 打开初始化页面。
- 完成配置后使用选定的域名或 IP 访问正式管理服务。
- 初始化支持 SQLite、MySQL、PostgreSQL 三种存储方式。
- DNS 面向阿里云,保留多用户、通知及其他原有功能。
- 数据库和 DNS 验证通过后,由服务端保存验证状态;客户端不能通过传入凭据引用绕过验证。
- 初始化入口与正式管理服务分离,初始化未完成时不得启动正式业务和后台续期任务。
## 任务状态(2026-09-16)
这里的“复审通过”仅指对应代码和本地自动化测试,不代表浏览器、Linux 实机或生产验收通过。
- [✓] 配置保存改用同目录随机临时文件;写入、权限、归属、同步和关闭全部在替换正式文件之前完成。
- [✓] 配置保存覆盖首次保存、覆盖保存及各准备步骤失败的回归测试;失败不能改变原正式配置。
- [✓] 新增 `POST /api/v1/bootstrap/complete`,强制初始化会话认证、正文限额、对象类型、未知字段和单段 JSON 校验。
- [✓] 初始化完成接口按错误类别映射状态码,不向浏览器返回底层错误、密码或凭据引用;成功撤销会话并清除 Cookie。
- [✓] 数据库和 DNS 验证结果支持原子领取;领取后令牌不能重复使用,凭据回收责任交给初始化事务。
- [✓] 过期清理、其他验证操作和批量清理不能删除事务持有的凭据;保存失败时精确回收本次领取的凭据。
- [✓] 补齐 32 个并发请求的唯一领取及一次性回收测试,并通过竞态检测。
- [✓] 初始化支持 HTTP、SMTP 通知配置;省略通知对象保留已有设置,新密码只交给敏感信息存储。
- [✓] 通知凭据部分写入失败、配置保存失败时回收本次新凭据,保留原有凭据。
- [✓] 显式关闭通知重试不再在配置重新加载时变回三次重试。
- [✓] 正式管理地址支持 IPv4、IPv6、默认及非默认 HTTPS 端口;代理模式不输出内部监听端口。
- [✓] 初始化提交测试夹具显式隔离所有可写目录,避免 Linux 默认路径指向 `/scert` 或 `/ssl`。
- [✓] CLI 启动状态机:未初始化进入独立 Bootstrap HTTPS,已初始化进入正式应用,损坏配置失败关闭。
- [✓] 接入 `--bootstrap-public-ip`、`SCERT_BOOTSTRAP_PUBLIC_IP` 和 `/run/scert/bootstrap-url`;systemd 为临时地址提供受保护运行目录。
- [✓] 正式应用构造函数拒绝未初始化配置,正式监听器不再提供未初始化明文 HTTP。
- [✓] 前端初始化向导迁移至 Bootstrap API,加入令牌兑换、三数据库选择及验证、通知对象和完成跳转。
- [✓] 正式服务不再注册旧初始化写接口,仅保留状态查询;未初始化桌面端保留本机向导和旧源文件。
- [✓] 桌面端已取得的处理器在配置保存后自动激活正式服务,无需重启窗口即可登录;并发切换、幂等关闭、取消在途初始化和损坏配置均有回归测试。
- [✓] 初始化写请求拒绝跨源访问;前端最终提交重新校验所有步骤和令牌有效期,避免响应乱序、计时缓存及重复提交绕过。
- [✓] 临时 HTTPS、SQLite 初始化、正式 HTTPS 同端口切换、管理员登录和会话可用性通过隔离集成测试。
- [✓] 临时 TLS 启动提示输出实际证书的 SHA-256 指纹供可信运维通道核对,摘要一致性及日志不泄漏回归通过;浏览器人工核对尚未验收。
- [✓] 修复 pgx SQL 注入依赖漏洞并同步桌面端,升级可修补的 gRPC 间接依赖;Windows/Linux 后端和 Windows 桌面端扫描无可达漏洞,保留未导入的 openpgp 模块级告警说明。
- [✓] 增加由本机选择的外部防火墙管理策略,Linux systemd 明确选择该策略;不提权、不自动降级、不冒充端口已验证,提示及本地回归通过,实机验证仍待完成。
- [✓] 修复关闭 Web 静态页面导致核心服务无法启动的回归;保留 API、桌面管理及续期服务,覆盖已初始化和首次切换两种场景。
- [✓] 修复 PostgreSQL URL 查询参数覆盖加密账号、连接目标和脱敏遗漏;新增落盘拒绝、运行时拒绝、特殊密码、驱动优先级及模糊测试,最新全量回归通过。
- [✓] 复审三库接入后的备份恢复兼容性:MySQL 接入加密凭据,PostgreSQL 未实现完整备份时明确拒绝,禁止漏备份却报告成功;内存凭据与拒绝操作的回归测试通过,不代表真实数据库备份恢复已验收。
- [✓] PostgreSQL 官方工具备份及同目标、同对象清单恢复代码和本地回归通过,包含恢复前快照和取消后的独立限时回滚;真实数据库演练、空库灾难恢复和跨结构版本恢复尚未完成,不能宣称三库运维全部验收。
- [!] 新版 Linux 发布包和桌面浏览器验收:本地独立服务启动及发布脚本执行此前被策略拒绝,未绕过限制。
- [ ] 真实 MySQL/PostgreSQL 的连接、迁移、权限及完整业务链路验收。
- [ ] Linux 最小权限 systemd 下的初始化、防火墙及管理入口切换验收。
- [ ] 在明确授权范围内进行真实 DNS、ACME、HTTPS 和远程部署验收。
## 本轮验证
### PostgreSQL 维护功能续接验证(2026-09-16 21:43)
- 修改前创建并推送中文检查点 `943fb8c`,未混入历史补丁、脚本或二进制。
- 最新后端全量普通测试、全量竞态检测、`go vet`、`go mod verify`、`go mod tidy -diff` 全部通过。
- 完整备份、恢复成功/失败/取消/回滚、取消不发布、缺工具保护等关键场景以 `-race -count=10` 重复通过;数据库行为由工具协议替身模拟,没有真实数据库连接。
- 实际子进程失败脱敏、超时终止测试通过;测试子进程是 Go 测试程序,不是 PostgreSQL 官方工具。
- 桌面模块普通测试、竞态检测、静态检查、依赖校验及一致性检查通过;前端 39 项测试及生产构建通过,产物保留在 `.runtime/frontend-postgres-backup-20260916-2128`。
- Linux amd64 无 CGO 源码构建及 CLI 测试二进制交叉编译通过,最新测试产物为 `.runtime/cli-postgres-backup-linux-20260916-2140.test`;没有执行 Linux 测试二进制,没有生成新版发布包或部署远程服务器。
- 覆盖率快照 `.runtime/postgres-backup-20260916-2136.out` 的 CLI 总语句覆盖率为 51.5%,此快照早于最后两个补充测试,不代表全代码全面覆盖或实机验收。
- 中间发现测试代码括号遗漏以及测试断言将 `--no-password` 错判为密码泄漏,均已修正;上述最终全量回归是在修正和全部代码改动完成后执行。
- 差异、Go 格式和 UTF-8 无 BOM 检查通过。文档、注释与提示为中文,无中文 HTML 数字实体;未删除用户历史文件,未连接远程主机或修改真实 DNS、证书和生产数据库。
以下为前序初始化及连接串安全阶段的验证记录,不替代上述本轮结果。
在 Windows 开发工作区执行并通过:
```text
go test -p 1 -count=1 -timeout=4m ./...
go test -race -p 1 -count=1 -timeout=5m ./...
go vet -p=1 ./...
go mod verify
git diff --check
```
桌面模块的 Go 测试、竞态检测、`go vet`、依赖校验及 `go mod tidy -diff` 通过;桌面端依赖已同步后端的 PostgreSQL 驱动等间接依赖。
前端 `npm.cmd test` 共 39 项通过,覆盖初始化令牌兑换、三数据库表单、完整向导提交、通知映射、过期令牌、错误响应、DNS 等待状态及外部防火墙警告。最新前端生产构建通过,产物写入新的 `.runtime/frontend-bootstrap-20260916-2104`,未清理旧产物;生产依赖审计未报告漏洞。
另外,设置 `GOOS=linux`、`GOARCH=amd64`、`CGO_ENABLED=0` 后执行 `go build -p 1 ./...` 通过,仅验证 Linux 目标源码可构建,没有生成或部署本轮 Linux 发布包。2026-09-16 20:35 已收齐新增维护检查后的全量测试、竞态检测、静态检查和 Linux 交叉构建结果,均通过。
2026-09-16 20:57 再次收齐外部防火墙策略、关闭 Web 后保留核心服务以及依赖升级后的后端全量测试、全量竞态检测、静态检查、依赖校验与 Linux 交叉构建结果,均通过。Linux `servicehost` 测试二进制交叉编译通过,但没有在 Linux 执行。
2026-09-16 21:09 收齐 PostgreSQL 连接串安全修复后的最新全量结果:后端普通测试、全量竞态检测、`go vet`、`go mod verify`、`go mod tidy -diff`、Linux amd64 交叉构建和差异检查均通过;桌面模块普通测试、竞态检测、静态检查及依赖一致性校验通过。修改文件经只读检查确认为 UTF-8 无 BOM。本轮仍未生成新版 Linux 发布包,未进行浏览器或远程实机验收。
### 安全依赖与重复验证
- 后端和桌面模块实际使用 Go `1.26.6`,不是系统目录可能显示的其他版本。
- pgx 从 `v5.8.0` 升至 `v5.9.2`,修复 `GO-2026-5004`;gRPC 从 `v1.83.1` 升至 `v1.83.2`,修复 `GO-2026-6443`,并同步 `golang.org/x/net v0.58.0`。
- 最新 Windows/Linux 后端安全扫描为零可达漏洞、零导入包漏洞;Windows 桌面端同样通过。仍有 `GO-2026-5932` 模块级告警:`golang.org/x/crypto/openpgp` 已停止维护且无修复版本。后端导入图未包含该包,不能表述为所有依赖零告警。
- 认证及桌面切换的七组回归以 `-race -count=10` 通过,包括不完整会话失败关闭、512 协程登录准入、容量饱和恢复、来源容量及在途失败上限、128 个本机 HTTP 请求突发、并发激活和幂等关闭、关闭取消在途初始化。
- 阿里云授权、唯一权威区识别、拒绝父区回退、保护域名、撤权重检和精确清理相关测试以 `-race -count=10` 通过,均使用测试替身,没有调用真实云 API。
- SQLite 临时 HTTPS 初始化及正式服务切换、取消启动清理以 `-race -count=3` 通过;完成流程覆盖 `automatic-fixture` 和真实 `external` 管理器,后者不执行系统防火墙命令。
- PostgreSQL 连接串校验模糊测试运行 20 秒、执行 833068 次,无失败;该结果仅说明测试断言和抗异常输入通过,不代表真实 PostgreSQL 服务验收。
覆盖率命令首次因 PowerShell 未正确传递未加引号的 `-coverprofile` 参数失败;给完整参数加引号后重跑通过。报告位于 `.runtime/postgres-config-security-20260916-2107.out`,配置和数据库两包总语句覆盖率为 67.3%,不能据此称为全面覆盖。
测试使用独立临时目录和隔离 SQLite 数据库;阿里云验证、证书签发和防火墙由测试替身模拟,没有修改真实 DNS 或主机防火墙。
MySQL/PostgreSQL 参数、验证状态和凭据处理有自动化覆盖,但这不等于本轮完成两个真实数据库服务的连接、迁移和权限验收。HTTP 接口测试不等于浏览器验收。通知配置测试不等于实际邮件投递。
HTTPS 集成测试只连接本机回环地址,严格校验证书及名称,不使用跳过 TLS 校验。临时初始化结束后,在同一端口启动正式服务并验证登录、会话、管理员接口和 `/readyz`。这里的就绪结果仅证明隔离夹具中的配置、SQLite 和加密凭据可用,不代表真实 RAM 权限、证书信任或远程生产就绪。
## 关键设计与续接注意事项
### 配置提交边界
`Config.Save` 只有正式文件替换成功才返回成功,替换之后不再执行可能返回错误的权限操作,避免调用方错误回滚已提交的证书和凭据。代码不保证断电后的目录项持久性;Linux 目录归属及权限准备仍可能产生元数据副作用。
### 验证凭据的事务所有权
`Claim` 在验证管理器的互斥锁下读取并移除有效令牌,返回验证结果和仅能执行一次的失败回收函数。`Completer` 成功保存配置后不调用回收函数;任何提交前失败都尝试回收。旧 `Resolve`、`Check`、`Consume` 保留给原有调用方,但新 Bootstrap 提交不再采用“先读取、最后消费”的模式。
此机制覆盖当前进程内的受控失败,不承诺进程强制终止后的孤立临时凭据自动恢复;后续启动清理机制应单独复审。数据库迁移和管理员写入可能已发生,不能宣称所有数据库副作用可回滚。
### 通知兼容
完成请求通过可选 `notification` 对象传递通知配置。省略对象保留原有配置,提供对象按完整表单应用;客户端不能指定 `http_credential_ref` 或 `smtp_credential_ref`。HTTP 支持 Bearer、HMAC-SHA256 和账号会话认证;SMTP 密码单独存储。
前端现已将原通知表单映射到该对象,通知步骤保留。不要把客户端输入或底层错误写入公开响应。
### 三库运维边界
新增数据库加密引用后,MySQL 维护操作必须在内存中解密账号再建立连接,不能直接使用无账号的持久化 DSN。恢复前应固定可用连接,避免配置和主密钥替换过程中失去快照或回滚连接。备份校验必须包括数据库凭据引用。
PostgreSQL 原完整备份实现只有 SQLite/MySQL,前序版本先采用明确拒绝保护。2026-09-16 本轮已接入官方 `pg_dump`/`pg_restore`:要求同主版本且至少为 16,生成自定义归档并完整解码校验,配置、加密凭据、证书共同纳入备份清单。缺工具、解码失败或快照失败不能发布备份。
自动恢复只支持相同目标及严格一致的对象清单,保留所有者和授权;先保存当前数据库快照,再以单事务导入,后续证书或凭据失败则恢复原数据。MySQL 和 PostgreSQL 回滚不再沿用已取消请求,改用独立五分钟超时。空库灾难恢复、跨结构版本恢复仍需原生工具和管理员流程。详细前提、保密边界及限制见 `PostgreSQL备份恢复说明.md`;本地替身测试不能替代真实恢复演练。
### PostgreSQL 连接串安全边界
驱动实际会让 URL 查询中的 `user`、`password` 覆盖用户信息部分。旧检查仅检查用户信息,导致查询中的明文凭据可以保存,连接时还可能覆盖已解密的账号。本轮先通过失败回归复现,再把校验集中到 `config.ValidatePostgresDSN`,配置保存、凭据解析和 URL 运行时连接共用边界。
拒绝查询中的账号、密码、客户端私钥密码、目标主机/端口/数据库覆盖及额外凭据文件来源;拒绝重复参数、混合大小写参数、无效编码和片段。继续允许正常 TLS 根证书、连接超时和应用名称等参数,合法配置可保存并重新加载,特殊字符密码经 URL 编码后与驱动解析值一致。
PostgreSQL 连接串日志辅助函数改为整体隐藏,解析失败不返回驱动原始连接串。拒绝无效配置时不读取凭据、不写入配置文件。这里的修复没有实现 PostgreSQL 备份恢复,也不证明数据库环境、连接权限和证书已在实机验收。
### 验收与操作边界
- 新启动链路已接入 `scert serve`,但独立服务的实际页面渲染和新版本 Linux 部署仍未验收。
- IP 管理入口目前使用自签名证书,不能表述为已获公共 CA 信任。
- Bootstrap 临时证书仅保存在进程内;启动日志提供实际证书 SHA-256 指纹,管理员须通过可信 SSH/控制台与浏览器核对,不一致则停止。每次未初始化服务重启都会生成新证书,不能复用旧指纹。
- Linux 固定及动态 systemd unit 显式选择 `SCERT_BOOTSTRAP_FIREWALL_MODE=external`,保留非特权 `Scert` 用户和空网络管理能力集。外部策略不查询、不写入规则,日志及完成响应提示管理员预先配置端口;不证明端口已放行。命令行默认 `auto` 仍失败关闭,操作限时三十秒,不能因权限错误悄悄降级或要求服务提权。
- 本轮未连接远程主机,未操作真实 DNS,未清空既有数据库,未修改 `pcux.cn` 及其证书。
- `47.108.78.12` 用于项目部署;`8.137.23.95` 用于推送测试,两者不可混用。
- 历史未跟踪补丁、测试脚本、二进制和 `dist/` 产物保持不动,不纳入提交。
## 下一步
PostgreSQL 官方工具与真实数据库的 Windows 隔离演练已于 2026-09-17 完成,见下节。下一步继续设计空库灾难恢复和跨结构版本恢复;完成非特权防火墙策略及 Linux 实机验证。在允许启动服务和执行发布脚本的环境中完成浏览器、实际证书指纹核对与 Linux 发布验收。真实数据库和 DNS/ACME 测试必须使用专属测试数据与已授权域名,并明确测试范围,不能清空生产数据库或触碰禁止修改的域名。
## PostgreSQL 真实演练续接(2026-09-17)
- `[✓]` 按最新附件接手中断的官方工具下载,核对本地及远程基线 `3749367`;修改前创建并推送检查点 `515e346`。
- `[✓]` 从 EDB 官方 HTTPS 地址断点续传 PostgreSQL 16.15 Windows 二进制包,文件大小为 333048048 字节;SHA-256 为 `5E8AFFFE67DAF949AEEB03B74951F1EC2324E1888F73FBD036AB0E567AB004D9`。哈希仅作本次文件记录,不等于官方独立签名校验。
- `[✓]` 新增显式启用的真实集成测试及辅助代码,未设置环境变量时跳过,不连接任意外部数据库。每轮自行创建回环地址集群,各场景使用全新数据库及六版实际迁移。
- `[✓]` 使用 SCRAM、严格 TLS 和普通数据库所有者执行最新编译的 Scert;七个场景通过:完整恢复、证书失败回滚、导入后取消回滚、权限不足、对象差异、错误密码、不可信 CA。
- `[✓]` 对比配置、主密钥、加密凭据、证书内容,查询业务数据、自增序列、所有者及授权,并检查恢复前快照保留。
- `[✓]` 首次实测发现测试启动器的输出管道被后台进程继承,造成 `WaitDelay` 超时;改为直接连接空设备后重跑通过。未发现必须修改生产备份恢复逻辑的缺陷。
- `[✓]` 后端全量普通测试、全量竞态检测、静态检查、依赖校验通过;CLI 普通竞态回归重复三轮通过。七个真实场景完成一轮普通演练及三轮竞态重复演练,全部通过。
- `[✓]` 核对五个隔离目录(包括首次启动器失败的一轮)均无运行标记,系统中无残留 `postgres.exe`;完整解压任务已结束,所有历史及本轮产物保留。
- `[!]` Linux 测试二进制只完成交叉编译,尚未执行。没有浏览器或远程部署验收,空库灾难恢复和跨版本恢复仍不支持。
本轮编译产物为 `.runtime/scert-postgres-integration-20260917.exe`;演练目录位于 `.runtime/postgres-integration-20260917/`。测试集群结束后停止,产物保留,不提交测试密码、私钥、数据库目录或二进制。未删除历史补丁、脚本和发布产物,未操作生产数据库、远程服务器、真实 DNS 或 `pcux.cn` 证书。