用 DNS-01 CNAME 委托为内网域名签发 Let's Encrypt 通配符证书

内网域名无法做 HTTP-01 验证时,可以把 _acme-challenge 记录 CNAME 到专用验证域完成 DNS-01 签发。本文给出前置条件、委托配置、签发与自动续期步骤,以及如何验证证书链和续期是否生效。

本文目录
用 DNS-01 CNAME 委托为内网域名签发 Let's Encrypt 通配符证书

适用场景

内网服务的域名不对外开放 80/443 端口,HTTP-01 和 TLS-ALPN-01 都走不通,只剩 DNS-01 一条路。问题是你通常不想把整个主域的 DNS API 凭证交给每台需要证书的机器——凭证权限太大,泄露风险高。

解决办法是 CNAME 委托:在主域里为 _acme-challenge.example.com 建一条 CNAME,指向一个专门用于验证的子域(比如 _acme-challenge.example.com.acme-dns.example.net),ACME 客户端只需要对这个验证子域有写权限。Let's Encrypt 验证时会沿着 CNAME 找到目标 TXT 记录,主域的 DNS 凭证完全不参与签发。

前置条件

  • 一个你能控制 DNS 的域名,且其 DNS 服务商支持 API 动态更新 TXT 记录,或你有一台可自行搭建 acme-dns 服务的主机。
  • 签发机器能访问 Let's Encrypt 的 ACME 接口(https://acme-v02.api.letsencrypt.org/directory)。
  • 通配符证书(*.example.com)只能通过 DNS-01 签发,这是 CA 侧的限制,不是客户端的限制。

步骤一:配置 CNAME 委托

在主域的 DNS 控制台添加:

_acme-challenge.example.com.  CNAME  example-com.acme-dns.example.net.

如果还要签发 *.example.com,注意通配符和裸域共用同一个 _acme-challenge.example.com 名称,但两次验证需要同时存在两个不同值的 TXT 记录——验证子域必须支持同名多条 TXT。acme-dns 和大多数 DNS 服务商都支持,自建 BIND 也没问题,但要确认你的更新脚本不是"覆盖"而是"追加再清理"。

用 dig 确认委托生效:

dig CNAME _acme-challenge.example.com +short

步骤二:执行 DNS-01 签发

用 DNS-01 CNAME 委托为内网域名签发 Let's Encrypt 通配符证书 illustration 1
用 DNS-01 CNAME 委托为内网域名签发 Let's Encrypt 通配符证书 illustration 1查看原图

以委托方式签发时,ACME 客户端操作的是 CNAME 目标域的 TXT 记录。不同客户端的配置方式不同,核心参数是一致的:指定 DNS 插件或 hook、验证域的 API 凭证、要签发的域名列表。以泛化流程描述:

  1. 客户端向 ACME 服务器下单,拿到 DNS-01 challenge 的 token。
  2. 客户端通过验证子域的 API 写入 TXT 记录,等待 DNS 传播。
  3. 通知 ACME 服务器开始验证,验证通过后下载证书。

传播等待时间不要乱猜。先查验证子域 NS 的 TTL 和实际解析情况,用 dig TXT <目标记录> @<权威NS> 确认记录已出现在权威服务器上,再触发验证,否则容易触发 Let's Encrypt 的失败速率限制。

步骤三:部署与续期

证书签发后部署到目标服务(Nginx、CDN、负载均衡等),并配置自动续期。DNS-01 续期和首次签发走完全一样的流程,所以续期脚本必须保留同样的凭证和 hook,不能只在首次手工执行一次就完事。

在 CertbotX 中实践

这类委托流程在 CertbotX 里可以直接配置:把主域的 _acme-challenge CNAME 委托交给 CertbotX 管理的验证域后,由它完成 ACME 自动签发和到期前重新签发,签好的证书可自动部署到 Agent、EdgeOne 或其他 CDN 目标,每次签发和部署都会留下部署记录,方便排查"证书到底换没换上去"这类问题。

验证

签发完成后做三件事:

  1. 查证书内容:openssl x509 -in fullchain.pem -noout -text,确认 SAN 里包含 *.example.com 和 example.com,有效期是新的。
  2. 从外部探测握手:openssl s_client -connect your-host:443 -servername your-host,看返回的证书链是否完整、是否就是刚签的那张。内网服务可以在同网段的机器上执行。
  3. 演习一次续期:多数 ACME 客户端支持 dry-run,确认续期路径(包括 DNS hook)能跑通,而不是等 60 天后由监控告警告诉你续期挂了。

如果 dry-run 失败,先查 CNAME 是否还在、验证子域的 API 凭证是否过期,这两处是委托方案最常见的断点。

参考

← 返回资讯中心