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-01 与 TLS-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(例如:cloudflare、ali、tencent_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 要求响应体严格匹配)。
在我们的系统里如何工作
- cert-ctrl 生成 token 和期望响应体(
keyAuthorization)。 - bbserver 通过隧道给指定设备下发指令:
- 开始提供
/.well-known/acme-challenge/<token>
- 开始提供
- 签发 worker 会做一次预检探测(HTTP GET,带短时间重试),确认可达且响应体完全一致。
- ACME CA 发起真实验证。
- cert-ctrl 通知 agent 停止提供该挑战。
需要配置什么
HTTP-01 验证需要:
challenge_device_id:由哪个设备/agent 提供挑战challenge_listen:agent 监听地址(必须包含bind和port)
如果 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无法生效)。
在我们的系统里如何工作
- cert-ctrl 生成一次性验证证书(SAN 匹配域名,并用于 ALPN
acme-tls/1)。 - bbserver 将该证书/私钥下发给指定设备。
- agent 临时在指定监听上提供 TLS 服务。
- 签发 worker 做一次预检探测(带短时间重试):连接域名、完成 TLS 握手、检查协商出的 ALPN 为
acme-tls/1,并校验返回证书中的acmeIdentifier。 - ACME CA 在 443 发起真实验证。
- cert-ctrl 通知 agent 停止该临时监听。
需要配置什么
TLS-ALPN-01 验证需要:
challenge_device_idchallenge_listen(必须包含port;建议同时包含bind)
如何选择
| 方法 | 适用场景 | 需要 DNS API 密钥? | 需要 agent + 开放端口? |
|---|---|---|---|
| CNAME(DNS-01) | 大多数域名,运维最简单 | 否 | 否 |
| DNS API(DNS-01) | 希望直接在自己 DNS 区域写 TXT | 是 | 否 |
| HTTP-01 | 无 DNS 控制能力,但 80 端口可达 | 否 | 是(80) |
| TLS-ALPN-01 | 80 不可用但 443 可达 | 否 | 是(443) |
快速排查
- CNAME:
dig CNAME _acme-challenge.example.com应返回<public-id>.acme.cjj365.cc。 - DNS API:检查 token 权限/zone 参数;等待 DNS 生效时间。
- HTTP-01:
curl http://example.com/.well-known/acme-challenge/<token>必须返回完全一致的内容(不要重定向,不要返回 HTML)。 - TLS-ALPN-01:确认 443 为 TCP/TLS 透传到 agent;终止 TLS 的代理可能导致 ALPN
acme-tls/1失败。