CAA DNS 记录:证书颁发机构授权机制的原理、协议与部署实践

协议详解 · 2026-06-15

概述

证书颁发机构授权(Certification Authority Authorization,CAA)是一种 DNS 资源记录类型,允许域名所有者指定哪些证书颁发机构(CA)被允许为其域名签发证书。CAA 的核心价值在于:将证书签发的授权决策权从 CA 侧转移到域名所有者侧,为域名所有者提供了一种主动防御恶意或错误签发证书的机制。

CAA 并非孤立的安全机制,而是 Web PKI 多层防御体系中的一环:

CAA 与 CT 的关系尤其重要:CAA 是预防性的(阻止不该签发的证书),CT 是检测性的(发现已经签发的证书)。两者互补而非替代。

设计动机:CA 签发权力的制衡

问题的本质

在传统 PKI 模型中,任何公开信任的 CA 都可以为任何域名签发证书。这一设计源于 X.509 信任模型——只要 CA 的根证书被浏览器/操作系统信任,该 CA 签发的任何证书都被信任。

这意味着:

  • 如果某个 CA 被入侵(如 2011 年 DigiNotar 事件),攻击者可以为任意域名(包括 google.com)签发伪造证书
  • 如果某个 CA 操作失误(如错误验证域名所有权),可能为错误的主体签发证书
  • 如果 CA 的 subordinate CA 被滥用,影响范围可能波及数百万域名
核心矛盾:域名所有者对自己的域名拥有最终控制权,但在传统 PKI 模型中,他们无法阻止 CA 为自己的域名签发证书。

CAA 的解决方案

CAA 的核心思想极其简洁:域名所有者通过 DNS 记录声明"只有这些 CA 可以为我的域名签发证书",CA 在签发前必须检查并遵守这一声明。

CODE
域名所有者的 DNS 区域文件:

example.com.  IN  CAA  0  issue  "letsencrypt.org"
example.com.  IN  CAA  0  issue  "digicert.com"
example.com.  IN  CAA  0  issuewild  "letsencrypt.com"
example.com.  IN  CAA  0  iodef  "mailto:security@example.com"

上述记录的含义:

  • 只允许 Let's Encrypt 和 DigiCert 为 example.com 及其子域名签发非通配符证书
  • 只允许 Let's Encrypt 签发通配符证书
  • 如果 CA 发现违反 CAA 记录的签发请求,通过邮件通知 security@example.com

协议规范:从 RFC 8659 到 RFC 8657

演进历程

CAA 标准经历了三个主要阶段:

阶段标准发布时间核心贡献
初始标准化RFC 68442013 年 1 月定义 CAA 记录的基本格式和语义属性
核心修订RFC 86592019 年 5月全面修订,修复已知问题,明确处理规则
扩展增强RFC 86572019 年 11 月新增 accounturi 和 validationmethods 参数
RFC 8659 是 CAA 的核心标准,RFC 8657 是其扩展。两者共同构成了当前 CAA 协议的完整规范。

CAA 记录的 Wire 格式

CAA DNS 记录的 Wire 格式由三个字段组成:

CODE
0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
├─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┼─┤
│                      Flags                        │
├─────────────────────────────────────────────────────┤
│                    Tag Length                      │
├─────────────────────────────────────────────────────┤
│                      Tag                           │
├─────────────────────────────────────────────────────┤
│                     Value                           │
│                      ...                           │
└─────────────────────────────────────────────────────┘

Flags(标志位):1 字节,目前仅定义了第 7 位(Critical Flag):

CODE
Bit 7 (Critical Flag):
  1 = 关键标志:CA 不理解该属性时必须拒绝签发
  0 = 非关键标志:CA 不理解该属性时可忽略

Tag(标签):标识属性类型的 ASCII 字符串,如 issueissuewildiodef

Value(值):属性的具体值,格式取决于属性类型。

三类核心属性

#### 1. issue:指定授权的 CA

issue 属性是最常用的 CAA 属性,指定允许为域名签发证书的 CA。

CODE
语法:
  issue <CA-domain-name>

示例:
  example.com.  IN  CAA  0  issue  "letsencrypt.org"

处理规则

  • CA 的域名必须与 issue 值匹配(精确匹配,不支持通配符)
  • 如果 issue 值为空字符串(issue ""),表示禁止任何 CA 为该域名签发证书
  • 多个 issue 记录表示"任一匹配即可"
CODE
# 禁止任何 CA 为 example.com 签发证书
example.com.  IN  CAA  0  issue  ""

# 允许 Let's Encrypt 或 DigiCert 签发
example.com.  IN  CAA  0  issue  "letsencrypt.org"
example.com.  IN  CAA  0  issue  "digicert.com"

#### 2. issuewild:通配符证书控制

issuewild 属性专门控制通配符证书(*.example.com)的签发授权。

CODE
语法:
  issuewild <CA-domain-name>

关键规则issuewild 的优先级高于 issue。当 CA 签发通配符证书时,只检查 issuewild 记录,忽略 issue 记录。

CODE
# 允许 Let's Encrypt 签发所有证书(包括通配符)
example.com.  IN  CAA  0  issue  "letsencrypt.org"
example.com.  IN  CAA  0  issuewild  "letsencrypt.org"

# 允许 DigiCert 签发非通配证书,但禁止其签发通配符证书
example.com.  IN  CAA  0  issue  "digicert.com"
# 注意:没有 issuewild 指向 digicert.com

这一分离设计的意义在于:通配符证书的安全影响范围远大于单域名证书(一个 *.example.com 证书可用于所有子域名),因此需要更严格的控制。

#### 3. iodef:违规通知

iodef 属性指定当 CA 检测到违反 CAA 记录的证书请求时,应如何通知域名所有者。

CODE
语法:
  iodef <mailto-uri>
  iodef <https-uri>

示例:
  example.com.  IN  CAA  0  iodef  "mailto:security@example.com"
  example.com.  IN  CAA  0  iodef  "https://example.com/caa-report"

iodef 使用 Incident Object Description Exchange Format(IODEF,RFC 7970)标准,支持邮件和 HTTP 两种通知方式。

实际效果:虽然 iodef 在理论上提供了实时通知能力,但在实践中,大多数 CA 并不自动发送 iodef 通知。CA/B 论坛的基线要求也未强制要求 CA 实现 iodef 通知。因此,iodef 更多是作为策略声明存在,而非可靠的检测机制。

RFC 8657 扩展参数

RFC 8657 为 CAA 引入了两个关键扩展参数,大幅增强了 CAA 的表达能力。

#### accounturi:CA 账户绑定

accounturi 参数允许域名所有者将签发权限限制到特定 CA 的特定账户。

CODE
语法:
  issue <CA-domain-name>;<parameter-name>=<parameter-value>

示例:
  example.com.  IN  CAA  0  issue  "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456"

安全语义

  • 只有 Let's Encrypt 的账户 123456 可以为 example.com 签发证书
  • 即使攻击者获得了 Let's Encrypt 的其他账户,也无法为 example.com 签发证书
  • 这大幅缩小了攻击面——从"任何 Let's Encrypt 账户"缩小到"特定账户"
accounturi 的核心价值在于防止 CA 内部的横向移动攻击。如果 CA 的某个账户被入侵,accounturi 可以限制该账户只能为特定域名签发证书。

#### validationmethods:验证方法绑定

validationmethods 参数允许域名所有者限制 CA 在验证域名所有权时使用的方法。

CODE
语法:
  issue <CA-domain-name>; validationmethods=<method1>,<method2>

示例:
  example.com.  IN  CAA  0  issue  "letsencrypt.org; validationmethods=dns-01,http-01"

安全语义

  • 只允许 Let's Encrypt 使用 DNS-01 或 HTTP-01 验证方法
  • 不允许使用 TLS-ALPN-01 等其他方法
  • 这可以防止攻击者利用验证方法的弱点(如 TLS-ALPN-01 的共享证书问题)

CAA 属性优先级与冲突处理

当 CAA 记录中存在多个属性时,处理规则如下:

CA/B 论坛基线要求中的 CAA

强制检查要求

CA/B 论坛(CA/Browser Forum)的基线要求(Baseline Requirements,BR)是公开信任 CA 必须遵守的行业规范。自 BR 1.6.0 版本起,CAA 检查已成为强制要求。

核心要求

CODE
┌──────────────────────────────────────────────────────────────┐
│  CA/B BR §3.2.2.8 — CAA 检查要求                             │
│                                                              │
│  1. CA 在签发证书前,必须查询 DNS 中的 CAA 记录              │
│  2. 如果存在 CAA 记录,CA 必须检查是否被授权                 │
│  3. 如果未被授权,CA 必须拒绝签发                            │
│  4. CA 必须在证书签发日志中记录 CAA 检查结果                 │
│  5. CAA 检查必须在证书签发的 8 小时内完成                    │
│  6. CA 必须处理 issue、issuewild、iodef 属性                 │
│  7. CA 必须处理 RFC 8657 的 accounturi 和 validationmethods │
│     (自 SC-098v2 生效,2027 年 3 月 15 日起强制)           │
└──────────────────────────────────────────────────────────────┘

SC-098v2:RFC 8657 参数成为强制要求

2026 年 5 月 13 日,CA/B 论坛通过了 SC-098v2 投票,规定自 2027 年 3 月 15 日起,所有公开信任的 CA 必须处理 RFC 8657 定义的 accounturivalidationmethods 参数。

这一要求的背景是:

  • ACME 协议的广泛采用:Let's Encrypt 等 CA 使用 ACME 协议自动化证书签发,accounturi 可以将 CAA 策略绑定到特定 ACME 账户
  • 验证方法的多样化:ACME 支持多种域名验证方法(DNS-01、HTTP-01、TLS-ALPN-01),不同方法的安全特性不同
  • 安全事件的教训:某些安全事件源于 CA 未正确处理 CAA 扩展参数

CAA TTL 与缓存

CA 在查询 CAA 记录时,必须遵守 DNS TTL(生存时间):

  • CA 不得缓存 CAA 记录超过其 TTL 值
  • 如果 TTL 为 0,CA 必须在每次签发时实时查询
  • CA/B BR 规定:如果 CAA 查询失败(NXDOMAIN 除外),CA 必须在 8 小时内完成签发
这一规则确保了域名所有者可以通过更新 CAA 记录来快速撤销签发授权。

CAA 与 DNSSEC 的协同

为什么 CAA 需要 DNSSEC

CAA 记录存储在 DNS 中,而 DNS 协议本身缺乏完整性保护。如果攻击者能够篡改 DNS 响应(通过 DNS 劫持、中间人攻击等),就可以绕过 CAA 保护:

CODE
攻击场景(无 DNSSEC):

1. 域名所有者设置了 CAA 记录:只允许 Let's Encrypt
2. 攻击者劫持 DNS 查询,将 CAA 记录替换为:允许某个恶意 CA
3. 恶意 CA 为域名签发伪造证书
4. 浏览器信任该证书(因为 CA 根证书被信任)

DNSSEC 通过对 DNS 记录进行数字签名,确保 DNS 响应的完整性和真实性。CAA 在没有 DNSSEC 的环境下,安全性被削弱为 DNS 的安全性。

DNSSEC 签名链

部署建议

对于安全要求高的域名,强烈建议同时部署 CAA 和 DNSSEC:

  • 先部署 DNSSEC:确保 DNS 响应的完整性
  • 再部署 CAA:在 DNS 安全的基础上添加签发控制
  • 监控 CAA 有效性:定期检查 CAA 记录是否被意外修改

CAA 与证书透明度的互补关系

CAA 和 CT 是 Web PKI 安全体系中两个互补的机制:

关键洞察:CAA 和 CT 不是替代关系,而是互补关系。一个完整的安全策略应该同时使用两者:

  • CAA:阻止未经授权的签发("不该签的不让签")
  • CT:发现所有已签发的证书("签了什么都知道")
即使 CAA 被绕过(如 DNS 被劫持),CT 仍然可以检测到未经授权的证书。反之,即使 CT 监控延迟,CAA 也能在签发时即时阻止。

实施中的关键问题

1. CAA 记录的 DNS 传播延迟

CAA 记录作为 DNS 记录,其变更需要时间传播到全球 DNS 缓存。这意味着:

  • 新增 CAA 记录:可能需要等待旧缓存过期(最多 TTL 时间)
  • 修改 CAA 记录:在传播窗口期内,不同地理位置的 CA 可能看到不同的 CAA 记录
  • 删除 CAA 记录:旧缓存可能继续生效,导致 CA 继续遵守已删除的 CAA 策略
缓解措施
  • 设置合理的 TTL 值(建议 3600 秒 = 1 小时)
  • 在变更 CAA 记录前,先降低 TTL 值,等待旧缓存过期
  • 变更后使用多个地理位置的 DNS 服务器验证

2. 子域名的 CAA 继承

CAA 记录具有继承性:如果子域名没有自己的 CAA 记录,将继承父域名的 CAA 记录。

CODE
example.com.      CAA  0  issue  "letsencrypt.org"
www.example.com.  (无 CAA 记录,继承父域名)

→ www.example.com 也只允许 Let's Encrypt 签发

重要细节

  • 继承是递归的:a.b.example.com 会继承 b.example.comexample.com 的 CAA
  • 一旦子域名设置了 CAA 记录,继承链断裂,不再受父域名 CAA 影响
  • 通配符匹配:*.example.com 的 CAA 记录匹配所有直接子域名

3. CAA 与内部 PKI

CAA 机制仅适用于公开信任的 CA。企业内部 PKI(如自建的 CA 体系)不受 CAA 约束,因为:

  • 内部 CA 不在浏览器/操作系统的信任列表中
  • 内部 CA 通常不查询外部 DNS 的 CAA 记录
  • 内部 PKI 的安全边界是企业网络本身
国密 PKI 的特殊情况:国密体系中的 CA(如金融 CA、政务 CA)通常不公开信任,因此 CAA 机制不直接适用。但国密体系可以借鉴 CAA 的设计思想,在内部 CA 的签发策略中实现类似的授权控制。

4. CAA 绕过风险

CAA 并非万能,存在以下绕过风险:

国密 PKI 体系中的 CAA 适用性

直接适用性分析

CAA 作为 DNS 层面的安全机制,其协议本身与算法无关,因此在协议层面对国密 PKI 体系完全适用

  • DNS 层面无国密依赖:CAA 记录是标准的 DNS 资源记录,不依赖任何特定密码算法
  • CA 检查逻辑通用:国密 CA 在签发证书前同样可以查询 CAA 记录
  • 与国密算法无关:CAA 控制的是"谁可以签发",而非"用什么算法签发"

国密体系的特殊考虑

然而,国密 PKI 体系在实际部署 CAA 时需要考虑以下特殊因素:

部署建议

对于国密 PKI 体系,建议:

  • 公开信任的国密 CA(如 CFCA 的公开服务)应完整支持 CAA 检查和 RFC 8657 扩展参数
  • 内部国密 CA 可以在内部策略引擎中实现 CAA 逻辑,作为签发决策的输入
  • 双证书环境 的 CAA 记录应同时包含国际 CA 和国密 CA
  • 推动 DNSSEC 部署,为 CAA 提供完整性保护基础

总结

CAA DNS 记录是 Web PKI 安全体系中一个设计简洁但影响深远的机制。通过在 DNS 层面声明签发授权,CAA 将证书签发的控制权从 CA 侧部分转移到域名所有者侧,有效缩小了恶意签发和错误签发的攻击面。

CAA 的核心价值不仅在于其技术机制,更在于其安全哲学的转变:从"信任 CA 不会犯错"到"不信任任何单一实体,通过制衡机制降低风险"。这一哲学与纵深防御、零信任等现代安全理念一脉相承。

随着 SC-098v2 在 2027 年 3 月将 RFC 8657 扩展参数变为强制要求,CAA 的表达能力和安全精度将进一步提升。域名所有者应积极部署 CAA 记录,并结合 DNSSEC、CT 日志等机制,构建多层次的证书安全防御体系。

参考来源

相关实践