CAA DNS 记录与 RFC 8657:从 jabber.ru 攻击到 Cloudflare 静默覆盖的深度剖析

PKI 体系 · 2026-06-13 · 7 阅读

前言:一个本不该发生的攻击

2023 年,俄罗斯 XMPP 即时通讯服务 jabber.ru 遭遇了一次精心策划的中间人攻击(MitM)。攻击者无需入侵 jabber.ru 的服务器,甚至不需要触碰目标网络中的任何设备。他们所做的,是劫持互联网的路由基础设施——BGP(边界网关协议),然后向 Let's Encrypt 申请了一张 jabber.ru 的有效 TLS 证书。

攻击链路简洁得令人不安:

  • 劫持 BGP 路由,拦截发往 jabber.ru 所在 IP 地址段的流量
  • 向 Let's Encrypt 发起证书申请,选择 HTTP-01 验证方式
  • Let's Encrypt 向 http://jabber.ru/.well-known/acme-challenge/ 发起验证请求
  • 攻击者拦截该请求,返回正确的 token
  • Let's Encrypt 验证通过,签发合法证书
  • 攻击者使用该证书对 jabber.ru 用户实施中间人攻击
这次攻击并非孤例。2018 年 Princeton 大学的研究论文《Bamboozling Certificate Authorities with BGP》就首次系统性地证明了这种攻击的可行性。IETF 随后发布了 RFC 8657,专门设计了两项安全机制来防御此类攻击:accounturi(账户绑定)和 validationmethods(验证方法限制)。

然而,到了 2026 年,这些安全机制仍然无法被数以百万计的域名使用者启用。原因不是技术复杂度,也不是标准未成熟——RFC 8657 早在 2019 年就已发布。真正的原因是:Cloudflare 的 Universal SSL 产品在用户不知情的情况下,静默覆盖了用户配置的 RFC 8657 CAA 记录,代之以不安全的默认值。

这不是一个技术 bug,而是一个\"功能冲突\"(feature collision)——便利性功能与安全控制之间的架构性矛盾。

CAA 基础:DNS 层面的证书签发授权

RFC 8659:品牌级信任

要理解问题的全貌,需要先了解 CAA(Certificate Authority Authorization)的基础标准 RFC 8659。

CAA 是一个 DNS 资源记录类型,允许域名所有者在 DNS 中声明\"哪些 CA 可以为我的域名签发证书\"。例如:

DNS
example.com.  IN  CAA  0  issue  "letsencrypt.org"

这条记录的含义是:全球所有 CA 在为 example.com 签发证书之前,必须检查自己的 DNS 名称是否匹配 letsencrypt.org。如果不匹配,签发请求必须被拒绝。

CAA 的防御价值在于:即使攻击者能够劫持验证流量(如 BGP 劫持),他们也无法让未授权的 CA 签发证书——因为未授权的 CA 在检查 CAA 记录后会直接拒绝签发。

但 CAA 有一个根本性的安全盲区:它只限制了\"哪个 CA 可以签发\",没有限制\"哪个账户可以签发\"。如果域名所有者指定了 Let's Encrypt 作为唯一授权 CA,那么 Let's Encrypt 上的任何账户都可以通过验证并获得证书。

在 jabber.ru 的攻击场景中,攻击者恰恰利用了这个盲区——他们在自己的 Let's Encrypt 账户下申请证书,而 HTTP-01 验证被 BGP 劫持所绕过。

RFC 8657:从品牌级信任到过程级信任

为了解决 CAA 的盲区,IETF 在 2019 年 11 月发布了 RFC 8657《Automated Certificate Management Environment (ACME) CAA Challenge Validation》,引入了两个关键参数:

1. accounturi — 账户绑定(\"第二因素\")

accounturi 参数将证书签发限制到特定的 ACME 账户。即使攻击者能够劫持验证流量,如果他们使用的是自己的 ACME 账户而非域名所有者的账户,CA 必须拒绝签发。

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

这条记录的含义是:只有 Let's Encrypt 上账户 ID 为 123456 的账户,才能为 example.com 签发证书。任何其他账户——无论验证是否通过——都必须被拒绝。

2. validationmethods — 验证方法限制(\"攻击向量盾牌\")

validationmethods 参数允许域名所有者限制 CA 可以使用的验证方法。ACME 协议定义了多种验证方式,其中 HTTP-01 最容易受到 BGP 劫持攻击,而 DNS-01 要求攻击者控制 DNS 基础设施,攻击难度显著更高。

DNS
example.com.  IN  CAA  0  issue  "letsencrypt.org; validationmethods=dns-01"

这条记录禁止 Let's Encrypt 使用 HTTP-01 方式为 example.com 验证域名控制权。如果攻击者劫持了 web 服务器的流量,他们也无法完成验证——因为 CA 不会使用 HTTP-01 方法。

防御矩阵:两个参数的协同效应

攻击场景无 CAARFC 8659 CAARFC 8657 accounturiRFC 8657 validationmethods
攻击者使用自己的 CA❌ 可签发✅ 拒绝✅ 拒绝✅ 拒绝
攻击者劫持 HTTP-01 验证❌ 可签发❌ 可签发✅ 拒绝(账户不匹配)✅ 拒绝(方法不允许)
攻击者劫持 DNS-01 验证❌ 可签发❌ 可签发✅ 拒绝(账户不匹配)❌ 可签发
攻击者同时劫持 HTTP-01 + 使用自己账户❌ 可签发❌ 可签发✅ 拒绝✅ 拒绝
最佳实践是同时使用两个参数,形成纵深防御:

DNS
example.com.  IN  CAA  0  issue  "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/123456; validationmethods=dns-01"

RFC 8657 的作者 Hugo Landau 本人在分析 jabber.ru 事件时明确指出:如果 jabber.ru 当时部署了上述 CAA 记录,攻击将完全失败。

Cloudflare 的问题:便利性 vs 安全性

Universal SSL 的\"好心\"覆盖

Cloudflare 是全球最大的 CDN 和安全平台之一,承载着约 21% 的互联网网站(数据来源:Cloudflare 官方统计,2025 年。W3Techs 估算约 20-22%)。其免费套餐包含 Universal SSL 功能——自动为所有接入 Cloudflare 的域名签发和续期 TLS 证书。

Universal SSL 的证书签发流程大致如下:

  • 域名接入 Cloudflare 后,Cloudflare 自动检测域名的 DNS 配置
  • Cloudflare 的 ACME 客户端向合作 CA(Let's Encrypt、Google Trust Services 等)发起证书申请
  • 在申请过程中,Cloudflare 需要确保 CAA 记录不会阻止其合作 CA 签发证书
  • 关键步骤:Cloudflare 自动向域名的 DNS 区域注入 CAA 记录,授权其合作 CA
问题出在第 4 步。当用户尝试在 Cloudflare 的 DNS 管理界面中添加自己的 CAA 记录(包含 accounturivalidationmethods 参数)时,Cloudflare 的系统会:

  • 检测到用户正在添加 CAA 记录
  • \"好心\"地同时添加 Cloudflare 自己的 CAA 记录
  • 如果用户的记录与 Cloudflare 的记录存在冲突,Cloudflare 的记录会覆盖用户的记录
最终 DNS 中实际生效的记录可能如下:

DNS
; 用户配置的安全记录(被覆盖/替换)
; example.com.  IN  CAA  0  issue  "letsencrypt.org; accounturi=..."

; Cloudflare 注入的记录(实际生效)
example.com.  IN  CAA  0  issue  "letsencrypt.org"
example.com.  IN  CAA  0  issue  "google.com"

根据 RFC 8659 的规则,CA 在检查 CAA 记录时,只要找到任何一条匹配的记录就必须允许签发。Cloudflare 注入的宽泛记录(没有 accounturivalidationmethods 约束)使得用户精心配置的安全控制形同虚设。

一个具体的攻击场景

假设一个域名所有者使用 acme-dns 服务(一个专门用于 DNS-01 验证的轻量级 DNS 服务器),并通过 CNAME 记录将 _acme-challenge.example.com 委托给 acme-dns

DNS
_acme-challenge.example.com.  IN  CNAME  user.acme-dns.example.net.

域名所有者配置了 RFC 8657 CAA 记录:

DNS
example.com.  IN  CAA  0  issue  "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/USER_ACCOUNT_ID; validationmethods=dns-01"

预期安全效果:只有域名所有者的 Let's Encrypt 账户(USER_ACCOUNT_ID)可以使用 DNS-01 方式为 example.com 签发证书。即使 acme-dns 服务器的管理员是恶意的,他们也无法用自己的账户为 example.com 申请证书。

Cloudflare 覆盖后的实际效果:Cloudflare 注入了宽泛的 issue "letsencrypt.org" 记录。acme-dns 服务器的管理员现在可以使用自己的 Let's Encrypt 账户,通过 DNS-01 验证为 example.com 申请证书。accounturi 的安全绑定被完全绕过。

平台对比:集成平台 vs DNS 提供商

Cloudflare 并非唯一存在此问题的平台,但问题的严重程度在不同类型的供应商之间存在显著差异:

供应商类型供应商CAA 行为安全影响
集成平台Cloudflare注入宽泛记录,覆盖用户配置严重:主动破坏 RFC 8657
集成平台Vercel抽象签发细节,可能冲突中等:取决于具体配置
集成平台Netlify公开 ACME accounturi,用户可安全配置无:提供平台级绑定
云服务商AWS (ACM)如果存在 CAA 则强制执行 issue "amazon.com"低:不干扰其他 CA 的记录
云服务商Google Cloud如果存在 CAA 则强制执行 issue "pki.goog"低:不干扰其他 CA 的记录
DNS-onlyAWS Route 53完全支持自定义 CAA 记录无:纯 DNS 服务,不干预
这个对比揭示了一个行业性的分歧:\"DNS-only\"供应商销售安全和控制,而\"集成平台\"销售便利——往往以牺牲安全为代价。

Netlify 的做法值得借鉴:他们公开了自己的 ACME accounturi,允许用户在 CAA 记录中同时授权 Netlify 和自己的账户,实现了平台便利性与用户安全控制的兼容。

MPIC:不完美的补充方案

有人可能会问:CA/B 论坛在 2024 年 7 月通过的 Ballot SC-067 v3 要求 CA 实施\"多角度签发确认\"(Multi-Perspective Issuance Corroboration, MPIC),这是否解决了 BGP 劫持攻击的问题?

MPIC 要求 CA 从多个独立的网络视角验证域名控制权,而不是依赖单一视角。根据实施时间表:

  • 2024 年 9 月:MPIC 成为推荐实践
  • 2025 年 3 月:MPIC 成为强制要求(至少 2 个独立视角)
  • 2026 年 3 月:要求收紧至至少 3 个独立视角
MPIC 确实显著提高了 BGP 劫持攻击的门槛,但它不能替代 RFC 8657:

控制机制主要目的防御的攻击类型
MPIC从多个网络视角验证域名控制权,防止单点 BGP 劫持网络层拦截、BGP 劫持
RFC 8657 accounturi将签发绑定到特定 ACME 账户恶意管理员、子账户滥用、第三方 DNS 操作员越权
RFC 8657 validationmethods限制 CA 可以使用的验证方法HTTP-01 劫持、路径遍历绕过
2023 年 Princeton 的后续研究(由 Henry Birge-Lee 等人合著)发现,标准 MPIC 部署对 BGP 攻击的中位韧性约为 88.6%,主要因为 DNS 基础设施的攻击面在扩大。这意味着仍有约 11% 的攻击向量是 MPIC 无法覆盖的。

MPIC 和 RFC 8657 是互补的防御层,而非替代关系。MPIC 减少了最容易被利用的网络层攻击,而 RFC 8657 提供了身份层的加密保证。对于高价值域名,两者都应该部署。

行业现状:RFC 8657 支持矩阵(2026 年)

截至 2026 年年中,RFC 8657 在行业中的支持情况呈现明显的两极分化:

实体角色支持状态
Let's EncryptCA完全支持(2023 年 1 月起强制实施)
Google Trust ServicesCA完全支持,Chrome Root Program 政策要求
DigiCertCA新一代 DNS-PERSIST 验证方法要求
Amazon Trust ServicesCA草案/测试阶段,DNS-PERSIST 草案合著者
FastlyCDN/MSP草案/测试阶段,DNS-PERSIST 草案合著者
Netlify托管平台已支持,公开 ACME accounturi
CloudflareCDN/MSP不支持,Universal SSL 覆盖用户配置
一个值得注意的细节:2025 年 11 月,IETF ACME 工作组正式采纳了 draft-ietf-acme-dns-persist-00,引入了\"持久化 DNS\"验证——这个新标准强制要求使用 accounturi 参数。Fastly 和 Amazon Trust Services 是该草案的合著者。而 Cloudflare 的架构与 accounturi 不兼容。

DNSSEC 的协同效应

RFC 8657 的安全价值在与 DNSSEC 结合时会进一步增强。Henry Birge-Lee 在 CA/B 论坛的讨论中指出,CAA + DNSSEC + RFC 8657 的组合是唯一能让证书签发\"完全基于加密信任\"的机制。

没有 accounturi,即使域名启用了 DNSSEC,如果攻击者能够拦截验证流量(如 2026 年 1 月的委内瑞拉 BGP 路由泄漏事件所证明的),仍然可能绕过验证。而 accounturi 将签发绑定到特定的账户密钥,提供了独立于网络层安全的加密保证。

实操指南:如何正确部署 CAA + RFC 8657

步骤 1:确定你的 ACME 账户 URI

如果你使用 Let's Encrypt 和 Certbot,可以通过以下方式获取账户 URI:

BASH
# 查看 Certbot 的账户信息
sudo certbot show_account

# 输出示例:
# Account Registration URL: https://acme-v02.api.letsencrypt.org/acme/acct/12345678

如果使用 ACME 客户端库(如 Python 的 acme 库),可以在代码中获取:

步骤 2:配置 CAA DNS 记录

在你的 DNS 管理界面(如果使用 Cloudflare,请先阅读第三节的说明)中添加以下记录:

基础 CAA(RFC 8659)— 仅限制 CA:

DNS
; 允许 Let's Encrypt 和 Google Trust Services
example.com.  IN  CAA  0  issue  "letsencrypt.org"
example.com.  IN  CAA  0  issue  "google.com"

; 禁止所有其他 CA(iodef 标签用于违规报告)
example.com.  IN  CAA  0  issuewild  ";"
example.com.  IN  CAA  0  iodef  "mailto:security@example.com"

完整 CAA(RFC 8657)— 限制 CA + 账户 + 验证方法:

DNS
; 仅允许特定 Let's Encrypt 账户,仅允许 DNS-01 验证
example.com.  IN  CAA  0  issue  "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/12345678; validationmethods=dns-01"

; 通配符证书同样限制
example.com.  IN  CAA  0  issuewild  "letsencrypt.org; accounturi=https://acme-v02.api.letsencrypt.org/acme/acct/12345678; validationmethods=dns-01"

; 违规报告邮箱
example.com.  IN  CAA  0  iodef  "mailto:security@example.com"

步骤 3:验证 CAA 配置

配置完成后,验证 DNS 记录是否正确生效:

BASH
# 查询 CAA 记录
dig example.com CAA +short
dig _acme-challenge.example.com CAA +short

# 或使用 nslookup
nslookup -type=CAA example.com

验证 CA 是否识别你的配置(使用 Let's Encrypt 的沙盒环境):

BASH
# 使用 Certbot 的干跑模式测试
sudo certbot certonly --dry-run --dns-dns \
  --server https://acme-staging-v02.api.letsencrypt.org/directory \
  -d example.com

步骤 4:监控 CAA 合规性

在生产环境中,建议设置 CAA 监控告警:

安装依赖:pip3 install dnspython

如果你使用 Cloudflare:当前可行的缓解方案

截至 2026 年 6 月,Cloudflare 免费版和专业版用户无法使用 RFC 8657 的完整保护。如果你的威胁模型需要严格的 CAA 执行,有以下几层缓解方案:

方案 A:使用付费套餐 + 自定义证书(推荐)

  • 升级到 Cloudflare Business 或 Enterprise 计划
  • 在 Cloudflare 控制面板中:SSL/TLS → Edge Certificates → Disable Universal SSL
  • 使用 Certbot 等工具自行签发证书(确保使用 accounturivalidationmethods
  • 将自定义证书上传到 Cloudflare
这确保了证书签发完全在你的控制之下,Cloudflare 不再注入 CAA 记录。

方案 B:使用 Cloudflare Advanced Certificate Manager(有限保护)

Cloudflare 的 ACM 插件允许在较低套餐上订购特定证书,但 Cloudflare 仍然管理签发流程,CAA 覆盖行为可能仍然存在。

方案 C:CT 监控作为检测手段(所有用户可用)

如果无法实现预防性控制,至少部署证书透明度监控:

BASH
# 使用 certstream 监控 CT 日志
pip3 install certstream
certstream monitor --domain example.com --alert-threshold 1

CT 监控是检测工具而非预防工具——它能在攻击发生后(证书已签发)及时发出告警,但无法阻止攻击。

历史视角:CA 安全事件的演进链

理解 CAA 和 RFC 8657 的安全价值,需要将它们放在 CA 安全事件的历史脉络中审视:

时间事件缺失的防御层
2011 年 9 月DigiNotar 被入侵基础 CAA 即可限制影响范围
2012 年Trustwave 签发 subordinate CACAA + accounturi 可限制
2015-2016 年WoSign/StartCom 违规签发validationmethods 可防止非标准验证
2017 年HTTP-01 路径遍历绕过(CVE-2017-15868)validationmethods=dns-01 可防御
2018 年Princeton BGP 劫持论文RFC 8657 可全面防御
2023 年jabber.ru BGP 劫持攻击RFC 8657 可全面防御
2026 年 1 月委内瑞拉 BGP 路由泄漏RFC 8657 + DNSSEC 可提供加密保证
每一次 CA 安全事件都推动了新的防御标准的诞生。CAA(RFC 8659)是对 DigiNotar 类事件的回应,而 RFC 8657 则是对 BGP 劫持攻击的回应。但标准的制定和部署之间存在巨大的鸿沟——这个鸿沟的长度,往往取决于\"集成平台\"的商业优先级。

总结

CAA 和 RFC 8657 代表了互联网 PKI 体系从\"信任但验证\"到\"加密保证\"的重要演进。通过 accounturivalidationmethods 两个参数,域名所有者可以将证书签发从\"任何 CA 任何账户\"的宽松模式,收紧到\"特定 CA + 特定账户 + 特定验证方法\"的严格模式。

然而,Cloudflare Universal SSL 的默认配置在用户不知情的情况下破坏了这一安全机制。这不是一个技术 bug,而是\"集成平台\"商业模式的固有限制——自动化 SSL 签发需要覆盖用户的 DNS 配置才能可靠运行。

对于依赖 Cloudflare 且安全要求高的域名所有者,当前最可靠的方案是:使用付费套餐 + 自行管理证书签发。对于所有域名所有者,至少应该:

  • 了解 RFC 8657 的存在和价值
  • 在 DNS 中配置基础 CAA 记录(限制授权 CA)
  • 部署 CT 监控作为最后一道检测防线
  • 关注 Cloudflare 等平台对 RFC 8657 的支持进展
互联网的安全不是单一技术能解决的问题,而是技术、标准和商业博弈的持续平衡。理解这一平衡的运作方式,是做出正确安全决策的第一步。

参考来源