在部署 HTTPS 时,常见做法是在网站服务器上直接运行 Certbot,并通过 HTTP 或 HTTPS 端口完成域名验证。
但在一些网络环境中,网站服务器可能无法稳定访问证书颁发机构,也可能不方便开放 80 或 443 端口。此时,可以将证书申请过程放到另一台网络条件更好的主机上,再通过 DNS TXT 记录证明域名控制权。
这种方式称为 DNS-01 验证。
本文介绍 DNS-01 的工作原理,以及为什么域名、网站服务器和证书申请主机可以相互独立。
一、证书申请实际上在验证什么
申请 HTTPS 证书时,证书颁发机构最关心的问题不是:
证书申请程序运行在哪台服务器上?
而是:
申请者是否真正控制这个域名?
只要能够证明对域名拥有控制权,证书就可以在任意一台能够连接证书颁发机构的计算机上申请。
例如,可以存在如下架构:
域名:www.example.com
网站服务器:中国某台 VPS
证书申请主机:其他国家或地区的一台服务器
DNS 服务商:独立的云解析平台
这三者不需要处于同一台机器,也不需要处于同一网络或同一国家。
二、DNS-01 验证涉及的角色
DNS-01 验证通常涉及四个角色。
1. 域名
例如:
example.com
域名本身只是一个名称,由 DNS 系统负责解析。
2. 权威 DNS 服务器
权威 DNS 保存该域名的正式解析记录,例如:
A
AAAA
CNAME
MX
TXT
DNS-01 验证使用其中的 TXT 记录。
3. Certbot 或其他 ACME 客户端
Certbot 负责:
- 向证书颁发机构提交申请;
- 接收验证任务;
- 提示需要添加的 TXT 记录;
- 请求证书颁发机构执行验证;
- 下载签发后的证书。
4. 证书颁发机构
例如 Let’s Encrypt。
证书颁发机构负责:
- 生成验证挑战;
- 查询域名的公网 DNS;
- 判断 TXT 记录是否正确;
- 验证通过后签发证书。
三、DNS-01 的整体通信流程
完整结构如下:
查询 DNS TXT
权威 DNS 服务器 <-------------------------- 证书颁发机构
↑ ↑
│ 添加验证值 │ ACME HTTPS
│ │
域名管理平台 Certbot 申请主机
这里有两条相互独立的通信路径。
第一条路径是:
Certbot 申请主机
↓ HTTPS
证书颁发机构 ACME API
第二条路径是:
证书颁发机构
↓ DNS 查询
域名的权威 DNS 服务器
证书颁发机构不需要通过域名连接 Certbot,也不需要连接实际的网站服务器。
四、随机字符串的真正作用
证书申请过程中,Certbot 会显示类似内容:
Please deploy a DNS TXT record under the name:
_acme-challenge.example.com
with the following value:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
其中的随机字符串并不是用来建立网络连接的。
它的作用是建立一种一次性的控制权证明。
可以把它理解成证书颁发机构给出的一张临时纸条:
请把指定内容放到 example.com 的 DNS 中。
如果申请者能够把该内容添加到指定位置,说明申请者拥有该域名 DNS 的控制权限。
验证关系如下:
证书颁发机构生成随机值
↓
Certbot 获得随机值
↓
随机值被添加到域名 TXT 记录
↓
证书颁发机构查询公网 DNS
↓
查询结果与原随机值一致
↓
域名控制权验证成功
因此,更准确的说法是:
随机字符串建立的是证明关系
而不是:
随机字符串建立了域名和服务器之间的网络连接
五、为什么记录名是 _acme-challenge
DNS-01 使用一个专门的 DNS 名称:
_acme-challenge.example.com
如果需要验证子域名:
www.example.com
对应记录通常是:
_acme-challenge.www.example.com
验证另一个子域名:
blog.example.com
对应记录通常是:
_acme-challenge.blog.example.com
例如:
TXT _acme-challenge.example.com
TXT _acme-challenge.www.example.com
TXT _acme-challenge.blog.example.com
这些 TXT 记录只用于 ACME 验证,不会影响网站正常的 A、AAAA 或 CNAME 解析。
六、一个完整的验证示例
假设需要申请以下域名的证书:
example.com
www.example.com
blog.example.com
admin.example.com
Certbot 可能要求添加:
_acme-challenge.example.com
_acme-challenge.www.example.com
_acme-challenge.blog.example.com
_acme-challenge.admin.example.com
每个名称对应一个随机值:
_acme-challenge.example.com
TXT "value-a"
_acme-challenge.www.example.com
TXT "value-b"
_acme-challenge.blog.example.com
TXT "value-c"
_acme-challenge.admin.example.com
TXT "value-d"
证书颁发机构会分别查询这些记录。
只要其中任何一条缺失或错误,整张多域名证书都可能验证失败。
七、网站服务器不参与 DNS-01 验证
DNS-01 最大的特点是:实际运行网站的服务器不必参与验证。
例如:
example.com A 记录
↓
网站服务器
但验证流程仍然是:
证书申请主机
↓
证书颁发机构
↓
查询 _acme-challenge.example.com
↓
权威 DNS
网站服务器可以:
- 不开放 80 端口;
- 不开放 443 端口;
- 位于 NAT 后面;
- 位于防火墙后面;
- 无法稳定访问证书颁发机构;
- 与证书申请主机处于不同国家或网络。
这些情况都不会直接影响 DNS-01 验证。
八、证书为什么能在其他主机上申请
证书包含的主要信息是:
- 允许使用的域名;
- 公钥;
- 签发机构;
- 有效期;
- 数字签名。
证书本身并不会记录:
- 申请证书时使用的服务器 IP;
- Certbot 运行在哪台主机;
- 证书必须部署在哪台机器;
- 申请主机所在的国家或地区。
因此,可以使用如下流程:
网络条件较好的主机
↓
运行 Certbot
↓
完成 DNS-01
↓
生成证书和私钥
↓
安全复制到网站服务器
↓
Nginx 或 Apache 加载证书
这种方式在以下环境中特别有用:
- 网站服务器国际网络不稳定;
- ACME API 连接经常超时;
- 网站服务器不方便安装 Certbot;
- 需要集中管理多台服务器证书;
- 需要申请通配符证书;
- 证书申请和网站部署职责分离。
九、DNS-01 与 HTTP-01 的区别
HTTP-01
HTTP-01 要求证书颁发机构访问:
http://example.com/.well-known/acme-challenge/...
通信方向是:
证书颁发机构
↓ TCP 80
网站服务器
因此要求:
- 域名指向网站服务器;
- 公网能够访问 80 端口;
- Web 服务能够正确返回验证文件。
DNS-01
DNS-01 要求证书颁发机构查询:
_acme-challenge.example.com TXT
通信方向是:
证书颁发机构
↓ DNS 查询
权威 DNS 服务器
不需要访问网站服务器的 80 或 443 端口。
对比:
| 项目 | HTTP-01 | DNS-01 |
|---|---|---|
| 验证对象 | 网站 HTTP 服务 | 域名 DNS |
| 是否访问网站服务器 | 是 | 否 |
| 是否需要开放 80 | 是 | 否 |
| 是否支持通配符证书 | 否 | 是 |
| 是否需要修改 DNS | 否 | 是 |
| 申请主机能否与网站服务器分离 | 有限制 | 可以完全分离 |
十、申请主机必须满足什么条件
虽然证书申请主机不需要被外部访问,但它必须能够主动连接 ACME API。
通信方向是:
证书申请主机
↓ 出站 TCP 443
证书颁发机构
如果这条连接失败,可能出现:
SSL connection timeout
Read timed out
UNEXPECTED_EOF_WHILE_READING
这些错误通常与 DNS TXT 是否正确无关。
即使 TXT 记录已经完全生效,只要 Certbot 无法稳定访问 ACME API,证书仍然可能无法下载。
因此 DNS-01 同时要求:
- Certbot 申请主机能够稳定访问证书颁发机构;
- 证书颁发机构能够查询到正确的公网 TXT 记录。
十一、如何确认 TXT 已经生效
可以使用公共 DNS 服务器查询:
dig +short TXT _acme-challenge.example.com @1.1.1.1
dig +short TXT _acme-challenge.example.com @8.8.8.8
也可以查询权威 DNS:
dig +short NS example.com
然后选择一个权威服务器:
dig +short TXT _acme-challenge.example.com @权威DNS服务器
理想情况下,应当确认:
权威 DNS:正确
1.1.1.1:正确
8.8.8.8:正确
再通知 Certbot 继续验证。
十二、为什么同一个 TXT 名称可能有多个值
有些申请会要求在同一个 DNS 名称下同时存在多个 TXT 值。
例如同时申请:
example.com
*.example.com
两者都可能使用:
_acme-challenge.example.com
此时 DNS 中需要同时保留两个 TXT 值:
_acme-challenge.example.com TXT "value-1"
_acme-challenge.example.com TXT "value-2"
DNS 标准允许同一个名称存在多条 TXT 记录。
在验证完成之前,不应删除前面已经添加的 challenge。
十三、证书与私钥分别是什么
签发完成后,Certbot 通常会生成:
cert.pem
chain.pem
fullchain.pem
privkey.pem
常用的两个文件是:
fullchain.pem
privkey.pem
fullchain.pem
包含:
- 服务器证书;
- 中间证书链。
Nginx 和多数现代 Web 服务器通常直接使用它。
privkey.pem
这是证书对应的私钥。
私钥必须严格保密。如果私钥泄漏,其他人可能冒充该域名的服务器。
典型 Nginx 配置:
ssl_certificate /etc/ssl/example.com/fullchain.pem;
ssl_certificate_key /etc/ssl/example.com/privkey.pem;
十四、在其他主机申请时的私钥问题
如果证书和私钥都在申请主机上生成,那么部署时需要把二者一起复制到网站服务器。
申请主机
├── fullchain.pem
└── privkey.pem
↓
安全传输
↓
网站服务器
更严格的做法是在网站服务器上生成私钥和 CSR,只把 CSR 交给申请主机。
结构如下:
网站服务器生成私钥
↓
生成 CSR
↓
申请主机使用 CSR 申请证书
↓
证书传回网站服务器
CSR 包含公钥和域名信息,但不包含私钥。
这种方法可以确保私钥始终不离开网站服务器,但实现过程会稍复杂。
十五、手动 DNS-01 的局限
手动执行:
certbot certonly --manual --preferred-challenges dns
虽然简单,但不能直接实现无人值守续期。
每次续期通常都需要:
- 重新运行 Certbot;
- 获取新的 TXT 值;
- 修改 DNS;
- 等待解析生效;
- 提交验证;
- 部署新证书。
如果 DNS 服务商提供 API,可以使用对应的 Certbot DNS 插件,实现自动添加和删除 TXT 记录。
自动流程可以变成:
Certbot
↓ 调用 DNS API
自动添加 TXT
↓
完成验证
↓
自动删除 TXT
↓
自动更新证书
十六、常见误解
误解一:域名必须指向证书申请主机
错误。
DNS-01 只检查 TXT 记录,域名的 A 记录可以指向另一台服务器。
误解二:证书颁发机构会连接运行 Certbot 的机器
DNS-01 下不会。
Certbot 主动连接证书颁发机构,证书颁发机构只查询 DNS。
误解三:随机字符串建立了网络连接
错误。
随机字符串只是一种一次性的域名控制权证明。
误解四:TXT 正确就一定能成功
不一定。
Certbot 到 ACME API 的 HTTPS 连接也必须稳定。
误解五:证书只能安装在申请它的机器上
错误。
只要证书和私钥匹配,就可以部署到目标服务器。
十七、简化后的核心原理
DNS-01 可以归纳成下面几句话:
证书申请主机向证书颁发机构提出申请。
证书颁发机构生成一次性随机验证值。
随机值被放入域名的 _acme-challenge TXT 记录。
证书颁发机构从公网查询该 TXT 记录。
查询结果一致,说明申请者控制该域名的 DNS。
验证通过后,证书颁发机构签发证书。
其中最重要的一点是:
域名与证书申请主机之间不需要直接通信。
真正建立联系的是证书颁发机构:
一边通过 ACME 与 Certbot 通信,
另一边通过 DNS 查询验证域名。
随机字符串只是连接这两部分流程的“一次性证明凭据”。
总结
DNS-01 将“证书申请主机”和“网站服务器”解耦。
最终结构可以是:
域名解析 → 网站服务器
DNS TXT 验证 → 权威 DNS
证书申请 → 独立申请主机
证书部署 → 网站服务器
这种设计使证书可以在网络环境更稳定的主机上申请,再安全部署到实际提供网站服务的服务器。
其核心不是让域名与 Certbot 建立连接,而是通过一次性随机 TXT 值,让证书颁发机构确认:
证书申请者拥有该域名的 DNS 控制权。