泛域名证书该用 DNS-01 还是 HTTP-01?从一次藏在 CDN 后面的验证失败说起

HTTP-01 和 DNS-01 都能完成 ACME 域名验证,但在泛域名证书、CDN 前置和多机部署场景下取舍完全不同。本文结合常见故障现场,说明两种验证方式的边界、小坑和选择依据。

本文目录
泛域名证书该用 DNS-01 还是 HTTP-01?从一次藏在 CDN 后面的验证失败说起

一个典型的卡住现场

运维群里隔三差五会出现这样的提问:证书签发一直失败,报错 unauthorized 或 connection,可站点明明访问正常。一查,域名前面挂着 CDN,回源还要过一层 WAF。HTTP-01 的挑战文件路径 .well-known/acme-challenge/ 被边缘节点缓存策略或者 WAF 规则拦了,Let's Encrypt 的验证请求根本到不了源站。

这不是 HTTP-01 有毛病,而是它的前提条件在这种架构下不成立了。选验证方式之前,先看自己的流量路径长什么样。

HTTP-01:简单,但要求"直达"

HTTP-01 的逻辑很直白:ACME 服务器通过 80 端口访问一个临时文件,文件内容对上了,就证明你控制这个域名。

它的好处是零依赖——不需要动 DNS,不需要 API 凭据,任何 Web 服务器都能伺候。单机、域名直接解析到本机、没有 CDN 的场景,它是最省心的选择。

边界也很清楚:

泛域名证书该用 DNS-01 还是 HTTP-01?从一次藏在 CDN 后面的验证失败说起:DNS ownership verification using a delegated CNAME, shown as a precise handoff between two controlled zones
泛域名证书该用 DNS-01 还是 HTTP-01?从一次藏在 CDN 后面的验证失败说起:DNS ownership verification using a delegated CNAME, shown as a precise handoff between two controlled zones查看原图
  • 签不了泛域名证书。*.example.com 必须走 DNS-01,这是 CA/B 规则层面定死的,没有商量余地。
  • 80 端口必须能从公网直达。前面有 CDN、WAF、端口被运营商封、或者服务在内网,都可能断在这条路上。
  • 多机部署麻烦。多台机器共用一个域名做负载均衡时,验证请求落到哪台是随机的,挑战文件得同步到所有节点,或者把挑战路径单独反代到一台机器上。能做,但都是额外工程。

还有一个容易忽视的点:80 端口暴露本身。有些安全策略要求关闭 80 只做 443,HTTP-01 就和这条策略打架了。

DNS-01:多一步 DNS 操作,换来几乎不挑环境

DNS-01 是在 _acme-challenge.example.com 上写一条 TXT 记录,ACME 服务器查 DNS 来验证。它不问你的 Web 服务在哪、开不开 80、前面有几层代理——只要你能改 DNS 记录就行。

适用面因此宽得多:泛域名证书、内网服务、CDN 后置、多机共用域名,全都成立。代价是自动化依赖 DNS 服务商的 API。每次续期 TXT 记录的值都会变,手动改是撑不住的(90 天有效期,续期时你大概率在忙别的事),所以 DNS-01 实际等于"必须有 API 凭据 + 自动写入"。

小坑集中在 DNS 本身:

  • 生效延迟。TXT 写入后要等权威 DNS 更新,ACME 客户端一般会自动轮询等待,但 TTL 设得太长或某些 DNS 服务商同步慢,会拖长签发时间甚至超时。
  • 凭据权限。DNS API token 往往权限偏大,落在服务器上是攻击面。建议用只允许改特定记录的细粒度 token。
  • 主域不在自己手里。比如域名 DNS 托管在没有 API 的服务商,或者跨团队申请改记录要走工单。这时可以用 CNAME 委托:把 _acme-challenge.example.com CNAME 到一个你有 API 权限的专用域,验证记录写到那边去。这是 DNS-01 里很实用的一个逃生舱,RFC 8555 的验证流程对此是兼容的。
泛域名证书该用 DNS-01 还是 HTTP-01?从一次藏在 CDN 后面的验证失败说起: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 还是 HTTP-01?从一次藏在 CDN 后面的验证失败说起:an ACME request being validated at separate stations and turned into a new deployable artifact while private key material remains at its origin查看原图

怎么选

判断逻辑其实很短:

  1. 要泛域名证书 → DNS-01,没有第二个选项。
  2. 域名直连源站、单机或少量机器、80 可通 → HTTP-01 够用,且依赖最少。
  3. 前面有 CDN/WAF、服务在内网、多机负载均衡、80 被关 → DNS-01。
  4. DNS 没有 API 可用 → 优先考虑 CNAME 委托到可自动化的 DNS 区,而不是退回手动操作。

混合场景也常见:主站域名走 DNS-01 签泛域名,几台内部机器用各自的 HTTP-01,互不冲突。验证方式是按证书选的,不是按账号选的。

在 CertbotX 中实践

CertbotX 的自动签发同时覆盖这两类场景:需要泛域名或源站不可直达时,可以用 DNS-01 加 CNAME 委托——把挑战记录委托到可自动化的 DNS 区,源站侧不用开 80、不用暴露 DNS 主域的凭据。签发完成后,证书到期前会自动重新签发,并可推送到 Agent、EdgeOne 或其他 CDN 上完成部署,每次部署有记录可查,出问题时能回溯是哪次推送、推到了哪里。对"证书在 CDN 上忘了换导致半夜告警"这类事故,部署记录加自动续期是比较实际的防线。

核验用链接

  • Let's Encrypt:Challenge Types — 官方对 HTTP-01 与 DNS-01 能力和限制的说明,包括泛域名只支持 DNS-01。
  • RFC 8555:ACME 协议 — 第 8 节定义了两种挑战的验证流程,想确认 CNAME 委托行为可看 DNS 挑战部分。
  • MDN:HSTS — 如果因为验证方式之争考虑关 80 端口,建议先确认 HSTS 部署状态,避免关出别的坑。
← 返回资讯中心