2025年10月22日,互联网系统联盟(ISC)披露了一个影响BIND 9 DNS服务器的严重漏洞(CVE-2025-40778)。攻击者无需网络访问权限,即可向递归解析器的缓存中注入伪造的DNS记录,将用户流量重定向到恶意服务器。这是自2008年Kaminsky漏洞以来,DNS缓存投毒攻击再次成为头条新闻。
讽刺的是,DNSSEC——这个专门设计用于防御此类攻击的协议——已经存在了近三十年。根区在2010年完成签名,绝大多数顶级域名(TLD)已支持DNSSEC,但根据2025年的统计数据,全球仅有约4.7%的域名启用了DNSSEC签名。在顶级网站的采纳率也仅为14.3%——尽管已是全球平均水平的三倍,但仍然低得惊人。
一个被寄予厚望的协议,为何在四分之一个世纪后仍未普及?答案远比"复杂性"三个字复杂得多。
Kaminsky时刻:DNS的至暗与转折
2008年夏天,安全研究员Dan Kaminsky发现了一个震惊业界的问题:DNS协议存在根本性缺陷,使得缓存投毒攻击变得可行且高效。
传统DNS查询使用16位的查询ID(Query ID)和固定的源端口——这意味着攻击者只需猜对65,536种可能性中的一种。Kaminsky的攻击方法更为巧妙:他通过不断查询目标域名的随机子域名(如12345.example.com),迫使解析器反复向权威服务器发起请求。在每次请求等待响应的窗口期内,攻击者可以发送大量伪造的响应包。只要有一个包猜对了查询ID和源端口,解析器的缓存就被成功污染。
更致命的是,Kaminsky攻击不仅污染单条记录,还能污染权威名称服务器(NS记录)本身——这意味着攻击者可以"接管"整个域名,而不仅仅是某个IP地址。
ISC在公告中直言:“DNSSEC是唯一的完整解决方案。”
这一事件催生了两个并行的发展方向:一是短期缓解措施(随机化源端口、增加熵);二是加速DNSSEC的部署进程。2008年7月的协调补丁发布后,DNSSEC从"重要但不紧急"变成了"关键基础设施项目"。
DNSSEC的工作原理:信任链的构建
DNSSEC的核心思想是通过数字签名验证DNS数据的真实性和完整性。它不改变DNS协议的基本工作方式,而是在现有记录基础上添加签名记录(RRSIG)。
密钥层次结构
DNSSEC使用两层密钥架构:
Zone Signing Key(ZSK):用于签名区域内的所有记录。由于需要频繁签名,通常使用较短的密钥(如ECDSA P-256),并定期轮换(通常每月或每季度)。
Key Signing Key(KSK):用于签名ZSK本身。这个密钥更敏感,轮换频率较低(通常每年或更久)。
两层架构的设计初衷是分离操作职责:ZSK可以频繁轮换而无需与父区域协调,只有KSK的变更需要通知父区域。但这个设计也带来了复杂性的翻倍——管理员需要管理两套密钥、两套轮换策略、两套备份方案。
信任链:从根到叶
DNSSEC的信任模型是层级式的。根区KSK作为全局信任锚点,由ICANN通过公开的签名仪式管理。每个子区域通过DS(Delegation Signer)记录将信任传递给父区域:
根区KSK → 签名 .com区的KSK → 签名 example.com的KSK → 签名 example.com的所有记录
验证过程从根开始,逐级向下验证签名链。任何一级断裂,整个信任链都会失效。
否定存在证明:NSEC与NSEC3
DNSSEC的一个独特挑战是如何证明"某个记录不存在"。传统DNS直接返回NXDOMAIN,但DNSSEC需要对此进行签名验证。
NSEC(Next SECure)记录按字母顺序链接区域内的所有名称,形成一条链。查询不存在的名称时,服务器返回相邻两个名称的NSEC记录,证明"在这个区间内没有你要找的名字"。
问题:任何人可以通过遍历查询,重建整个区域的域名列表——这被称为"区枚举"(Zone Walking),可能泄露本应隐藏的内部主机名。
NSEC3通过哈希域名来缓解这个问题。名称被哈希后排序,攻击者需要破解哈希才能还原原始名称。但NSEC3增加了响应包大小和计算开销,且仍不能完全阻止枚举(通过彩虹表或暴力破解)。
根签名仪式:互联网的"核按钮"
根区KSK的管理是DNSSEC最引人注目的部分。ICANN每季度举行一次"根签名仪式"(Root Signing Ceremony),在严格监控下使用KSK签名ZSK。
仪式在两个设施中进行:洛杉矶和弗吉尼亚州的库尔佩珀。每个设施都包含一个特别设计的"仪式室",存放硬件安全模块(HSM)。HSM是一个高度安全的设备,如果被物理篡改、震动或未经授权操作,会自毁内部密钥。
参与者与控制机制:
约50名来自全球互联网社区的专家参与仪式,分为三组(每组7人):
- 密码持有者(Crypto Officers):持有激活HSM所需的智能卡
- 保险柜组合员(Safe Combination Holders):知道存放HSM的保险柜密码
- 仪式见证人(Ceremony Witnesses):独立观察并验证每个步骤
整个仪式持续3-8小时,严格遵循预设脚本,全程录像直播。至少需要十几人同时在场才能激活系统——这是典型的"双人控制"原则的扩展版本。
媒体报道常简化为"七把钥匙控制互联网",这掩盖了实际的复杂性。 真正的安全依赖于多层重叠的控制机制,远非七个人或七把钥匙所能概括。
设计的困境:来自DNSSEC创始人的反思
2024年7月,Edward Lewis——DNSSEC原始设计团队成员之一——在APNIC博客上发表了一篇深刻的反思文章《Where did DNSSEC go wrong?》。他指出了几个根本性的设计决策失误。
“不能信任主机处理私钥”
1990年代的设计假设是:主机安全性差到无法安全存储私钥。因此,所有签名必须预先计算——服务器不能根据查询动态生成签名。
这个假设导致了连锁问题:
否定响应复杂化:预计算的否定响应必须覆盖所有"不存在"的情况,而这在概念上是不可能的。NSEC/NSEC3的复杂设计正是为了解决这个问题。
通配符处理困难:DNS通配符需要根据查询动态合成响应。DNSSEC不得不"揭示"服务器的工作过程,增加了协议复杂性和信息泄露。
CNAME/DNAME重定向:同样需要动态处理,DNSSEC被迫暴露内部操作。
Lewis指出,现代实践已经证明"在线签名"是可行的——将私钥保存在在线服务器上,根据查询动态签名。但这与DNSSEC的原始设计哲学冲突,集成起来相当复杂。
“与父区域的联系应最小化”
这个原则导致了KSK/ZSK双密钥架构的诞生。设计者担心父区域对子区域密钥更新的响应可能很慢,因此引入了ZSK作为可以自主轮换的"工作密钥"。
后果:密钥管理的工作量翻倍。解释DNSSEC变得更加困难——即使验证算法已经确定,两个密钥角色的具体使用规则仍然模糊。协议定义和软件实现都无法假设统一的实践。
实际上,单密钥(CSK,Common Signing Key)方案完全可以工作,且管理更简单。但这在DNSSEC发展多年后才被广泛认识。
“所有区域都是平等的”
设计者拒绝将大型区域(如.com)视为特殊案例,追求"一个协议适用所有场景"的简洁性。
问题:根区是真正特殊的——它没有父区域,必须依赖预配置的信任锚点。这个关键问题在早期设计中被低估了。根信任锚点的分发和管理成为了一个持续挑战。
自下而上的预期,自上而上的现实
DNSSEC的设计预期是:区域管理员认识到安全价值后,从叶节点开始部署,逐级向上签名。根区可能是最后被签名的,届时技术已经成熟可靠。
现实恰恰相反:根区在2010年完成签名,超过90%的TLD已签名,但叶子域名的签名率仍低于10%。部署压力来自上层,但底层动力不足。
Slack的24小时故障:DNSSEC部署的残酷课堂
2021年9月30日,Slack经历了一次持续24小时的故障,影响了不到1%的用户。事故原因?尝试为slack.com启用DNSSEC。
Slack工程团队的事故报告提供了一个宝贵的案例研究,展示了DNSSEC部署中可能出错的方方面面。
第一次尝试:无关事故
2021年9月7日,Slack首次尝试启用slack.com的DNSSEC签名。但在向注册商发布DS记录之前,一家美国大型ISP发生故障,导致许多用户报告无法访问Slack。团队出于谨慎回滚了变更。
第二次尝试:VPN用户的麻烦
9月8日的第二次尝试中,团队发现部分使用VPN的用户报告DNS解析问题。调查发现:某些解析器在权威名称服务器启用DNSSEC签名后——即使DS记录尚未在根/区发布——就会更严格地执行DNS规范。
问题在于Slack使用了CNAME记录在区域顶点(Apex)。RFC 2181规定这是不允许的,但许多实现之前放行了它。当DNSSEC启用时,某些解析器开始拒绝这种配置。
团队停止签名slack.com区域,问题解决。
第三次尝试:灾难性的回滚
9月30日,在周密计划后,团队进行了第三次尝试:
- 在NS1和Route53上启用slack.com区域的DNSSEC签名
- 验证解析正常,等待3小时"浸泡时间"
- 向注册商发布DS记录
- 验证再次成功
然后,问题出现了。用户报告"ERR_NAME_NOT_RESOLVED"错误。团队决定回滚——移除DS记录。
但关键的是,团队错误理解了DS记录的缓存行为。.com区域会指示解析器缓存DS记录24小时。移除DS记录后,解析器仍在24小时TTL内继续尝试验证签名。
更糟的是,团队随后回滚了签名本身——移除了DNSKEY记录。现在,解析器持有有效的DS记录,但没有对应的DNSKEY可以验证。结果是SERVFAIL——DNSSEC验证彻底失败。
团队不得不紧急联系主要ISP和公共DNS提供商(Google 8.8.8.8、Cloudflare 1.1.1.1等),请求刷新slack.com的缓存记录。
根本原因:通配符的NSEC问题
为什么第一次发布DS记录后就出现了NODATA响应?调查显示:Slack使用了*.slack.com通配符记录。
当查询不存在的记录类型时(如AAAA),Route53返回的NSEC响应缺少必要的信息。某些公共解析器(包括Google DNS)实现了"激进NSEC"(RFC 8198),会根据缓存的NSEC记录推断其他类型也不存在——导致后续的A记录查询也返回NODATA。
这不是解析器的bug,也不是Route53完全错误——而是协议的模糊地带,在特定实现组合下触发了问题。
AWS Route53团队后来修复了NSEC类型位图的问题。
响应包大小:被忽视的性能杀手
DNS最初设计使用UDP协议,响应包限制在512字节以内。超过这个限制会触发TCP回退,增加延迟和资源消耗。
DNSSEC显著增加了响应包大小:
- 一个典型的DNS响应约50-60字节
- DNSSEC签名的响应可能超过512字节,甚至接近4096字节
- 每个RRSIG记录增加46字节+密钥大小的开销
- DNSKEY记录本身也很大(RSA-2048约260字节,ECDSA P-256约90字节)
后果:
- 延迟增加:超过512字节的响应需要TCP回退,至少增加一次RTT
- IP分片风险:大UDP包可能被分片,增加丢包概率
- DDoS放大攻击:DNSSEC响应可作为放大攻击的载体——小查询触发大响应
2014年的研究《DNSSEC and Its Potential for DDoS Attacks》指出,DNSSEC签名的响应可以作为反射攻击的有效放大器。虽然这不是DNSSEC独有的问题,但签名记录的大尺寸确实加剧了风险。
替代方案的崛起:DoH与DoT的威胁模型差异
当DNSSEC在部署上举步维艰时,另一组DNS安全技术——DNS over HTTPS(DoH)和DNS over TLS(DoT)——却获得了快速采纳。
理解这种差异,需要回到威胁模型。
DNSSEC解决的威胁
- 完整性:确保DNS数据在传输中未被篡改
- 真实性:验证数据确实来自声称的权威服务器
- 否定存在证明:确认某个记录确实不存在(而非被拦截返回NXDOMAIN)
DNSSEC不解决的威胁
- 保密性:DNS查询和响应是明文的,任何人都可以看到你在查什么
- 隐私:ISP、权威服务器都可以收集你的查询日志
- 最后一公里:DNSSEC验证发生在解析器,客户端与解析器之间的通信仍然明文
DoH/DoT解决的威胁
- 保密性:加密客户端与解析器之间的通信
- 防窥探:ISP无法看到你的DNS查询内容(除非它也是你的DNS提供商)
- 防篡改:攻击者无法在传输中修改DNS响应
DoH/DoT不解决的威胁
- 解析器信任:你必须信任解析器返回正确的答案
- 权威服务器信任:无法验证权威服务器是否被入侵
- DNSSEC验证:加密通道不保证数据本身的真实性
关键洞察:DNSSEC和DoH/DoT解决的是不同的问题。前者验证"数据是否正确",后者保护"传输是否私密"。它们可以互补,但也可以独立部署。
这也是为什么浏览器厂商(Mozilla、Google)积极推动DoH,却对DNSSEC相对冷淡。对于普通用户,“ISP看不到我在查什么"是更直接的隐私需求;“权威服务器被劫持"是更抽象的安全威胁。
部署障碍的经济学
2024年,APNIC首席科学家Geoff Huston发表了题为《Calling time on DNSSEC?》的文章,直指问题的核心:经济学不利于DNSSEC采用。
网络效应缺失
DNSSEC的价值依赖于端到端的部署:域名签名、注册商支持、解析器验证。任何一环断裂,整个链条失效。
对于域名所有者:启用DNSSEC意味着:
- 配置复杂性增加
- 运维风险上升(签名过期、密钥轮换失败)
- 调试难度加大(DNSSEC错误通常表现为"不工作”,无明确错误信息)
- 直接收益有限——你无法强迫用户的解析器验证
对于ISP/解析器运营商:启用验证意味着:
- 增加CPU开销(签名验证计算密集)
- 增加响应延迟
- 可能导致"合法"域名被拒绝(签名配置错误)
- 用户无法理解"为什么有些网站打不开”
对于用户:几乎无感知——他们不知道DNSSEC是否存在,也无法选择。
负外部性
DNSSEC部署失败的主要代价由最终用户承担(安全风险),但部署成本由域名所有者和ISP承担。这种错位导致投资不足。
替代技术的竞争
HTTPS已广泛部署,TLS证书提供了另一种身份验证机制。对于Web应用,浏览器地址栏的锁图标来自证书验证,而非DNSSEC。DNSSEC的主要价值——DANE协议——在实践中很少使用。
DANE允许在DNS中发布TLS证书指纹,理论上可以绕过证书颁发机构(CA)的信任模型。但:
- 浏览器厂商对DANE缺乏热情(他们已经建立了CA生态系统)
- DANE本身依赖DNSSEC部署,陷入鸡生蛋的困境
- 证书透明度(CT)日志提供了另一种防篡改机制
2025年的现状与未来
截至2025年:
- DNSSEC验证率约36%(APNIC数据)
- 域名签名率约4.7%(Whisper State of DNSSEC 2025)
- ECDSA算法占签名域名的40.3%(RSA仍占主导)
- 荷兰、瑞典等国家的验证率较高,政府推动是关键因素
积极趋势
- 自动化工具成熟:Let’s Encrypt风格的DNSSEC自动化正在出现
- 注册商支持改善:主要注册商开始提供一键启用DNSSEC
- 云服务集成:AWS Route53、Google Cloud DNS支持DNSSEC签名
- 算法现代化:ECDSA减少了响应包大小,缓解了部分性能问题
持续挑战
- 密钥轮换风险:根区KSK轮换(2018年首次、2025年第二次)仍需要广泛协调
- 错误配置后果严重:DNSSEC错误通常导致域名完全不可达,而非降级服务
- 教育缺口:许多管理员不了解DNSSEC,或认为复杂性超过收益
教训与反思
DNSSEC的发展历程提供了宝贵的教训:
协议设计需要考虑运营现实。DNSSEC的许多设计决策在1990年代的威胁模型下是合理的,但未能预见现代互联网的运营复杂性。预计算签名、双密钥架构、最小化父区域联系——这些决策增加了部署成本,却没有带来相应的收益。
自上而下的部署模式失效。信任链要求端到端部署,但实际推动力量来自上层(根、TLD),底层(域名所有者)缺乏动力。这与HTTPS的成功形成鲜明对比——HTTPS通过浏览器警告(如"不安全"标签)创造了自下而上的部署压力。
替代方案可能更"足够好"。DoH/DoT的快速采纳表明,用户更关心"ISP看不到我的查询"而非"权威服务器被劫持"。这不意味着DNSSEC无用,但其价值主张需要更清晰的表达。
失败需要被承认和学习。Edward Lewis的反思文章展现了设计者的勇气:承认设计错误,而非归咎于"教育不足"或"工具不完善"。低采纳率本身就是对协议设计的批评。
DNSSEC不是失败品——它为DNS提供了真正需要的身份验证机制。根区和TLD的广泛签名构成了重要的基础设施。但对于叶子域名,三十年来的4.7%采纳率提出了一个尖锐的问题:一个协议如果过于复杂以至于几乎无人使用,它还能被称为成功吗?
2025年BIND缓存投毒漏洞的披露提醒我们:Kaminsky发现的问题从未真正消失,只是被缓解措施推迟了。DNSSEC仍然是"唯一完整的解决方案"——但这句15年前的断言,今天听起来既是一种承诺,也是一种无奈。
参考文献
-
Lewis, E. (2024). Where did DNSSEC go wrong? APNIC Blog.
-
Huston, G. (2024). Calling time on DNSSEC? APNIC Blog.
-
Whisper Security. (2025). State of DNSSEC 2025.
-
ISC. (2025). CVE-2025-40778: BIND 9 Vulnerability Announcement.
-
Friedl, S. (2008). An Illustrated Guide to the Kaminsky DNS Vulnerability. Unixwiz.net.
-
Slack Engineering. (2021). The Case of the Recursive Resolvers.
-
ICANN. (2023). The Key to the Internet and Key Ceremonies: An Explainer.
-
Kaminsky, D. (2008). Black Ops 2008: It’s The End Of The Cache As We Know It. Black Hat.
-
RFC 4033/4034/4035. DNS Security Extensions.
-
RFC 7858. DNS over TLS (DoT).
-
RFC 8484. DNS over HTTPS (DoH).
-
RFC 8198. Aggressive Use of DNSSEC-Validated Cache.
-
APNIC Labs. DNSSEC Validation Rate Statistics.
-
Internet Society. DNSSEC Deployment Maps.