Caddy Cloudflare DNS-01 质询:获取通配符 TLS 证书
为什么要用 DNS-01 而不是 HTTP-01
Let’s Encrypt 提供两种主流的证书质询方式:
| 方式 | 原理 | 适用场景 | 局限 |
|---|---|---|---|
| HTTP-01 | 在 80 端口提供指定文件 | 单域名、公网可达 | 不能签发通配符证书 |
| DNS-01 | 在 DNS TXT 记录写入质询令牌 | 通配符证书、内网服务 | 需要 DNS 服务商 API |
如果你的服务跑在内网(只有部分端口暴露),或者你需要 *.example.com 这样的通配符证书,就必须使用 DNS-01。
Caddy 默认会自动选择 HTTP-01。要让它使用 DNS-01,你需要安装 caddy-dns/cloudflare 插件(参考上一篇文章的 xcaddy 构建方法),然后在全局配置中指定 acme_dns。
配置 DNS-01
{
acme_dns cloudflare <API_TOKEN>
}就这么一行。Caddy 启动时会调用 Cloudflare API 创建 _acme-challenge.example.com 的 TXT 记录,Let’s Encrypt 验证通过后自动删除记录,全过程无需人工干预。
证书续期也是自动的——Caddy 在后台检测证书过期时间,到期前自动重复同样的流程。
Cloudflare API Token 权限配置
不要把 Account API Key(全局密钥)用在这里。正确的做法是创建一个有限权限的 API Token:
- 登录 Cloudflare Dashboard → My Profile → API Tokens
- 点击 Create Token → 选择 Edit zone DNS 模板
- 权限设置为:
- Zone → DNS → Edit
- Zone → Zone → Read
- Zone Resources 选择你的域名(如
example.com) - TTL 设为永不或按需设置
这样即使 Token 泄露,攻击者也只能修改你指定域名的 DNS 记录,做不了其他操作。
全局 Caddyfile 配置
{
acme_dns cloudflare xxx
servers {
trusted_proxies cloudflare {
interval 12h
timeout 15s
}
}
}Cloudflare 信任代理
trusted_proxies cloudflare {
interval 12h
timeout 15s
}当 Caddy 跑在 Cloudflare CDN 后面时,所有请求的真实源 IP 被 Cloudflare 的代理 IP 覆盖。Caddy 需要知道哪些 IP 是可信的代理,才能正确提取 X-Forwarded-For 头中的真实客户端 IP。
caddy-cloudflare-ip 插件(我在自定义构建中已包含)会自动获取 Cloudflare 的 IP 范围列表,并定期更新(每隔 12 小时检查一次)。如果 Cloudflare 增加了新的回源 IP,配置会自动生效,不需要手动更新。
timeout 15s 指定 IP 范围获取的超时时间。
验证证书
部署完成后,用 OpenSSL 验证:
openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -text | grep -A1 "Subject Alternative Name"应该看到类似输出:
X509v3 Subject Alternative Name:
DNS:*.example.com, DNS:example.com总结
DNS-01 配置本身只有一行 acme_dns cloudflare ...,但它依赖的几个前置条件需要注意:自定义构建包含 caddy-dns/cloudflare 插件、API Token 需要合适的权限、配合 trusted_proxies 获取真实客户端 IP。