申请 HTTPS 证书的三种验证方式,什么时候该用哪一种

给域名配 HTTPS,签发机构(CA)必须先确认一件事:你真的控制这个域名。这个确认动作就是所谓的 ACME 挑战(challenge)。方式是三种,选哪一种,结果差别很大。
三种方式在验什么
| 方式 | 怎么证明 | 依赖的端口/权限 | 能否签泛域名 |
|---|---|---|---|
| HTTP-01 | CA 访问 http://域名/.well-known/acme-challenge/<token>,看到约定内容 | 80 端口从公网可达 | 否 |
| DNS-01 | 在 DNS 里加一条 _acme-challenge TXT 记录 | 域名解析的写权限 | 可以 |
| TLS-ALPN-01 | CA 在 443 端口发起 TLS 握手,SNI 用你的域名、ALPN 带 acme-tls/1,服务端回一张专用证书 | 443 端口从公网可达 | 否 |
一个容易被忽略的细节:三种方式里只有 DNS-01 需要动解析,另外两种都只是「服务端配合一下就行」。
什么时候会卡住
HTTP-01 卡在 80 端口。 常见的两种:服务器上前面的 Nginx/面板已经占了 80;或者域名指向的是服务器上的默认站点,请求被别的规则接管(比如跳转、拦截页)。CA 会跟随 302 去看最终结果,跟到最后发现内容不对,就只能判失败。
TLS-ALPN-01 卡在 443 不可达。 端口没放行、没有进程监听,都会让握手直接失败。
DNS-01 卡在要等解析生效。 记录加完到全球可见之间有几秒到几分钟的窗口,自动化脚本必须轮询确认,不能加完就立刻让 CA 去查。
怎么选
判断顺序很简单:
- 能用 443 吗?能 → 优先 TLS-ALPN-01。它不碰 80 端口,对「80 被面板占用」的机器最省事。
- 需要泛域名证书,或者 80/443 都不方便对外(内网、只做 DNS 的域名)?→ 用 DNS-01,代价是要拿到解析 API 的凭据。
- 只有 80 能对外?→ 只能 HTTP-01。
一个真实的连环坑
自动签发工具通常这样做:先用一种方式去试,失败了换一家 CA 再试。但这可能越换越糟——比如第一家 CA 走 TLS-ALPN 失败后,第二家 CA 只支持 HTTP-01,而你的 80 端口恰好是坏的,于是从「偶发失败」变成「必然失败」,日志里一串报错,看起来像证书配置写错了。
所以有两条原则:
- 认准一种可行的挑战方式,把签发机构固定住,别让工具乱降级;
- 或者反过来,把 80 和 443 两条通道都打通,让工具怎么试都能成。
我在 Caddy 那篇 里提过它把申请和续期全包了,但「自动」不等于「不用管」——端口和网络环境是自动化的前提,前提不成立,自动化只会更快地失败。
小结
三种方式的本质区别是依赖什么:80、443,还是 DNS。先确认自己能满足哪一条,再决定用哪种,比盲目重试高效得多。