跳到主要内容

cert-ctrl 使用场景图解

使用场景 1:开发环境的自签名 CA

问题:手动 CA 分发

开发者需要在 localhost 上使用 HTTPS

生成自签名 CA

😫 在每台机器上手动操作:

┌────────────────────────────────┐
│ 1. 复制 CA 证书文件 │
│ 2. 安装到信任存储 │
│ • Windows: certmgr.msc │
│ • Linux: update-ca-trust │
│ • macOS: Keychain Access │
│ 3. 配置每个应用程序 │
│ 4. CA 更改时重复以上步骤 │
└────────────────────────────────┘

在 WSL/Docker 中仍然不工作?😭
再重复一遍所有步骤!

解决方案:自动化 CA 分发

┌──────────────────────────────────────┐
│ cert-ctrl 服务器 │
│ • 生成自签名 CA │
│ • 向已认证的代理提供 CA │
│ • 颁发开发证书 │
└──────┬───────────────────────────────┘

│ 代理认证并拉取 CA

├─────────────┬──────────────┬──────────────┐
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│Windows│ │ WSL │ │ SSH │ │Docker │
│ 宿主机│ │Ubuntu │ │远程 │ │ VM │
└───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘
│ │ │ │
┌───▼────────────▼──────────────▼──────────────▼───┐
│ 所有机器自动信任 CA! │
│ • 浏览器:✅ https://app.localhost.dev │
│ • curl: ✅ curl https://api.localhost.dev │
│ • Python:✅ requests.get(https://...) │
│ • Node: ✅ fetch(https://...) │
└──────────────────────────────────────────────────┘

时序图:首次设置

开发者        cert-ctrl        代理            操作系统
服务器 (Windows) 信任存储
│ │ │ │
│ 1. 启动 │ │ │
│──────────────>│ │ │
│ │ │ │
│ 2. 安装代理 │ │
│──────────────────────────────>│ │
│ │ │ │
│ │ 3. 注册 │ │
│ │<───────────────│ │
│ │ │ │
│ │ 4. 发送 CA │ │
│ │────────────────>│ │
│ │ │ │
│ │ │ 5. 安装 CA │
│ │ │───────────────>│
│ │ │ │
│ │ │ 6. CA 受信任 │
│ │ │<───────────────│
│ │ │ │
│ │ 7. 确认成功 │ │
│ │<───────────────│ │
│ │ │ │
│ 8. 浏览 https://app.localhost.dev ✅ │
│────────────────────────────────────────────────>│

使用场景 2:生产证书分发

问题:手动证书部署

从 Let's Encrypt 获取证书

😫 每 90 天,在每台服务器上:

┌──────────────────────────────┐
│ ssh server1.example.com │
│ sudo certbot renew │
│ sudo cp cert to nginx │
│ sudo nginx -s reload │
│ │
│ ssh server2.example.com │
│ sudo certbot renew │
│ ... 重复 ... │
│ │
│ ssh server10.example.com │
│ ... 筋疲力尽 ... │
└──────────────────────────────┘

忘记一台服务器?网站宕机!💥

解决方案:集中式证书管理

┌────────────────────────────────────────────┐
│ cert-ctrl 服务器 │
│ 1. 与 Let's Encrypt/ZeroSSL 通信 │
│ 2. 自动解决 DNS-01 挑战 │
│ 3. 存储证书 + 私钥(加密) │
│ 4. 跟踪到期,自动续期 │
└────────┬───────────────────────────────────┘

│ 代理轮询更新

├─────────┬─────────┬─────────┬─────────┐
▼ ▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│ Web1 │ │ Web2 │ │ API │ │ LB │ │ CDN │
│ Nginx │ │ Nginx │ │Node.js││HAProxy│ │ 源站 │
└───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘
│ │ │ │ │
└─────────┴─────────┴─────────┴─────────┘
所有服务器自动获取证书!✅

时序图:证书续期流程

cert-ctrl     Let's Encrypt    Cloudflare    代理(Web1)   代理(Web2)
服务器 API DNS
│ │ │ │ │
│ 1. 检查到期(第60天) │ │ │
│────────────────>│ │ │ │
│ │ │ │ │
│ 2. 请求新证书 │ │ │
│────────────────>│ │ │ │
│ │ │ │ │
│ │ 3. DNS 挑战 │ │
│ │───────────────>│ │ │
│ │ │ │ │
│ 4. 设置 TXT 记录 │ │ │
│────────────────────────────────>│ │ │
│ │ │ │ │
│ │ 5. 验证 │ │ │
│ │<──────────────>│ │ │
│ │ │ │ │
│ 6. 颁发证书 │ │ │ │
│<───────────────│ │ │ │
│ │ │ │ │
│ 7. 存储并加密证书 │ │ │
│ │ │ │ │
│ │ │ 8. 轮询更新 │
│ │ │<────────────│ │
│ │ │ │ │
│ 9. 新证书可用 │ │ │
│────────────────────────────────>│ │ │
│ │ │ │ │
│ │ │ 10. 部署并重载 │
│ │ │─────────────>nginx │
│ │ │ ✅ │
│ │ │ │ │
│ │ │ │ 11. 轮询 │
│ │ │ │<────────────│
│ │ │ │ │
│ 12. 新证书可用 │ │ │
│────────────────────────────────────────────────────────────>│
│ │ │ │ │
│ │ │ │ 13. 部署 │
│ │ │ │─────────────>nginx
│ │ │ │ ✅

时间线:90 天证书生命周期

第 0 天  │ 证书颁发(有效期 90 天)
│ ✅ cert.example.com(第 90 天到期)

第 30 天 │ 首次续期检查
│ ℹ️ 仍然有效,无操作

第 60 天 │ 触发自动续期
│ 🔄 cert-ctrl 联系 Let's Encrypt
│ 🔄 自动解决 DNS 挑战
│ ✅ 颁发新证书(有效期至第 150 天)
│ 🚀 代理部署到所有服务器
│ 🔄 Nginx/Apache 重新加载(零停机)

第 90 天 │ 旧证书过期
│ ✅ 已经替换!没人注意到!

第 120 天│ 下次续期检查
│ 🔄 重复循环...

对比表格

方面手动管理cert-ctrl
初始设置每个域名 2-3 小时15 分钟(一次性)
续期每 90 天 1-2 小时自动(0 小时)
停机时间每次续期 5-30 分钟零停机
错误率高(人为错误)接近零(自动化)
可扩展性差(线性工作量)优秀(恒定工作量)
多服务器手动复制到每台自动分发
监控手动日历内置警报
安全性磁盘上未加密密钥使用设备密钥加密
审计跟踪完整审计日志

安全架构:设备特定加密

私钥如何保持安全

┌─────────────────────────────────────────────────────┐
│ cert-ctrl 服务器 │
│ │
│ 1. 证书颁发 │
│ 私钥:────────┐ │
│ ▼ │
│ 2. 使用主密钥包装(AES-256) │
│ 加密 Blob:[XXXXXXXXX] │
│ │ │
│ 3. 分配给设备 │ │
│ ▼ │
│ 4. 使用设备公钥包装(X25519) │
│ 设备特定 Blob:[YYYYYYYYY] │
└──────────────────────────┬──────────────────────────┘

│ 通过 HTTPS

┌─────────────────┐
│ 代理 (Web1) │
│ │
│ 拥有:设备 │
│ 私钥 │
│ │ │
│ ▼ │
│ 解密 blob │
│ │ │
│ ▼ │
│ 私钥 │
│ (仅在内存中!)│
│ │ │
│ ▼ │
│ 安装到 │
│ /etc/nginx/ssl/│
└─────────────────┘

❌ Web2 的代理无法解密 Web1 的 blob
✅ 每个设备都有唯一的加密密钥
✅ 服务器从不存储未加密的私钥
✅ 私钥仅在安装期间存在于内存中

代理轮询机制

长轮询实现实时更新

代理                              cert-ctrl 服务器
│ │
│ 1. 轮询(长超时:60秒) │
│─────────────────────────────────────>│
│ │
│ ... 连接保持打开 ... │
│ │
│ │ 2. 颁发新证书
│ │ (第60天自动续期)
│ │
│ 3. 响应:"新证书可用" │
│<─────────────────────────────────────│
│ │
│ 4. 获取证书 │
│─────────────────────────────────────>│
│ │
│ 5. 加密的证书包 │
│<─────────────────────────────────────│
│ │
│ 6. 解密并安装 │
│ 7. 重新加载 nginx │
│ │
│ 8. 再次轮询 │
│─────────────────────────────────────>│
│ ... 连接保持打开 ... │

相对于 webhooks 的优势:

  • 无需配置防火墙
  • 可在 NAT/代理后工作
  • 代理发起连接(安全)
  • 失败时自动重试

多云部署示例

                    ┌────────────────────┐
│ cert-ctrl 服务器 │
│ (您的基础设施) │
└─────────┬──────────┘

┌─────────────────┼─────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ AWS │ │ GCP │ │ Azure │
│ │ │ │ │ │
│ EC2 (Nginx) │ │ GCE (Node) │ │ VM (IIS) │
│ 代理 ✅ │ │ 代理 ✅ │ │ 代理 ✅ │
└──────────────┘ └──────────────┘ └──────────────┘
│ │ │
└─────────────────┼─────────────────┘

所有服务器使用同一证书!
每 60 天自动续期

这之所以可行是因为:

  • 代理拉取证书(仅出站,无需打开防火墙)
  • 同一证书可以部署到任何提供商
  • 设备特定加密保护密钥安全
  • 无供应商锁定

开发与生产工作流

开发工作流

┌──────────────────────────────────────────────────┐
│ 步骤 1:启动本地 cert-ctrl 服务器 │
│ docker-compose up │
│ 服务器自动生成自签名 CA │
└──────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────┐
│ 步骤 2:在开发机器上安装代理 │
│ certctrl-agent install --server localhost:8443│
│ 代理在系统中信任 CA │
└──────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────┐
│ 步骤 3:请求开发证书 │
│ 面板 → 新证书 │
│ 域名:myapp.localhost.dev │
│ 类型:自签名(CA) │
└──────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────┐
│ 步骤 4:在您的应用中使用 │
│ nginx 配置: │
│ ssl_certificate /var/certctrl/cert.pem; │
│ ssl_certificate_key /var/certctrl/key.pem; │
│ │
│ 浏览:https://myapp.localhost.dev ✅ │
└──────────────────────────────────────────────────┘

生产工作流

┌──────────────────────────────────────────────────┐
│ 步骤 1:将 cert-ctrl 部署到生产服务器 │
│ Kubernetes / Docker / VM │
│ 配置 DNS 提供商凭据 │
└──────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────┐
│ 步骤 2:请求公共证书 │
│ 面板 → 新证书 │
│ 域名:example.com │
│ DNS:Cloudflare(API 令牌) │
│ CA:Let's Encrypt(生产) │
└──────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────┐
│ 步骤 3:在生产服务器上安装代理 │
│ ssh web1 && certctrl-agent install │
│ ssh web2 && certctrl-agent install │
│ ssh api1 && certctrl-agent install │
└──────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────┐
│ 步骤 4:将证书分配给设备 │
│ 面板 → 分配 │
│ ☑ web1, web2, api1 │
│ 代理自动部署并重新加载 │
└──────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────┐
│ 步骤 5:然后就不用管了! │
│ • 第 60 天自动续期 │
│ • 零停机部署 │
│ • 出现问题时发送邮件警报 │
└──────────────────────────────────────────────────┘

这些图表展示了两种使用场景的完整工作流程,使用户能够轻松理解 cert-ctrl 如何简化开发和生产环境中的证书管理。