Scert/backend/internal/nginxactivation/README.md

6.4 KiB
Raw Blame History

Nginx 本地激活组件

本组件包含受限的 Nginx 管理证书事务及应用侧双层协调器。应用已接入协调与周期恢复,但正式部署、真实 Nginx 协调及完整自动续期仍须单独验收,不能仅凭组件测试或交叉编译通过就正式切流。

权限边界

  • scert-nginx 独立命令只在 Linux 上运行,以 root 身份加载 root 所有且不可由其他用户写入的独立策略文件。
  • 仅接受 systemd 提供的单个 Unix 流监听器,验证进程编号、描述符数量和固定 socket 路径;不自行监听 TCP、不删除 socket。
  • 服务端通过 SO_PEERCRED 核对固定非 root UID;客户端同时验证 socket 路径及父目录和服务端内核 UID。
  • 请求不能提供命令、配置路径、证书磁盘路径、上游地址或域名;这些值只能来自独立策略。策略引用的 Nginx 配置及其 include 依赖仍须由部署者维护为可信配置。
  • Directory 及其版本目录为激活器所有的 0700 目录,私钥、证书、事务文件使用 0600。应用主进程不获得 Nginx 重载权限。

协议与事务

协议为四字节大端长度前缀和 JSON,版本为 1,帧上限为 2 MiB,拒绝未知字段和尾随内容。并发连接上限为四个;事务冲突直接返回失败,由协调者查询状态,不自动重放变更操作。

动作 行为
ready 检查不存在未决事务、双层 TLS 和专用证书材料一致、Nginx 配置合法
state 返回事务编号、状态和两张叶证书的 SHA-256,不返回私钥或磁盘路径
stage 验证候选,持久化事务并仅切换 Nginx,成功后返回随机事务编号
stage_request 接受应用预先保存的随机请求编号,先持久化占位再暂存;同一编号不允许重放
resolve_request 与暂存使用同一把锁,返回关联事务,或先持久化取消栅栏再返回未执行终态
commit 确认双层已使用候选证书,再记录提交
reconcile 依据实际上游证书回退或提交;无关证书、上游不可用或外部变更时保留未决事务

stage 的应答丢失不等于没有执行。调用方必须用 state 查询,并结合持久化的候选摘要核对事务,不能直接重新申请证书或重试暂存。重复 commit 不返回幂等成功,调用方须确认查询到的是同一事务的提交终态。reconcile 对已完成的同一事务返回原终态,不代表重新验证了当下入口状态。

应用协调器只使用 stage_request,并在签发前要求 ready.request_fencing=true。请求编号为 128 位随机数的规范十六进制文本,不接受任意路径。激活器保留每个请求的占位或取消记录,后续事务覆盖主事务日志也不会解除旧编号的重放保护。尚未进入事务的请求可由 resolve_request 取消;并发暂存持锁时恢复请求失败并等待下轮,不抢先报告取消。取消应答丢失后可查询同一编号,不重放变更操作。

协调记录仍兼容旧版本没有请求编号的记录,但不能为旧请求追溯建立可靠栅栏。旧记录无法确认对应事务时继续保持未决,需要维护人员核对,禁止直接清除。新应用与激活器必须配套升级,旧客户端可能拒绝新增的就绪字段。请求记录目前不自动清理,容量规划须包含这些小文件。

激活等待要求三次间隔 100 毫秒的新连接探测连续通过,每次严格核验证书链、域名、叶证书及 Scert 就绪响应。该检查降低平滑重载过程中偶然命中新工作进程导致的误判,不构成对未来所有连接的保证。

停止服务会取消活动请求并等待有界回退;监听器异常关闭报告错误。请求持有的私钥切片及帧缓冲在返回路径清理,但不声明能够擦除 Go 运行时或 JSON 解码器产生的所有内部副本。

接入前要求

发布包现提供独立 socket/service、拒绝直接使用的策略模板和 --initialize 命令。初始化从 root 受保护副本导入当前证书,核对双层 TLS 与就绪状态,仅创建专用材料,不修改或重载站点;已有状态或失败残留拒绝覆盖。部署步骤见 deploy/nginx/Nginx辅助服务部署说明.md,新增初始化用例尚待 Linux 执行,模板尚未完成 systemd 实机验收。

  1. 安装独立 socket/service,固定调用 UID,初始化专用版本目录并让目标站点引用 active.conf。
  2. 应用须持久化旧状态、候选摘要、激活阶段和关联事务;完整生命周期必须串行化,不能在恢复检查上游之后并发切换上游。
  3. 覆盖代理暂存、上游配置持久化与内存切换、代理提交之间的中断及应答丢失,并在启动时先恢复再允许申请下一张证书。
  4. 不可将本组件的 Recover 视作双层恢复。它只回退代理;Reconcile 也必须由了解应用持久化状态的协调者调用。
  5. 应用等待自身 HTTPS 进入接收循环后开始周期恢复,每次最多 100 秒,结束后等待一分钟;关闭应用会取消并等待恢复。只有 Handler() 的桌面或嵌入式运行时不能充当管理 HTTPS 上游,签发前检查明确拒绝。
  6. 协调记录归应用用户所有,允许中文或空格目录,同时保留 0700、所有者、父路径及链接检查;实际写入 Nginx 指令的激活目录仍限制字符。
  7. 本协议不提供租约超时后强制覆盖、自动清理旧版本或通用 Nginx 管理接口。损坏记录、保存失败、无关证书或配置变动保留保护,不宣称已经完成无人值守续期验收。

验证范围

Windows 测试只能覆盖通用协议和 TLS 探测。Linux 测试覆盖目录、文件、Unix 身份、策略、事务及继承监听器;真实 Nginx 用例需显式指定 SCERT_TEST_NGINX_BINARY。不同 UID 测试需在隔离 root 单元中设置 SCERT_TEST_ROOT_IPC=1,只在临时目录中复制测试程序并降权子进程,不修改真实用户或正式 socket。

TestCoordinatorWithRealNginxAndIPC 使用独立 Nginx 进程和真实 Unix IPC,覆盖正常提交以及暂存、提交应答丢失。上游仍为测试 HTTPS 夹具,不等同于真实应用配置持久化、ACME 签发或正式 systemd 安装验收。2026-09-20 新增用例已交叉编译,当前目标主机身份尚待确认,未执行本轮 Linux 用例。

实机执行命令、程序摘要和失败修复记录见仓库 doc/Linux生产流程测试记录.md。