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+,避免自动覆盖发行版包;支持到位后再切换 |