HTTPS 证书的域名验证方式:HTTP 验证与 DNS 验证

签发证书前必须证明你拥有域名,本文讲清 HTTP 验证与 DNS 验证的区别、certbot 用法与自动续期要点。

申请一张 HTTPS 证书时,证书颁发机构(CA)不会凭你一句话就签发,它必须先确认「这个域名确实归你控制」。这个确认过程叫域名所有权验证(Domain Control Validation),目前主流有两种方式:HTTP 验证和 DNS 验证。理解它们的差异,能帮你在不同场景下选对方法、少走弯路。

HTTP 验证:在网站里放一个文件

HTTP 验证的原理很直接:CA 给你一段随机字符串,你把它放到网站的指定路径下(通常是 http://你的域名/.well-known/acme-challenge/<token>),CA 通过 80 端口访问这个 URL,能读到正确内容就算通过。

  • 适用场景:域名已经解析到你的服务器、且 80 端口可从公网访问的在线站点。
  • 前提要求:DNS 已生效、防火墙放行 80 端口、没有其他程序抢占该端口。
  • 局限:站点还没上线、或服务器不对公网开放时无法使用;不能签发通配符证书。

用 certbot 签发(以 Nginx 为例,--webroot 方式):

sudo certbot certonly --webroot \
  -w /var/www/html \
  -d example.com -d www.example.com

其中 -w 指向网站根目录,certbot 会把校验文件写进 .well-known/acme-challenge/。

DNS 验证:加一条 TXT 记录

DNS 验证不碰你的网站,而是让你在域名的 DNS 里添加一条指定的 TXT 记录(名称形如 acme-challenge.example.com),CA 查询这条记录、内容匹配即通过。

  • 适用场景:站点还没上线、服务器不对外开放、或需要通配符证书。
  • 优点:不依赖 80 端口和网站可访问性,内网服务也能签。
  • 注意:DNS 记录有生效延迟(受 TTL 影响),手动加记录时可能要等几分钟。

手动 DNS 验证:

sudo certbot certonly --manual \
  --preferred-challenges dns \
  -d example.com -d www.example.com

certbot 会暂停并提示你去 DNS 服务商后台添加一条 TXT 记录,添加并生效后再回车继续。

通配符证书必须用 DNS 验证

想签发 .example.com 这样的通配符证书,CA 规则强制要求使用 DNS 验证,HTTP 验证不被接受:

sudo certbot certonly --manual \
  --preferred-challenges dns \
  -d "*.example.com" -d example.com

如果你的 DNS 服务商提供 API,还可以安装对应的 certbot DNS 插件实现全自动添加 TXT 记录,免去手动操作。

自动续期的注意事项

证书有效期通常较短(如 90 天),必须自动续期,否则会过期导致站点报错。

  • certbot 安装后一般已配置好定时任务(systemd timer 或 cron),可先演练测试:
  sudo certbot renew --dry-run
  • HTTP 验证续期基本无感,只要 80 端口和 webroot 保持可用即可自动完成。
  • 手动 DNS 验证无法自动续期——因为每次都要人工加 TXT 记录。若用 DNS 方式,务必改用 DNS 插件(API 自动化),否则每 90 天就得手动跑一次。
  • 续期后记得让 Web 服务重新加载证书,可配置续期钩子:
  sudo certbot renew --deploy-hook "systemctl reload nginx"

小结

  • HTTP 验证:放文件、走 80 端口,适合已上线、可公网访问的站点,续期省心,但不支持通配符。
  • DNS 验证:加 TXT 记录,适合站点未上线、内网服务,以及唯一支持通配符 .example.com 的方式。
  • 用 DNS 方式时优先选带 API 插件的自动化方案,否则无法自动续期。
  • 无论哪种方式,都要用 certbot renew --dry-run 验证续期链路,并配好 reload 钩子。