使用 Certbot 通过 DNS-01 验证获取 SSL 证书
Certbot 是一个免费且开源的工具,用于自动申请和管理 Let’s Encrypt 证书。它支持多种验证方法,其中 DNS-01 挑战要求在域名的 DNS 中添加指定的 TXT 记录以证明对域名的控制权。DNS-01 特别适用于获取通配符证书(如 *.example.com),或在无法使用 HTTP 验证的环境中使用。
安装
certbot 是用 Python 编写的工具。如果机器上已经有 Python 环境。那么可在创建虚拟环境后,使用 pip 安装:
pip install certbot当然,也可使用 uv 等现代工具安装。
获取证书
使用 DNS-01 挑战获取证书时,需要指定 --manual 和 --preferred-challenges dns 参数。例如,获取 example.com 和 *.example.com 的证书:
certbot certonly --manual --preferred-challenges dns -d example.com -d *.example.comcerbot 程序在运行过程中会提示输入邮箱,但可以跳过。运行完毕后,会显示需要添加到 DNS 记录中的 TXT 记录内容。然后将该记录添加到域名的 DNS 配置中,等待 DNS 记录生效。生效后,按回车继续,Certbot 会验证该记录并颁发证书。
默认证书路径为 /etc/letsencrypt/live/<domain>/;在无管理员权限时,可用 --config-dir、--work-dir、--logs-dir 指定目录,例如:
certbot certonly --manual --preferred-challenges dns \ -d example.com -d *.example.com \ --config-dir ~/letsencrypt/config \ --work-dir ~/letsencrypt/work \ --logs-dir ~/letsencrypt/logs另外,certbot 支持使用插件自动管理 DNS 记录,从而简化 DNS-01 挑战的过程。
速率限制与测试
Let’s Encrypt 对证书签发设有速率限制,调试阶段很容易踩中。与本文最相关的两条是:
- 相同标识符集(exact set of identifiers):每 7 天最多签发 5 张证书。比如反复用同一组
-d example.com -d *.example.com申请,第 6 次就会被拒绝。 - 同一注册域名(registered domain):每 7 天最多签发 50 张证书。
两条都是全局限制,所有账户的申请请求都会计入,而且吊销证书并不会返还已消耗的额度。
因此调试时不要直接请求生产环境的证书,改用 Let’s Encrypt 的 staging 环境拿假证书:
certbot certonly --manual --preferred-challenges dns \ -d example.com -d *.example.com \ --test-cert--test-cert 等价于 --server https://acme-staging-v02.api.letsencrypt.org/directory,其别名是 --staging。--dry-run 也会走 staging,但它只做一次验证、不保存证书,适合在续期前做演练。staging 的额度远高于生产环境(例如相同标识符集为每周 30000 张),但它签发的证书不受信任,只能用于测试。
将证书转换成 pfx 格式
在某些情况下,可能需要将证书转换成 pfx 格式以供 Windows 或其他系统使用。比如当上传自定义证书到 Azure Application Gateway, Azure Key Vaults 时,就必须使用带密码的 pfx 格式。可以使用 OpenSSL 工具进行转换:
openssl pkcs12 -export -out ~/letsencrypt/cert.pfx \ -inkey ~/letsencrypt/live/example.com/privkey.pem \ -in ~/letsencrypt/live/example.com/fullchain.pem运行期间会提示输入导出密码。
其他工具
除了 Certbot 外,还有其他一些工具也支持通过 DNS-01 挑战获取 SSL 证书。例如:
- lego:一个用 Go 语言编写的 ACME 客户端,支持多种 DNS 提供商的 API。