用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发

内网或防火墙后的域名无法走 HTTP-01 验证时,可以把 _acme-challenge 记录 CNAME 委托到一个可自动管理的 DNS 区域,用 DNS-01 完成签发。本文给出前置条件、具体配置步骤和签发前后的验证方法。

本文目录
用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发

有台服务器藏在 NAT 后面,80 端口根本不通公网,证书申请卡了好几天——这是很多人第一次碰上 DNS-01 的场景。HTTP-01 要求 Let's Encrypt 能从公网访问你的服务器放验证文件,内网机器、CDN 回源端口被占、或者想签泛域名证书,这三类情况都走不通。DNS-01 的思路是:不去碰你的 Web 服务,而是让你在 DNS 里放一条 TXT 记录证明域名控制权。

问题又来了:主域名的 DNS 可能在一家没有 API 的注册商那里,或者你根本不想给 ACME 客户端主域名的修改权限。解决办法是 CNAME 委托——把验证用的子记录指到一个可以自动化管理的区域里。下面按前置条件、配置、签发、验证的顺序走一遍。

前置条件

用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:DNS ownership verification using a delegated CNAME, shown as a precise handoff between two controlled zones
用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:DNS ownership verification using a delegated CNAME, shown as a precise handoff between two controlled zones查看原图

先确认这几件事,缺一个都走不下去:

  • 你能在主域名的 DNS 控制台添加 CNAME 记录。只需要加一条,之后不用再动。
  • 有一个专门用于验证的 DNS 区域(比如 acme-dns.example.com 这种子域),它的 DNS 服务商提供 API,或者有对应的 ACME 客户端插件。
  • 如果签的是泛域名证书(*.example.com),注意 DNS-01 是唯一可行的验证方式,HTTP-01 不支持通配符。
  • ACME 客户端能访问 DNS API 的凭据(API token),权限只给那个验证用子域就够,别图省事给整个主域。

一个小坑:CNAME 委托的验证区域不要复用有别的业务的域名。TXT 记录会频繁更新,独立子域出问题时不至于波及生产解析。

第一步:在主域名加一条 CNAME

用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:an ACME request being validated at separate stations and turned into a new deployable artifact while private key material remains at its origin
用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:an ACME request being validated at separate stations and turned into a new deployable artifact while private key material remains at its origin查看原图

假设要给 app.internal.example.com 签证书,在主域名 DNS 里加:

_acme-challenge.app.internal.example.com.  CNAME  app.internal.example.com.acme-dns.example.org.

要点有三个:

  • 记录名是 _acme-challenge. 加上你要签的域名,不是域名本身。泛域名也一样,_acme-challenge.example.com 对应 *.example.com。
  • CNAME 的目标就是验证区域里对应的那条记录。ACME 协议会跟随 CNAME 找到最终的 TXT,这在 RFC 8555 的 DNS-01 章节里是明确允许的。
  • 加完后先验证解析生效:dig CNAME _acme-challenge.app.internal.example.com,能返回目标再继续。DNS 传播没完成就急着签发,只会收获一条失败记录。
用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:a new certificate version moving from its source to several edge appliances while the previous working version remains ready for rollback
用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:a new certificate version moving from its source to several edge appliances while the previous working version remains ready for rollback查看原图

第二步:配置 ACME 客户端走 DNS-01

客户端需要两样东西:知道验证记录该写到哪,以及有权限写。具体配置取决于你选的客户端和 DNS 插件,但逻辑都一样:签发时客户端把验证 token 写成 TXT 记录到 CNAME 指向的目标,等 ACME 服务端查完再清理(或不清理,留着无害,但看着乱)。

手动模式也能跑:客户端提示你 TXT 的内容,你自己去加,确认后告诉客户端继续。手动模式适合一次性签发验证流程,但 90 天的证书周期意味着三个月后你得再干一遍——自动化几乎是刚需,不是锦上添花。

用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:an approaching certificate expiry being detected early, followed by a fresh request and a safe replacement before the live connection is interrupted
用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:an approaching certificate expiry being detected early, followed by a fresh request and a safe replacement before the live connection is interrupted查看原图

在 CertbotX 中实践

这套流程在 CertbotX 里就是日常操作:它原生支持 DNS-01 的 CNAME 委托,你只要在主域名加好那条 CNAME,把验证区域的解析权限交给 CertbotX,后续的 ACME 自动签发和到期前重新签发都由它接管,不用自己写定时任务。签发成功后,证书可以自动部署到 Agent、EdgeOne 或其他 CDN,每次部署都有记录可审计——排查"证书换了但某节点还在用旧的"这类问题时,部署记录比猜靠谱。

第三步:签发后的验证

别只看客户端输出"success"就收工,做三件事确认:

用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:a browser-side endpoint independently inspecting the live TLS connection after deployment and comparing the observed endpoint artifact
用 DNS-01 CNAME 委托给内网域名签发证书:从挖坑到验证签发:a browser-side endpoint independently inspecting the live TLS connection after deployment and comparing the observed endpoint artifact查看原图
  1. 看证书本身:openssl s_client -connect app.internal.example.com:443 -servername app.internal.example.com,检查证书链、SAN 列表里有没有你的域名、有效期是否符合预期。
  2. 如果签的是泛域名,确认 SAN 里确实是 *.example.com 而不是某个具体子域,这个填错客户端也会"成功"签发,只是签了个不是你想要的东西。
  3. 跑一次续期演练(大多数客户端支持 dry-run),确认自动化链路在续期时也能走通。签发成功但续期失败,等于给自己埋了个 90 天后响的闹钟。

最后检查主域名那条 CNAME 别被清理工单顺手删了——它看起来常年没用,但每次续期都靠它。

参考文档

← 返回资讯中心