Skip to content

TLS 与 PKI

AuthNexus 构建了一套完整的 PKI 体系,通过四类独立 CA 实现不同安全域的证书隔离,所有业务通讯均强制 TLS 1.3 + mTLS。

四类 CA 概览

CA 名称标识保护的通讯签发对象
CP Server CAcp_server_caCP 南向接口(:9091Control Plane 服务端证书
CP Node Client CAcp_node_client_ca节点 → CP 的 mTLS 客户端认证业务节点客户端证书
TCP Server CAtcp_server_ca业务 TCP 连接Server App 服务端证书
App Client CAapp_client_caSDK → Server 的 mTLS 客户端认证应用级 SDK 客户端证书

四类 CA 完全独立,各自有自己的根证书、签名密钥和吊销列表。这种设计确保:

  • CP 管控面与业务面的证书互不信任
  • 节点证书被吊销不影响管控通道
  • 应用级 CA 可独立轮换,不影响其他应用

首次 PKI 初始化

Web 部署向导

首次启动 Control Plane 时,系统进入 setup-only 状态

  • 仅开放 /admin/v1/setup/* 端点
  • 不开放 /cp/* 南向接口
  • 不接受任何节点注册

访问 http://localhost:8080 进入部署向导,按顺序初始化四类 CA:

初始化步骤

第一步:CP Server CA

配置 CP 服务端 CA 的根证书参数:

  • 密钥算法(RSA 2048/4096、ECDSA P-256/P-384)
  • CA 有效期
  • 证书主题(Subject)

系统自动生成 CA 根证书和密钥对,并签发 CP 服务端证书。

第二步:CP Node Client CA

配置节点客户端 CA,参数与上一步类似。此 CA 用于签发节点的 mTLS 客户端证书。

第三步:TCP Server CA

配置业务 TCP 服务端 CA。此 CA 签发的证书用于 Server App 的 TLS 监听。

第四步:App Client CA

配置应用客户端 CA。此 CA 签发 SDK 客户端证书,支持按应用隔离。

重要

四类 CA 全部初始化完成后,CP 才退出 setup-only 状态并开放南向接口。中途中断需重新开始。

mTLS 握手验证

业务连接(SDK → Server)

SDK 连接 Server App 时,双向 TLS 握手执行四道约束验证

┌───────────────┐                    ┌───────────────┐
│   SDK 客户端   │ ── TLS 1.3 ──→   │  Server App   │
│               │ ← 服务端证书 ──    │               │
│  客户端证书 ──→│                    │               │
└───────────────┘                    └───────────────┘

约束一:CA 信任链

  • Server 验证 SDK 客户端证书是否由 app_client_ca 签发
  • SDK 验证 Server 证书是否由 tcp_server_ca 签发

约束二:证书语义

  • 客户端证书必须包含 clientAuth 扩展密钥用途(EKU)
  • 客户端证书必须包含格式为 urn:authnexus:app:<id> 的 URI SAN(Subject Alternative Name)

约束三:CP 绑定

  • Server 从 CP 拉取的 app_mtls_trust_bundle 中验证证书绑定关系
  • app_cert_bindings 记录了哪些证书被授权用于哪个应用

约束四:业务握手

  • TLS 握手完成后,SDK 在业务协议层声明 app_id
  • Server 验证 claimed app_id 与证书中 URI SAN 的 app_id 一致

四道约束全部通过后才允许业务通讯。任何一道失败都会拒绝连接。

管控连接(Server → CP)

节点连接 CP 南向接口时:

  • Server 使用 cp_node_client_ca 签发的客户端证书
  • CP 使用 cp_server_ca 签发的服务端证书
  • 双向验证确保只有合法节点能访问管控接口

App Client CA 热替换

应用级客户端 CA 支持运行时热替换,无需停机。

Generation 机制

每次 CA 替换生成一个新的 generation 编号。Server 维护当前有效的 generation:

  1. Admin 通过后台发起 CA 替换
  2. CP 生成新的 CA 根证书,递增 generation
  3. CP 通过 Channel ② 推送 config.pending 事件
  4. Server 拉取新的 app_client_ca_bundle
  5. Server 构建新的 TLS context,包含新 CA
  6. 旧 TLS context 上的在途握手会被拒绝
  7. 后续新连接使用新 CA 验证

注意

CA 热替换后,所有使用旧 CA 签发证书的 SDK 客户端将无法连接。请确保在替换前已完成客户端证书迁移。

CP Node Client CA Reconcile

节点客户端 CA 的 reconcile 是 fail-closed 的:如果 reconcile 失败,节点将无法连接到 CP,直到问题解决。

OCSP Stapling

AuthNexus 实现了完整的 OCSP Stapling 流程,为 SDK 提供证书吊销状态的实时证据。

整体流程

┌──────────┐  ① POST /ocsp/  ┌──────────┐
│  Server  │ ───────────────→ │    CP    │
│  App     │ ←─ OCSP Resp ── │  OCSP    │
│          │                  │ Responder│
│ ┌──────┐ │                  └──────────┘
│ │Staple│ │
│ │Cache │ │
│ └──┬───┘ │
│    │     │
│ ┌──▼───┐ │  TLS Handshake   ┌──────────┐
│ │ TLS  │ │ ←───────────────→ │   SDK    │
│ │Server│ │  + OCSP Staple    │  客户端   │
│ └──────┘ │                   └──────────┘
└──────────┘

Server 端:OcspStaplingManager

OcspStaplingManager 运行在后台 strand 上,负责:

  1. 周期获取:约每 15 分钟向 CP 的 OCSP Responder 发送请求
  2. 自适应刷新:根据 OCSP 响应中的 nextUpdate 字段调整刷新周期(取 nextUpdate / 2
  3. 本地缓存:在 nextUpdate 有效期内使用缓存响应
  4. Staple 到握手:将 OCSP 响应附加到 TLS 握手的 CertificateStatus 消息中

获取 OCSP 响应的 HTTP 请求通过 cp_io_threads 池执行(blocking httplib POST),与 Channel ① 共用实现模式。

CP 端:OCSP Responder

  • 监听独立端口(默认 9092)
  • 使用独立线程池(ocsp_thread_pool_count
  • 每个请求现场签发 OCSP 响应(不缓存)
  • RSA-SHA256 签名

SDK 端验证

SDK 在 TLS 握手阶段验证 OCSP Staple:

验证项说明
签名验证使用 ocsp_signer_ca.pem(= tcp_server_ca 信任锚)验证签名
时间窗校验thisUpdate 到当前时间不超过 maxsec(1800 秒)
证书状态good 放行,revoked 拒绝,unknown 拒绝
must-staple若服务端证书带 must-staple 扩展,无 staple 直接拒绝握手

吊销场景

当管理员在后台吊销某节点的 TCP Server 证书:

  1. CP OCSP Responder 对该证书返回 revoked 状态
  2. Server 获取到 revoked 的 OCSP 响应
  3. Server 继续 staple revoked 响应(不自行关停)
  4. SDK 在 TLS 握手中验证到 revoked 状态,拒绝连接
  5. 业务流量立即中断
  6. 管控通道(mTLS /cp/v2/*)不受影响,因为使用不同的 CA 体系

管理员 re-enable 证书后,下次 OCSP 刷新获取到 good 响应,节点自动恢复。

证书生命周期

节点证书 Enrollment

新节点首次注册的证书获取流程:

  1. 在管理后台创建节点记录
  2. 节点生成密钥对和 CSR(Certificate Signing Request)
  3. 通过管理后台或 API 提交 CSR
  4. CP 使用对应 CA 签发证书
  5. 节点获取证书后启动 mTLS 连接

证书续期

节点证书接近到期时需要续期:

  1. 节点生成新的密钥对和 CSR
  2. 通过管控通道提交续期请求
  3. CP 签发新证书
  4. 节点切换到新证书

Reissue 与恢复

节点证书 reissue 后,必须删除节点旧证书文件才能重新 enroll。节点 enroll 决策只看本地证书文件是否存在——如果旧证书文件仍在,节点会用废弃的证书尝试连接,导致 403 循环。

安全隔离总结

通讯路径传输层认证方式CA 体系
SDK → ServerTLS 1.3 TCPmTLS(双向)tcp_server_ca + app_client_ca
Server → CPTLS 1.3 HTTPmTLS(双向)cp_server_ca + cp_node_client_ca
Server → CP OCSPPlain HTTPOCSP 签名tcp_server_ca(签名验证)
Admin → CPHTTP (loopback)Session Token无(本地 + 反向代理)

下一步