DNS-01 挑战:CNAME 委托机制说明
✅ 工作原理(超简单!)
终端用户只需添加一条 CNAME 记录(一次性设置):
名称: _acme-challenge.example.com
类型: CNAME
目标: <public-id>.acme.cjj365.cc
就这样! 一次性设置后:
- cert-ctrl 自动管理
<public-id>.acme.cjj365.cc上的 TXT 记录 - 终端用户无需 DNS 提供商 API 密钥
- 自动颁发和续期证书
- 零人工 DNS 操作
🔄 完整流程
一次性设置(终端用户)
步骤 1:从 cert-ctrl 仪表板获取您的 public-id
- 添加证书时,cert-ctrl 会生成一个唯一的
public-id - 示例:
abc123def
步骤 2:在您的 DNS 提供商添加 CNAME 记录:
名称: _acme-challenge.example.com
类型: CNAME
目标: abc123def.acme.cjj365.cc
└──────┬──────┘
public-id(来自 cert-ctrl 仪表板)
TTL: 3600(或任何值)
自动化流程(cert-ctrl 后端)
当 cert-ctrl 向 Let's Encrypt 请求证书时:
-
Let's Encrypt 生成挑战令牌
- 示例:
aBcD1234eFgH5678
- 示例:
-
cert-ctrl 在其自己的域名上创建 TXT 记录
名称: abc123def.acme.cjj365.cc
类型: TXT
值: aBcD1234eFgH5678
TTL: 120(2 分钟)这发生在 cert-ctrl 的 DNS(cjj365.cc 区域)上,使用 cert-ctrl 自己的 API 凭证
-
Let's Encrypt 跟随 CNAME 并验证
# Let's Encrypt 查询:
dig TXT _acme-challenge.example.com
# DNS 返回 CNAME:
_acme-challenge.example.com. → CNAME → abc123def.acme.cjj365.cc
# 然后查询目标:
abc123def.acme.cjj365.cc. 120 IN TXT "aBcD1234eFgH5678" ✅ -
cert-ctrl 在验证后删除 TXT 记录
- 保持 DNS 干净
- CNAME 保留用于未来续期(永不改变)
📋 对比表格
| 方法 | 手动 TXT | acme.sh DNS API | cert-ctrl CNAME |
|---|---|---|---|
| 用户设置 | 每 90 天一次 ❌ | 一次性 API 密钥 ⚠️ | 仅一条 CNAME ✅ |
| API 密钥 | 不需要 ⚠️ | 用户必须提供 ❌ | 不需要 ✅ |
| DNS 提供商 | 任何 | 必须支持 API | 任何(仅 CNAME)✅ |
| 安全风险 | 低但需手动 ⚠️ | 高(API 密钥)❌ | 低(无密钥)✅ |
| 续期 | 每 90 天手动 ❌ | 自动 ✅ | 自动 ✅ |
| DNS 清理 | 手动(易忘)❌ | 自动 ✅ | 自动 ✅ |
| 设置难度 | 简单但重复 | 复杂(API 设置) | 简单(一条 CNAME)✅ |
🎯 为什么 CNAME 委托是完美的
cert-ctrl 使用 CNAME 委托,这很巧妙:
# 用户的 DNS(一次性设置,永不改变):
_acme-challenge.example.com → CNAME → abc123def.acme.cjj365.cc
# cert-ctrl 的 DNS(自动,按需创建/删除):
abc123def.acme.cjj365.cc → TXT → "challenge_token"
✅ 优势
- 用户无需 API 密钥 - 用户永不共享 DNS 凭证
- 适用于任何 DNS 提供商 - 只需支持 CNAME(所有提供商都支持)
- 一次性设置 - CNAME 永不需要更改
- 安全 - 用户只委托
_acme-challenge子域名,而非整个区域 - 自动续期 - cert-ctrl 更新自己的 TXT 记录
- 干净的 DNS - 验证后立即删除 TXT 记录
📊 安全性对比
❌ 其他需要 DNS API 密钥的 ACME 工具:
您的 DNS 提供商 API 密钥 → 提供给 ACME 服务
风险:
- 服务可以修改您区域中的任何 DNS 记录
- API 密钥可能泄露/被盗
- 必须信任服务拥有完全的 DNS 控制权
- 难以撤销(会破坏自动化)
✅ cert-ctrl CNAME 委托:
您的 DNS:仅 CNAME 记录(只读委托)
cert-ctrl DNS:管理 cjj365.cc 区域上的 TXT 记录
风险:
- cert-ctrl 只能证明挑战的域名所有权
- 无法修改您的其他 DNS 记录
- 容易撤销(删除 CNAME)
- 无凭证共享
🎯 用户体验对比
传统 DNS API 方法(acme.sh、certbot-dns-*)
步骤 1:注册 ACME 服务
步骤 2:创建 DNS 提供商 API 凭证
步骤 3:在 ACME 工具中配置 API 密钥
步骤 4:担心 API 密钥安全性
步骤 5:请求证书
步骤 6:希望 API 集成能工作
步骤 7:手动部署证书
步骤 8:自动续期(但 API 密钥仍是风险)
问题:
- ❌ 必须向第三方工具暴露 DNS API 密钥
- ❌ 复杂的 API 设置(每个提供商不同)
- ❌ 密钥泄露的安全风险
- ❌ 必须手动部署证书
cert-ctrl CNAME 方法
步骤 1:注册 cert-ctrl
步骤 2:添加证书 → 获取 public-id
步骤 3:添加 CNAME 记录(一次性)
步骤 4:完成!✅
步骤 5:每 60 天自动续期
步骤 6:自动部署到所有代理
优势:
- ✅ 无需管理 API 密钥
- ✅ 适用于任何 DNS 提供商
- ✅ 一条 CNAME,永久完成
- ✅ 自动部署
🔐 安全说明
为什么 CNAME 委托更安全
- 有限范围:仅影响
_acme-challenge.*子域名 - 只读委托:cert-ctrl 只能证明所有权,无法更改您的记录
- 无凭证:您的 DNS 登录/API 密钥保留在您这里
- 容易撤销:只需删除 CNAME 记录
- 审计跟踪:所有操作记录在 cert-ctrl 端
- 临时 TXT 记录:仅在验证期间存在(30-60 秒)
用户无法做什么(有意设计)
用户无法(也不需要):
- ❌ 访问 cert-ctrl 的 DNS 提供商 API
- ❌ 查看或管理
*.acme.cjj365.cc上的 TXT 记录 - ❌ 修改挑战令牌
- ❌ 手动创建/删除 TXT 记录
这很完美! 用户获得自动化而无安全风险。
📝 示例:真实证书请求
逐步可视化流程
1. 用户在仪表板添加证书:
域名:example.com
SAN:example.com, www.example.com
2. cert-ctrl 生成 public-id:
public-id: f8e3c2b9a1d4
3. 仪表板显示 CNAME 指令:
┌─────────────────────────────────────────────────┐
│ 在您的 DNS 中添加此 CNAME 记录: │
│ │
│ 名称: _acme-challenge.example.com │
│ 类型: CNAME │
│ 目标: f8e3c2b9a1d4.acme.cjj365.cc │
│ │
│ [复制 CNAME] [标记为完成] │
└─────────────────────────────────────────────────┘
4. 用户添加 CNAME(在其 DNS 提供商的 Web 界面):
Cloudflare/Route53/阿里云/任何 DNS 提供商:
名称: _acme-challenge.example.com
类型: CNAME
目标: f8e3c2b9a1d4.acme.cjj365.cc
TTL: 3600
5. 用户在 cert-ctrl 仪表板点击"颁发证书"
6. 幕后操作(自动):
cert-ctrl → Cloudflare API(cjj365.cc 区域)→ 创建 TXT f8e3c2b9a1d4.acme.cjj365.cc
Let's Encrypt → DNS 查询 → _acme-challenge.example.com
→ 跟随 CNAME → f8e3c2b9a1d4.acme.cjj365.cc
→ 获取 TXT 记录 → 验证 ✅
cert-ctrl → Cloudflare API(cjj365.cc 区域)→ 删除 TXT f8e3c2b9a1d4.acme.cjj365.cc
cert-ctrl → 自动部署证书到所有代理
7. 用户看到:
✅ 证书颁发成功!
- 已部署到 3 个代理
- 下次续期:60 天后
- CNAME 记录可以永久保留(永不需要更改)
🌐 多域名示例
请求包含多个 SAN 的证书时:
域名:example.com
SAN:example.com, www.example.com, api.example.com
用户需要为每个子域名添加 CNAME:
_acme-challenge.example.com → f8e3c2b9a1d4.acme.cjj365.cc
_acme-challenge.www.example.com → f8e3c2b9a1d4.acme.cjj365.cc
_acme-challenge.api.example.com → f8e3c2b9a1d4.acme.cjj365.cc
所有都使用相同的 public-id,cert-ctrl 自动管理不同的 TXT 记录。
🚀 总结
✅ 什么是正确的
- 使用 CNAME 委托(用户一次性设置)
- 自动管理 TXT 记录(cert-ctrl 在其自己的域名上)
- 用户无需 DNS API 密钥
- 适用于任何 DNS 提供商(所有都支持 CNAME)
- 安全(有限的委托范围)
- 自动续期(CNAME 永不改变)
- 干净的 DNS(验证后删除 TXT 记录)
❌ 什么是错误的
- ❌ 用户不需要手动创建 TXT 记录
- ❌ 用户不需要向 cert-ctrl 提供 DNS API 密钥
- ❌ 用户不需要支持 API 的 DNS 提供商
- ❌ CNAME 无需为续期而更改
- ❌ 用户无需查看或管理
*.acme.cjj365.cc上的 TXT 记录
🎯 关键见解
CNAME 委托分担了责任:
- 用户的责任:添加一条 CNAME 记录(一次性,永不改变)
- cert-ctrl 的责任:自动管理 TXT 记录(使用其自己的 DNS API 凭证)
结果:用户获得完全自动化而无安全风险!🎉
🤔 常见问题
问:如果我的 DNS 提供商没有 API 访问怎么办?
答:没问题!CNAME 记录可以通过任何 DNS 提供商的 Web 界面添加。您不需要 API 访问。
问:我可以使用多个 DNS 提供商吗?
答:可以!每个域名可以使用不同的 DNS 提供商。只需在每个提供商中添加 CNAME。
问:如果我在证书颁发后删除 CNAME 会怎样?
答:当前证书可以工作,但续期会失败。永久保留 CNAME 以实现自动续期。
问:cert-ctrl 能修改我的其他 DNS 记录吗?
答:不能!cert-ctrl 只能在其自己的域名(*.acme.cjj365.cc)上创建/删除 TXT 记录,而非您的域名。
问:如果 cert-ctrl 被入侵会怎样?
答:攻击者只能在 *.acme.cjj365.cc 上创建/删除 TXT 记录,无法修改您的 DNS 区域。删除 CNAME 即可撤销访问。
问:这与 acme.sh 别名模式有何不同?
答:acme.sh 别名模式仍需要您管理 TXT 记录(或提供 API 密钥)。cert-ctrl 为您管理一切。
问:我能看到 cert-ctrl 创建的 TXT 记录吗?
答:可以!在验证期间查询:dig TXT f8e3c2b9a1d4.acme.cjj365.cc(替换为您的 public-id)
问:为什么是 60 天续期而不是 90 天?
答:安全边际。Let's Encrypt 证书有效期为 90 天;我们在 60 天时续期以避免过期风险。
还是不明白? 可以这样理解:
- 🏠 您的房子(DNS 区域):您拥有它,完全控制
- 📬 邮箱委托(CNAME):您放了一个标志说"ACME 邮件送到 cert-ctrl 的办公室"
- 🏢 cert-ctrl 的办公室:我们接收邮件,处理它,永不触碰您的房子
- ✅ 结果:您自动获得证书,无需给我们房子钥匙(DNS API 凭证)