跳到主要内容

ACME 域名所有权验证方式(CNAME / DNS API / HTTP-01 / TLS-ALPN-01)

cert-ctrl 在签发或续期证书(Let’s Encrypt / ZeroSSL)时,需要通过 ACME 的“挑战(challenge)”来证明你对域名(或 IP)的控制权。

在我们的系统里,一个证书可以通过以下方式完成验证:

  • CNAME 委托(DNS-01):你在自己的域名下只添加一次 CNAME;我们在自己的域名下管理 TXT。
  • DNS API(DNS-01):你提供 DNS 提供商的凭证;我们在你的 DNS 区域里创建/删除 TXT。
  • HTTP-01:由 cert-ctrl agent 在 http://<domain>/.well-known/acme-challenge/<token> 返回挑战内容。
  • TLS-ALPN-01:由 cert-ctrl agent 在 443 端口用 ALPN acme-tls/1 提供一次性的验证证书完成握手验证。

目前我们已经完整支持 HTTP-01TLS-ALPN-01 用于真实签发与续期。

注意:通配符证书(*.example.com)必须使用 DNS-01(CNAME 或 DNS API)。HTTP-01 和 TLS-ALPN-01 无法验证通配符。


1)CNAME 委托(DNS-01)——推荐

你需要做什么

只需添加 一条 CNAME 记录(一次性设置):

名称:   _acme-challenge.example.com
类型: CNAME
目标: <public-id>.acme.cjj365.cc

public-id 会在你添加证书后由 cert-ctrl UI 展示。

cert-ctrl 会做什么

  • CA 下发 DNS-01 的挑战 token。
  • cert-ctrl 在我们自己的 DNS 区域创建临时 TXT
    • <public-id>.acme.cjj365.cc TXT <challenge-token>
  • CA 查询 _acme-challenge.example.com,跟随 CNAME 到 <public-id>.acme.cjj365.cc 并读取 TXT。
  • 验证完成后 cert-ctrl 删除 TXT;你的 CNAME 保留用于后续续期(长期不变)。

为什么推荐

  • 适用于任何 DNS 提供商(只要支持 CNAME)。
  • 无需用户提供 DNS API 密钥。
  • 易于撤销:删除 CNAME 即可。

完整细节请看: DNS-01 挑战:CNAME 委托机制说明


2)DNS API(DNS-01)——在你的 DNS 区域直接写 TXT

何时使用

在以下情况下可以使用 DNS API 模式:

  • 你的 DNS 环境不方便做 CNAME 委托,或
  • 你希望 cert-ctrl 直接在你的 DNS 区域管理 TXT 记录。

需要配置什么

你需要提供:

  • dns_provider_id(例如:cloudflarealitencent_dnspod
  • 提供商 secret(token/key),并在部分提供商下还需要额外变量(例如 zone id)

支持的提供商列表由服务端的 DNS Provider Catalog 决定。

在 cert-ctrl 中如何工作

  • cert-ctrl 调用 DNS 提供商 API 创建 TXT:
    • _acme-challenge.<domain> TXT <challenge-token>
  • CA 查询该 TXT 记录并验证。
  • 验证完成后 cert-ctrl 删除 TXT。

安全建议

  • 使用最小权限的 DNS token(仅限必要区域的 DNS 记录操作)。
  • DNS API 凭证相当于对域名的高权限访问,请妥善保管。

3)HTTP-01 —— agent 提供 well-known 路径

何时使用

当你无法使用 DNS-01(无法做 CNAME,且不想/不能提供 DNS API)时,如果你的域名可以在公网通过 80 端口访问到 cert-ctrl agent,可使用 HTTP-01。

必须满足的条件

  • 域名的 A/AAAA(或负载均衡)能够路由到运行 cert-ctrl agent 的机器。
  • 公网 80 端口可达。
  • 不要让 CDN/反代改写响应内容(HTTP-01 要求响应体严格匹配)。

在我们的系统里如何工作

  1. cert-ctrl 生成 token 和期望响应体(keyAuthorization)。
  2. bbserver 通过隧道给指定设备下发指令:
    • 开始提供 /.well-known/acme-challenge/<token>
  3. 签发 worker 会做一次预检探测(HTTP GET,带短时间重试),确认可达且响应体完全一致。
  4. ACME CA 发起真实验证。
  5. cert-ctrl 通知 agent 停止提供该挑战。

需要配置什么

HTTP-01 验证需要:

  • challenge_device_id:由哪个设备/agent 提供挑战
  • challenge_listen:agent 监听地址(必须包含 bindport

如果 agent 监听的不是 80 端口,你需要在网络侧做 80 → agent_port 端口转发。


4)TLS-ALPN-01 —— agent 在 443 提供 ALPN acme-tls/1

何时使用

当 80 端口受限但 443 可用时,可考虑 TLS-ALPN-01:

  • 80 被封/不可达,但
  • 可以把公网 443 暴露给 cert-ctrl agent。

必须满足的条件

  • 域名能路由到 agent 的 443(或通过转发 443 → agent_port)。
  • 连接必须是“TLS 透传”(部分 CDN/反代会终止 TLS,从而导致 ALPN acme-tls/1 无法生效)。

在我们的系统里如何工作

  1. cert-ctrl 生成一次性验证证书(SAN 匹配域名,并用于 ALPN acme-tls/1)。
  2. bbserver 将该证书/私钥下发给指定设备。
  3. agent 临时在指定监听上提供 TLS 服务。
  4. 签发 worker 做一次预检探测(带短时间重试):连接域名、完成 TLS 握手、检查协商出的 ALPN 为 acme-tls/1,并校验返回证书中的 acmeIdentifier
  5. ACME CA 在 443 发起真实验证。
  6. cert-ctrl 通知 agent 停止该临时监听。

需要配置什么

TLS-ALPN-01 验证需要:

  • challenge_device_id
  • challenge_listen(必须包含 port;建议同时包含 bind

如何选择

方法适用场景需要 DNS API 密钥?需要 agent + 开放端口?
CNAME(DNS-01)大多数域名,运维最简单
DNS API(DNS-01)希望直接在自己 DNS 区域写 TXT
HTTP-01无 DNS 控制能力,但 80 端口可达是(80)
TLS-ALPN-0180 不可用但 443 可达是(443)

快速排查

  • CNAMEdig CNAME _acme-challenge.example.com 应返回 <public-id>.acme.cjj365.cc
  • DNS API:检查 token 权限/zone 参数;等待 DNS 生效时间。
  • HTTP-01curl http://example.com/.well-known/acme-challenge/<token> 必须返回完全一致的内容(不要重定向,不要返回 HTML)。
  • TLS-ALPN-01:确认 443 为 TCP/TLS 透传到 agent;终止 TLS 的代理可能导致 ALPN acme-tls/1 失败。