Files
opsx-vpn/docs/specs/SDD-008-ip-certificate-renewal.md
T

61 lines
5.9 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.
# SDD-008:IP 证书、续签记录与证书状态
| 字段 | 内容 |
|---|---|
| 版本 / 变更级别 | 0.1 / S3(ACME、证书部署与公网入口) |
| 设计状态 | 已形成 |
| 实现状态 | 已实现,待部署与兼容 Certbot 版本的真实 IP 签发验证 |
| 负责人 / 日期 | opsx-vpn / 2026-10-26 |
| 关联需求 | IPv4 自动签发/续期;域名与 IP 定时任务及每次成功续签记录;修正 HTTP IP 的证书假状态 |
| 批准状态 | 用户要求开发与核对 |
## 1. 背景、目标与范围
- 当前行为:`GatewaySettings.vue` 凡有公网 Host 即产生证书行,并在 Nginx 模式标为 HTTP-01、Certbot;零值到期时间被浏览器转换为 `1/1/1`。`nginxgateway.RunEntryWithAuth` 仅为域名执行 `certbot certonly --webroot -d`;固定 deploy hook 只执行 `nginx -t` 和 reload。生产 Ubuntu Certbot 2.9.0、certbot.timer 每天两次检查,域名证书有效但尚未到期。
- 目标:HTTP 入口只显示“未启用 HTTPS”,不能伪造证书和续签;支持 HTTPS 公网 IPv4 的短期 ACME 证书签发与自动续签,在当前客户端不具备能力时清晰报告升级要求;记录每次成功续签并在证书页展示最近记录。
- 非目标:在生产强制切换当前 HTTPS 域名到 IP、用自签证书充数、删除已有域名证书或升级系统 Certbot 软件包。
- 保留:运行中 OIDC 回调变更保护、Nginx 白名单、首次签发需 80 可达、既有域名证书和续签行为、OpenVPN 进程。
## 2. 需求与约束
- FR-01:公网 HTTP(含 IP)不显示虚假的证书来源、到期日和自动续签;HTTPS 仅在发现实际有效证书时标为有效,零值时间显示横线。
- FR-02:HTTPS IPv4 允许公网单一非私网 IP;签发使用支持 `--ip-address` 与 `--preferred-profile shortlived` 的 Certbot >=5.4 webroot;不满足条件时在更改站点前报错。IP 证书路径使用与域名相同的 Certbot lineage,验证叶证书的 IP SAN,成功后复用 Nginx HTTPS 与续签钩子。
- FR-03:Certbot 定时器仍负责定时检查;成功续签之后的 deploy hook 先检查、重载 Nginx,再以无密钥信息的时间/lineage 追加记录;页面展示最近记录,未续签不产生成功记录。
- NFR-01:不自动安装来源不明的软件;续签记录路径和证书身份不可被未授权外部输入任意写入;既有钩子只能识别已知旧版本并安全替换;新增状态展示不宣称定时器健康,除非实际探测。
## 3. 架构与方案
`tlsservice` 按协议校验公网 Host,HTTPS IPv4 只允许真正公网单播 IP,证书校验继续使用 `x509.VerifyHostname`。`nginxgateway` 分支执行 IP 专用 Certbot 参数,向用户报告最低版本要求;沿用 webroot 80 路径及 Certbot 的 renewal 配置,由系统定时器负责续签。生成并管理固定 deploy hook:续签成功后执行 `nginx -t` 与 reload,写 root 限权的追加日志。TLS 状态 API 返回最近记录,前端按实际 `certificate_valid`、`cert_source` 和协议显示,证书页给出短期 IP 证书与升级要求提示。
## 4. 接口、数据与配置契约
- `GET /api/system/tls` 增加可选 `renewal_events` 最近成功记录(时间、证书标识);旧字段兼容。
- `PUT /api/system/tls/domain` 接受 HTTPS 公网 IPv4;生产活跃 OIDC 回调仍可返回 409。已有同一 Host 的 HTTP 站点在目标证书缺失时只保存 HTTPS 草稿,显式执行站点启用步骤后才签发并切换;在 Certbot 能力不足时保存前返回 412,保留原站点。
- 固定续签记录:`/var/log/opsx-vpn/cert-renewals.log`,仅成功执行钩子时追加;首次签发和上传应由现有审计记录区分,不误标续签。
## 5. 风险与验收
| 风险或失败场景 | 防护 / 恢复 | 可观察信号 |
|---|---|---|
| 旧 Certbot 不支持 IP webroot | 版本/参数检查前置;保留旧域名站点 | 明确报错、旧站点继续响应 |
| 六天证书无法及时续期 | certbot.timer 每天两次;部署钩子和记录;需运维监控 timer/到期时间 | 证书到期日、续签历史、systemd 日志 |
| 钩子被篡改或日志泄密 | 只替换精确识别的旧版本,安全转义证书标识,不写私钥 | root 文件权限、失败告警 |
| HTTP IP 页面误报 HTTPS | 仅从证书和实际协议渲染 | 空证书行和无续签状态 |
| AC | 对应需求 | 操作 | 预期结果 | 验证 | 结果 |
|---|---|---|---|---|---|
| AC-01 | FR-01 | HTTP IP、HTTPS 域名无证书 | 不显示伪证书或 0001 日期 | 前端构建/代码检查 | 构建和代码检查通过;未做交互测试 |
| AC-02 | FR-02 | 验证公网 IPv4、私网、非法 IP 和 Certbot 参数 | 公网 IP HTTPS 可签,低版本明确拒绝,域名原流程不变 | Go 单测/本机渲染 | Go 单测通过;未在兼容 Certbot 上签发真实 IP 证书 |
| AC-03 | FR-03 | 模拟 deploy hook 记录 | 成功重载后追加事件;不记录失败/未续签 | Go 测试/只读检查 | Go 事件解析与 shell 语法通过;真实续签未发生 |
| AC-04 | NFR-01 | 远端部署检查 | 生产域名登录、OIDC、证书/定时器正常,未改公网模式 | 远端只读探测 | Not Run |
## 6. 发布与恢复
先本地测试构建;远端备份管理二进制及旧 hook 后拉取构建,精确重启管理服务,使用已识别的旧 hook 更新续签记录能力;核对 Nginx、Certbot timer、生产证书到期时间与 OIDC/OpenVPN。保留当前 HTTPS 域名;不发起真实 IP 签发,除非服务器部署兼容客户端并另行切换公网入口。若新 hook 校验失败,恢复旧 hook、二进制,`nginx -t` 并重载。现有 `certbot` 2.9.0 必须明确标记 IP 自动证书尚未就绪。
## 7. 待决问题
| 问题 | 是否阻塞 | 推荐方案 |
|---|---|---|
| 服务器升级 Certbot 来源 | 对真实 IP 签发是 | 使用经管理员维护的 5.4+,避免自动覆盖发行版包;支持到位后再切换 |