域名不能开 80 端口时,DNS-01 和 HTTP-01 到底怎么选
很多团队纠结证书验证方式,其实答案取决于场景:要通配符证书、80 端口被封、或源站藏在 CDN 后面时,HTTP-01 往往走不通。本文按实际部署条件对比 DNS-01 与 HTTP-01 的取舍,并说明自动化续期时的关键差异。
本文目录

线上有个常见误会:证书签发失败,就先怀疑 CA 或者 ACME 客户端有问题。排查一圈才发现,是验证方式选错了——HTTP-01 根本到不了源站,或者要签的是通配符证书却一直在用 HTTP 验证。
这两种验证方式没有绝对的优劣,只有和你的部署环境合不合。
HTTP-01:简单,但有硬前提
HTTP-01 要求 CA 通过 80 端口访问 /.well-known/acme-challenge/ 下的一个临时文件。听起来直接,但前提条件列出来就不简单了:
- 80 端口必须对公网可达。很多内网服务、只开 443 的机器、被安全组封掉 80 的实例,直接出局。
- 请求必须真的落到你的 ACME 客户端所在的机器上。前面挂了 CDN、WAF、负载均衡,而 challenge 路径没被正确放行或回源,验证就会失败。
- 不能签通配符证书。这是协议层面的限制,不是配置问题。RFC 8555 规定通配符标识只能用 DNS-01 验证。
如果你的场景是单台公网服务器、几个固定域名、80 端口畅通,HTTP-01 依然是最省事的选择:不需要碰 DNS 的 API,不引入新的凭据。
DNS-01:多走一步,换来通配符和可达性自由
DNS-01 要求在 _acme-challenge.example.com 下放一条 TXT 记录。CA 查 DNS 拿到值就放行。它解决的是 HTTP-01 的死穴:
- 通配符证书(
*.example.com)的唯一合法路径。 - 服务器不需要公网可达,80 端口可以不存在。证书可以先在跳板机上签好,再分发到内网节点。
- CDN 后面、多节点负载均衡后面都不影响,因为 CA 根本不访问你的服务器。

代价是自动化依赖 DNS API。每次续期都要写 TXT 记录,这意味着你的 ACME 客户端要持有 DNS 凭据。这里有个实用的收敛手段:CNAME 委托。把 _acme-challenge.example.com 用 CNAME 指向一个专门用于验证的子域(比如放在另一个 DNS 区域里),客户端只需要那个区域的 API 权限,主域的 DNS 凭据不用交出。凭据爆炸半径小了很多,安全评审也好过。
另一个小坑是 DNS 传播延迟。TXT 记录写进去到所有权威服务器可见需要时间,客户端如果查得太急会失败重试。这不是 bug,是 DNS 的本性。
在 CertbotX 中实践
DNS-01 的 CNAME 委托在 CertbotX 里是已确认支持的工作方式:把 _acme-challenge 委托到独立的验证域后,CertbotX 用该域的凭据自动完成 ACME 签发,并在到期前自动重新签发,不需要人工盯着日历。签下来的证书可以自动部署到 Agent、EdgeOne 或其他 CDN 节点,每次部署都有记录可查,出问题能回溯是哪次更新引入了变更。这对于"证书要同时出现在源站和多个 CDN 边缘"的场景尤其顺手——HTTP-01 在这种拓扑里基本没戏,而 DNS-01 签一次、推多处的流程正好对上。
怎么选
判断逻辑其实很短:
- 要通配符证书?DNS-01,没有第二个选项。
- 服务器 80 端口不可达、在内网、或前面有不可控的中间层?DNS-01。
- 单台公网服务器、域名固定、不想把 DNS 凭据交给任何自动化系统?HTTP-01 够用,别过度设计。
两者也可以混用:不同域名、不同机器各走各的验证方式,ACME 协议本身不限制你。真正要避免的是一开始选了 HTTP-01,后来加了通配符需求或上了 CDN,再回头迁移——那时候往往是在续期失败告警响起的凌晨。