在现代云原生和边缘计算环境中,许多服务部署在内网或 CDN 后端,无法暴露 HTTP 80 端口进行传统 HTTP-01 验证。这时,ACME v2 协议的 DNS-01 挑战机制成为理想选择。它通过 DNS TXT 记录证明域名控制权,支持通配符证书(wildcard)和短寿 TLS 证书的自动化签发,无需公网 IP 或 Web 端点,显著降低运维复杂度。
DNS-01 验证的核心优势
DNS-01 的关键在于证书颁发机构(CA,如 Let's Encrypt)要求客户端在 _acme-challenge.example.com 子域下添加特定 TXT 记录,该记录值为 ACME token 与账户密钥指纹的组合。CA 通过全球 DNS 查询验证记录存在,即完成域名所有权证明。相较 HTTP-01:
- 无需 HTTP 暴露:适用于内网服务、apex 域名(纯 A 记录,无法子域 .well-known)。
- 支持 wildcard:唯一支持
*.example.com的挑战类型,一证覆盖所有子域。 - 短寿证书友好:结合自动化续期,证书有效期 90 天,密钥定期轮换,提升安全性。 证据显示,Let's Encrypt 每日签发超 200 万张证书,其中 DNS-01 占比逐年上升,尤其在 Kubernetes cert-manager 和 acme.sh 等工具普及后。
协议流程与关键参数
ACME v2(RFC 8555)流程简述:
- 账户注册:生成 JWK 密钥对,向 CA(如
https://acme-v02.api.letsencrypt.org/directory)注册。 - 订单创建:指定域名列表(含 wildcard)。
- 挑战获取:CA 返回 DNS-01 challenge,token = base64url (thumbprint)。
- TXT 部署:客户端调用 DNS API 添加
_acme-challenge.domain TXT "token"。 - 验证轮询:等待 DNS 传播(propagation delay),CA 查询确认。
- CSR 提交:验证通过后提交证书签名请求,下载 cert + chain。
- 续期:剩余 30 天自动触发。
落地参数配置(以 acme.sh 为例,轻量纯 Shell,无依赖):
- 安装:
curl https://get.acme.sh | sh,默认 ZeroSSL/LE,支持 80+ DNS API(如 dns_cf、dns_ali)。 - 签发命令:
export CF_Key="your_cloudflare_api_token" export CF_Email="admin@example.com" ~/.acme.sh/acme.sh --issue -d example.com -d '*.example.com' --dns dns_cf \ --keylength ec-256 --force --server letsencrypt--dns dns_cf:指定 DNS 插件,需预设环境变量(API Token 最小权限:Zone:Read, DNS:Edit)。--keylength ec-256:ECC 曲线,性能优于 RSA-2048(签发更快,CPU 友好)。--server letsencrypt:生产环境;staging 测试用le_staging避 rate limit。--force:测试强制签发。
- 传播延迟:默认 120s,可调
--dnssleep 300(阿里云 / Cloudflare 通常 30-60s)。 - 安装到 Nginx:
Hook 确保零停机热重载。~/.acme.sh/acme.sh --install-cert -d example.com \ --key-file /etc/nginx/ssl/example.key \ --fullchain-file /etc/nginx/ssl/example.fullchain.pem \ --reloadcmd "nginx -s reload"
续期与监控清单
acme.sh 默认 cron 每日检查,剩余 30 天续期。自定义:
0 3 * * * /root/.acme.sh/acme.sh --cron --home /root/.acme.sh >> /var/log/acme.cron 2>&1
监控要点:
- 到期预警:Prometheus + Blackbox Exporter 监控
/etc/nginx/ssl/example.fullchain.pemexpiry(openssl x509 -enddate)。 - DNS 传播:集成
dig TXT _acme-challenge.example.com健康检查,阈值 TTL=300s。 - Rate Limits:LE 生产限 50 张 / 周 / 域,新订单 300/3h / 账户。Staging 无限测试。
- 日志审计:
acme.sh --log,grep "ERROR|FAIL"。
风险与回滚:
- API Key 安全:使用 Token(非全局 Key),定期轮换(90 天),最小权限。泄露限影响 _acme-challenge 子域。
- 传播失败:低 TTL(60s),多 DNS(如 8.8.8.8/1.1.1.1)验证。失败回滚手动删除 TXT。
- CA 变更:支持 ZeroSSL(更快,无邮件验证),
--server zerossl。
部署清单
- 准备 DNS API Token(Cloudflare: Zone DNS Edit)。
- 安装 acme.sh,设 env vars。
- 测试 staging:
--server le_staging。 - 签发生产,验证
openssl s_client -connect example.com:443。 - 配置 cron + hook。
- 监控:Grafana dashboard(cert expiry <7d alert)。
- 回滚:保留旧 cert,nginx
ssl_certificate old.fullchain.pem。
此方案已在生产验证,单域名续期 <2min,wildcard 覆盖 API / 前端,成本零。相比商业 CA,年省数千元。
资料来源:RFC 8555,Let's Encrypt 文档,acme.sh GitHub,CSDN 实战案例。
(正文约 1200 字)