证书签发和续期
CAA record prevents issuance:在 DNS 里允许你的 CA
urn:ietf:params:acme:error:caa: CAA record for example.com prevents issuance这个报错的意思是:CA 检查了你域名的 DNS CAA 记录,发现名单里没有自己,按规定不能签发。 你或者 DNS 服务商发布的 CAA 记录只允许其他 CA,把你正在用的 CA 的标识加进去即可。
快速修复
修法是在生效的 CAA 记录里加上你的 CA 的标识。先查出 CA 实际看到的 CAA 记录,从具体域名开始逐级往上:
dig +short CAA www.example.com
dig +short CAA example.com
第一个返回记录的域名,就是生效的那一级。在那一级加上你的 CA,已有的、仍需要的条目保留:
example.com. 3600 IN CAA 0 issue "letsencrypt.org"
example.com. 3600 IN CAA 0 issuewild "letsencrypt.org"
example.com. 3600 IN CAA 0 iodef "mailto:security@example.com"
等旧记录的 TTL 过期后重试(先用 --dry-run 或 staging)。CAA 检测工具能显示实际生效的记录,CAA 记录生成器可以帮你生成。
原因
最常见的原因是 CAA 里只写了别的 CA,其次是通配符被 issuewild 挡住和从父域名继承的记录。
1. CAA 里写的是别的 CA
从商业证书换到 Let's Encrypt(或者反过来),旧的 CAA 记录只允许原来的 CA。
- 确认:
dig CAA example.com的issue值里没有你当前 CA 的标识。 - 修复: 为新 CA 增加一条
issue记录。常见标识:Let's Encryptletsencrypt.org、Google Trust Servicespki.goog、DigiCertdigicert.com、Sectigosectigo.com。其他 CA 以其官方文档为准。在阿里云、腾讯云买的证书,实际签发者是背后的 CA(如 DigiCert、GeoTrust 品牌由 DigiCert 签发),要写那个 CA 的标识。
2. 通配符被 issuewild 挡住
只要存在 issuewild 记录,通配符证书就只看它。常见写法 issuewild ";" 表示禁止所有 CA 签发通配符。
- 确认: 你申请的是
*.example.com,记录里有不包含你 CA 的issuewild。 - 修复: 加一条
0 issuewild "letsencrypt.org"(或你的 CA),或删除这条限制。
3. 从父域名或 CNAME 目标继承
CAA 先查具体域名,再逐级查父域名(不含顶级域)。如果域名是 CNAME,CA 会跟随它,检查目标域名的记录。
- 确认:
dig CAA shop.example.com返回的是 CNAME 指向的 CDN 域名的记录,或者为空,而dig CAA example.com返回了限制性记录。 - 修复: 在生效的那一级加上你的 CA。CNAME 记录所在的名字上一般不能再加 CAA,所以通常改父域名。
4. accounturi 或 validationmethods 不匹配
- 确认: 记录里有
accounturi=或validationmethods=。 - 修复: 确认账户 URI 和客户端实际使用的账户一致,所用的验证方式(
http-01、dns-01、tls-alpn-01)在列表里。
5. CAA 查询本身失败
权威 DNS 对 CAA 查询返回 SERVFAIL 或超时,CA 无法检查,也就不会签发。这时报错里会提到 SERVFAIL 或 DNS problem,而不是 prevents issuance。
- 修复: 用
dig CAA example.com @权威服务器测试;修复错误的 DNSSEC 配置,或者更换不能正确处理 CAA 类型的 DNS 服务。
各环境修法
各家 DNS 控制台的写法相同:记录类型选 CAA,记录值写 0 issue "CA 标识",已有的条目保留。
DNSPod / 阿里云解析 / 华为云解析: 添加记录时类型选 CAA,主机记录填 @(或子域名),记录值填 0 issue "letsencrypt.org"。有的控制台把 flag、tag、value 分成三栏填写。
Cloudflare、Route 53 等国外 DNS: 都支持 CAA。部分服务商会在替你签证书时自动加 CAA 记录,添加自己的 CA 时保留这些条目。
同时使用多家 CA: 每家写一条 issue。CDN 自己签发证书的话,它的 CA 也要列上。
宝塔、1Panel 申请 Let's Encrypt: 面板报“CAA 记录不允许签发”时,按上面的方法在 DNS 里加 letsencrypt.org 即可;用 ZeroSSL 等其他 CA 时写对应 CA 的标识。
ACME 客户端重试: 改完 DNS 后,Certbot 用 certbot renew --dry-run,acme.sh 用 --staging,cert-manager 删掉失败的 CertificateRequest 让它重新发起。
不要这样做
下面 3 种做法要么去掉防误签发的保护,要么让签发继续失败。
- 不清楚来由就删光 CAA 记录。 它们可能是安全团队特意加的,用来防止误签发。
- 立刻循环重试。 TTL 过期前缓存的旧答案仍然会失败,失败的订单还会计入 Let's Encrypt 速率限制。
- 用经销商或品牌名做标识。 只有签发 CA 官方文档写明的域名才有效;从经销商买的证书,实际签发者仍是背后的 CA。
常见问题
我从没加过 CAA 记录,为什么会报这个错?
CAA 会从父域名继承。example.com 上的记录对 shop.example.com 同样有效,除非子域名有自己的一组。CNAME 也会被跟随,CNAME 指向的 CDN 或 SaaS 域名上的 CAA 记录也可能生效。另外,有些 DNS 服务商或公司其他同事可能已经加过。
直接删掉所有 CAA 记录行不行?
能解决,因为没有 CAA 时任何受信任的 CA 都可以签发,但你也失去了一道防护。把你实际使用的 CA 加进去,花的时间一样,更稳妥。
改完多久生效?
CA 在签发时实时查询 DNS,所以权威服务器返回新记录、且旧记录的 TTL 过期后就生效。重试前用 dig CAA example.com @权威服务器 确认。DNSPod、阿里云解析修改后一般很快同步到权威服务器,主要等的是 TTL。
能限制只有我自己的 ACME 账户能签吗?
可以。Let's Encrypt 支持 accounturi 和 validationmethods 参数,例如 0 issue "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456",之后只有这个账户能签发证书。