本文为 Cloudflare 官方博客《DNSSEC: An Introduction》的中文翻译,原文地址:https://blog.cloudflare.com/dnssec-an-introduction。翻译仅用于学习与交流,版权归 Cloudflare 所有。如有侵权,请联系删除。

点评

这篇文章对 DNS 和 DNSSEC 做了简短而优秀的介绍,从传统的 DNS 工作原理,不足,以及 DNSSEC 解决的问题入手,告诉读者为什么我们需要 DNSSEC 以及它能帮助我们解决什么问题

不管是开发者,或者还是使用这些网络基础设施的用户,这篇文章都值得一看

可惜直到我翻译这篇博客的 2025 年,目前互联网上的 DNSSEC 的普及率仍然不高,DNS 安全的这块互联网漏洞还需要补齐

DNSSEC 简介

在 CloudFlare,我们的使命是帮助构建更好的互联网。这项工作的一部分包括使网站更快、更可靠、更值得信赖。显然,使网站更安全的协议首选是 HTTPS。CloudFlare 的最新产品——通用 SSL(Universal SSL)——通过免费为网站提供 HTTPS 支持,帮助网站运营者为访问者提供可信的浏览体验。在本篇博文中,我们关注另一个协议——DNS,并探讨一项提高其可信度的提案:DNSSEC。

DNS(域名系统)是互联网权威性的支柱之一。它负责将域名(如www.cloudflare.com)转换为数字化的网络地址(如 198.41.214.163),因此常被称为“互联网的电话簿”。

DNSSEC(域名系统安全扩展)是为 DNS 提供记录认证机制的一套安全扩展协议。CloudFlare 计划在未来六个月内推出 DNSSEC 服务,并已邀请该协议的发明者之一奥拉弗·古德蒙德松(Olafur Gudmundsson)加入团队主导该项目。

介绍 DNS

域名系统(DNS)是现代互联网最古老且最基础的组件之一。作为将域名映射到IP地址的机制,它为人性化的网络导航提供了可能,让用户得以访问互联网上数以百万计的机器与设备。20世纪80年代初设计DNS时,协议中并未考虑强安全机制——当时的计算机性能远逊于当今设备,公钥加密技术尚属新兴概念且受到严格管制,网络规模较小,参与者多为彼此熟识的可信机构。随着网络规模扩大与技术演进,DNS始终保持着最初不加密、不验证的安全缺陷。

1993年,互联网工程任务组(IETF)发起公开讨论,探索如何提升DNS的可信度。经过长期论证,最终在2005年正式发布了一套名为"域名系统安全扩展"(DNSSEC)的协议标准,取代早期方案成为DNS安全防护的权威规范。尽管该标准发布已近十年,DNSSEC至今仍未实现大规模普及。

推动DNSSEC普及的关键因素包括2008年丹·卡明斯基(Dan Kaminsky)发现的缓存投毒攻击,该事件暴露出传统DNS存在的重大信任缺陷,也印证了DNSSEC的解决方案价值。然而即便经过多年努力,其普及进程依然迟缓——这主要源于多重阻力:网络运营商出于稳定性考虑(这无可厚非)对复杂协议持保守态度;更根本的矛盾在于,业界始终未能就"DNSSEC是否为DNS安全的最优解"达成共识。

本文将深入剖析DNS与生俱来的安全缺陷,并阐释如何通过DNSSEC增强这个互联网基础架构的可信度。

DNS:分布式键值存储的先行者

DNS 的核心概念很简单:它是一个记录域名信息的全球数据库,堪称互联网世界的电话簿。

当客户端需要访问 "www.example.com" 这类地址时,会向 DNS 查询对应的 IP 地址。通常情况下,所有 DNS 通信都通过 UDP 协议传输。(译者注:现在的一些先进的 DNS 查询协议,比如说 DoT 或者 DoH 也使用 TCP 作为传输协议)

DNS 能够应答多种资源记录(RR)类型的查询。其中最重要的 RR 类型是"A 记录",它存储着域名对应的 IPv4 地址。要查询某域名下任意记录的值,可以向 DNS 解析器发起请求。例如,若想获取 www.example.com 的IP地址,可提出如下查询请求:

"域名www.example.com的A记录是什么?"

原始 DNS 请求是一个 UDP 数据包,如代码清单1 所示。该请求包含一个 ID(0x27e1)、若干标识请求类型的标志位,以及查询内容本身。

针对原始 DNS 请求的响应如代码清单2 所示。该响应包含匹配的 ID(0x27e1)、回显的原始请求副本、若干标志位(1/0/0),以及查询结果:93.184.216.119。响应中还包含称为生存时间(TTL)的有效期字段,用于指示该记录的缓存有效期。

原始的 DNS 请求:

0x0000: 5ad4 0100 0001 0000 0000 0000 0765 7861 ‘............exa
0x0010: 6d70 6c65 0363 6f6d 0000 0100 01        mple.com.....

WireShark 的抓包:

原始的 DNS 响应:

0x0000: 51d4 8180 0001 0001 0000 0000 0765 7861 ‘............exa
0x0010: 6d70 6c65 0363 6f6d 0000 0100 01c0 0c00 mple.com........
0x0020: 0100 0100 0031 f500 045d b8d8 77 .....1...]..w

WireShark 的抓包:

DNS 是如何工作的

DNS 本质上是一个分布式键值数据库。理论上其返回值可以是任意数据,但实际应用中必须符合既定的记录类型标准,如地址记录、邮件交换记录、服务器列表、自由格式文本记录等。键值结构由名称(name)、类型(type)和类别(class)三要素构成。

该命名空间采用层级结构(详见下文),DNS 信息由权威服务器(Authoritative Servers)负责发布。DNS 解析器(Resolvers)通过遵循命名层级体系,依次向各级权威服务器发起查询请求,最终定位目标信息。互联网服务提供商(ISP)通常会为用户提供递归解析器(Recursive Resolver)服务,代表用户完成整个解析过程。用户也可选择公共解析服务,例如谷歌提供的 8.8.8.8/8.8.4.4,或 OpenDNS 提供的 208.67.222.222/208.67.220.220 等。

支持网络功能的应用程序(如浏览器)通过名为"存根解析器"(Stub Resolver)的组件与 DNS 系统交互。当应用程序或浏览器成功获取网站 IP 地址后,即可通过 HTTP 或 HTTPS 协议访问目标网站。

DNS 的命名空间

DNS 命名空间的层级结构有明确定义:DNS 名称由点号分隔的多个标签组成。例如,"www.example.com." 包含 4 个标签——"www"(叶子节点)、"example"(域名)、"com"(顶级域)以及代表根域的 "."。解析器查询时遵循最长标签匹配原则:若仅知晓根域信息,则从根域开始查询;若已缓存 ".com" 的信息,则直接从此层级启动查询流程。

全球由 12 家不同机构运营着 13 台根域名服务器。根区文件由 ICANN 下属机构 IANA 负责维护,并由运营其中两台根服务器的威瑞信(Verisign)公司对外发布。根区文件本质上是一份记录所有顶级域名权威服务器的清单,不包含其他扩展信息。例如,当根服务器收到 "www.example.com" 的查询请求时,它会返回一个指向".com"解析器的转介响应(referral)。该响应包含一组名为 NS(域名服务器)的记录,这些记录列出了掌握目标区域(此处指".com"域)更详细信息的权威服务器列表。

每个顶级域(TLD)的权威域名服务器都掌握其下属域名(如 example.com、cloudflare.com、google.com 等)的权威服务器信息。通过这种逐级向下的查询机制,最终会抵达能解答目标域名记录查询的权威服务器。

DNS(域名系统)是全球规模最大的分布式授权数据库。"授权"意味着每个域名可由不同管理机构维护信息,所有变更都会实时反映在 DNS 中。正因如此,解析器(resolver)绝不能永久保存已查询的记录。同样,高负载解析器也必须能够复用已获取的信息——这一机制通过为每条 DNS 记录设置 TTL(生存时间)来实现,该数值告知解析器记录的有效缓存时长。当解析器返回缓存数据时,会动态扣减 TTL 值以反映该数据在缓存中的留存时长。

中间人发起的 DNS 攻击

2014 年 3 月,土耳其政府决定在国内封锁推特。他们通过 DNS 层面实施封锁,要求本国互联网服务提供商将 twitter.com 的解析记录篡改为指向土耳其政府网站。民众很快识破这一做法,通过使用境外递归解析服务器成功绕过封锁,继续获取推特的真实地址。这一事件促使民众在建筑物和公共场所喷涂谷歌公共 DNS 服务器地址,形成独特的数字抗争景观。

土耳其这一事件揭示了 DNS 的首要安全隐患:缺乏认证机制。任何具备网络特权地位的参与者(例如控制着通信链路中间路由器的机构)都能篡改 DNS 记录,将其指向任意目标。这就是所谓的"路径劫持攻击",而 DNS 系统对此类攻击毫无招架之力。

Kaminsky 的攻击

2008 年,丹·卡明斯基揭露了一种针对 DNS 系统的攻击手段,该攻击能诱骗 DNS 递归解析器存储错误的 DNS 记录。一旦域名服务器缓存了错误响应,就会持续向所有查询者返回该错误信息,直至缓存条目过期(通常由 TTL 值决定)。这种被称为"DNS 投毒"的攻击使任意攻击者都能欺骗 DNS 系统,将网页浏览器(及其他应用程序)重定向到恶意服务器,从而实现流量劫持。

DNS 投毒攻击原理描述简单但实施困难,其攻击流程如下:

  1. 客户端向递归解析器发起查询
  2. 递归解析器向权威服务器转发查询
  3. 权威服务器响应递归解析器
  4. 递归解析器将最终答复返回客户端

卡明斯基攻击的核心在于利用 UDP 协议的无状态特性及对源 IP 地址的盲目信任。整个攻击流程中的请求与响应均通过包含收发双方 IP 地址的 UDP 数据包完成。理论上,任何主机都能伪造 UDP 报文中的源地址,伪装成合法来源发送数据。只要攻击者所处的网络未启用出站数据包过滤,就能构造伪造成权威服务器的 UDP 报文,并将其发送至递归解析器。

在上述请求中,第 3 条信息是最佳的攻击目标。因为递归解析器会接受第一个匹配查询的响应结果。所以只要你能比权威服务器更快给出应答,递归解析器就会把你的伪造响应当作正确答案——这就是 DNS 投毒攻击的核心原理:

  1. 选定你想劫持的域名
  2. 向递归解析器请求目标 DNS 记录
  3. 伪造大量 UDP 响应包冒充权威服务器,植入恶意解析记录(比如把 A 记录指向你控制的 IP 地址)

只要你的恶意伪造响应(恰好符合校验规则)比真实响应抢先到达,递归解析器就会采信你的记录,并按照 TTL 设置的时长缓存这个结果。之后所有查询这个被污染记录的用户,都会被引导到你控制的恶意服务器上。

实际操作起来可比听起来复杂多了,主要难点在于你得准确猜中以下关键信息:

  1. 那个 16 位的请求 ID 号
  2. 查询请求发往的权威服务器地址
  3. 发起查询的递归解析器地址
  4. 权威服务器接收查询时用的 UDP 端口号

当年卡明斯基刚提出这种攻击手法时,这些关键参数很容易被猜到或探测到,DNS 投毒简直防不胜防。不过现在情况好多了——请求 ID 随机化、端口号随机分配、源地址轮换这些防护措施层层加码,虽然不能百分百杜绝,但攻击门槛确实高了不少。但可别掉以轻心,DNS 缓存投毒至今仍是实打实的威胁,最近在 2014 年 9 月还曝出过真实案例。

这类攻击得以实施的根本原因在于:解析器无法验证收到的 DNS 记录是否真实可信。值得注意的是,若攻击者能够监听到递归解析器发出的查询流量,便掌握了伪造应答所需的所有信息(详见《连线》杂志 2014 年 3 月报道《量子攻击》http://www.wired.com/2014/03/quantum/)。

DNSSEC

DNS 安全扩展协议(DNSSEC)为 DNS 记录提供了防护机制,使解析器和应用程序能够验证接收数据的真实性。这一重大改进意味着所有 DNS 应答都将具备可验证的信任基础。

此前我们解释过 DNS 解析流程——从根域名服务器开始逐级向下查询(例如解析"www.example.com" 时,依次访问根服务器→".com"服务器→"example.com"服务器)。DNSSEC 的信任传递机制与此类似:以 DNS 根区作为终极信任锚点,通过层级递进的信任链验证所有 DNS 记录。这与 TLS/SSL 证书的信任链验证原理高度相似,但关键区别在于:TLS/SSL 依赖多个受信根证书机构,而 DNSSEC 的信任链顶端仅由互联网号码分配机构(IANA)管理的单一根密钥作为全球唯一信任源。

DNSSEC 的核心目的是为 DNS 记录的接收者提供一种可信的验证机制。它的关键创新在于引入了公钥加密技术,用以确保 DNS 记录的真实性。DNSSEC 不仅能让 DNS 服务器证明其返回记录的真实性,还支持声明某些记录不存在的能力。

DNSSEC 信任链本质上是一系列记录构成的验证体系,其中每条记录要么包含公钥,要么包含资源记录集的数字签名。这个信任链的源头是根区密钥(Root Key),由 DNS 根区运营机构负责维护管理。DNSSEC 的技术规范由互联网工程任务组(IETF)在 RFC 4033、RFC 4034 和 RFC 4035 这三份标准文档中明确定义。

有几种重要的新记录类型:

  • DNSKEY:公钥,用于对一组资源记录(RRset)进行签名。
  • DS(委派签名者):一个密钥的哈希值。
  • RRSIG(资源记录签名):对共享名称、类型和类的资源记录集(RRset)的签名。

DNSKEY 记录是一种加密公钥,可分为两种角色,可由不同的密钥或同一密钥处理:

  • KSK(密钥签名密钥): 用于对 DNSKEY 记录进行签名。
  • ZSK(区域签名密钥): 用于对该域名权威的所有其他记录进行签名。

对于给定的域名和查询类型,会返回一组答案。例如,若查询 cloudflare.com 的 A 记录,将获得一组 A 记录作为应答:

cloudflare.com.            285    IN    A    198.41.212.157
cloudflare.com.            285    IN    A    198.41.213.157

某个域名下特定类型的所有记录集合称为资源记录集(RRset)。RRSIG(资源记录签名)实质上是为 RRset 提供的数字签名。每个 RRSIG 都与一个 DNSKEY 相关联:DNSKEY 资源记录集由密钥签名密钥(KSK)进行签署,而其他所有记录则由区域签名密钥(ZSK)签署。通过 RRSIG,信任关系从 DNSKEY 传递至记录——若您信任某个 DNSKEY,即可信任由该密钥正确签署的所有记录。

然而,域名的密钥签名密钥(KSK)是由其自身签署的,这使得直接建立信任变得困难。解决方法是向上追溯至父级域(parent zone)进行验证——例如,要确认 example. Com 的 DNSKEY 有效性,必须向.com 的权威服务器查询。此时 DS 记录(委派签名记录)便发挥作用:它作为信任桥梁,将验证链条延伸至 DNS 的父级层级。

DS 记录本质上是 DNSKEY 的哈希值。在.com 顶级域中,会为每个已提交 DNSSEC 密钥信息的子域存储该记录。DS 记录作为.com 域资源记录集(RRset)的组成部分,同样配有对应的 RRSIG 签名——不过这次是由.com 的区域签名密钥(ZSK)完成签署。而.com 的 DNSKEY 资源记录集则由其密钥签名密钥(KSK)进行签名。

整个信任链的最终锚点是根域(DNS root)的 KSK DNSKEY。该密钥作为全球公认的权威凭证被广泛公开。

以下是 2010 年 8 月发布的根域名系统密钥签名密钥(DNSKEY root KSK),该密钥采用 base 64 编码并将持续使用至 2015 或 2016 年某个时间节点:

AwEAAagAIKlVZrpC6Ia7gEzahOR+9W29euxhJhVVLOyQbSEW0O8gcC jFFVQUTf6v58fLjwBd0YI0EzrAcQqBGCzh/RStIoO8g0NfnfL2MTJR kxoXbfDaUeVPQuYEhg37NZWAJQ9VnMVDxP/VHL496M/QZxkjf5/Efu cp2gaDX6RS6CXpoY68LsvPVjR0ZSwzz1apAzvN9dlzEheX7ICJBBtuA 6G3LQpzW5hOA2hzCTMjJPJ8LbqF6dsV6DoBQzgul0sGIcGOYl7OyQd XfZ57relSQageu+ipAdTTJ25AsRTAoub8ONGcLmqrAmRLKBP1dfwhY B4N7knNnulqQxA+Uk1ihz0=

通过遵循 DNSKEY、DS 和 RRSIG 记录构成的信任链回溯至根域,任何记录均可获得可信验证。

这些记录足以验证资源记录的完整性,但要证明某条记录不存在,则需要借助另外两种记录类型——NSEC 和 NSEC3 来实现。

当 DNS 权威服务器确认不存在与查询请求匹配的记录时,会通过特定方式响应此类请求:若查询的域名不存在,则返回状态码(RCODE)为 NXDOMAIN 的应答;若域名存在但请求的记录类型不存在,则返回空应答(NODATA)。

这些否定应答(如域名不存在或记录类型不存在)原本未经认证,可能像其他 DNS 响应一样被第三方伪造。DNSSEC 通过引入一种新型记录解决了这个问题——这种名为 NSEC 的记录能明确声明哪些域名存在,以及每个域名下存在哪些记录类型。经过 DNSSEC 签名的 NSEC 记录可被逐级验证直至根域。NSEC 记录通常用于填补区域内所有已存在记录之间的空白。虽然这会使区域内的记录数量近乎翻倍,但它使得权威域名服务器能够对所有查询(包括否定应答)返回经过数字签名的响应。例如,当查询一个不存在的域名时,服务器会返回与其相邻的两个有效域名之间的 NSEC 记录,通过密码学方式证明请求的域名确实不存在。

域名 ietf.org 使用了 NSEC 记录。当查询"trustee.ietf.org"时,会返回包含 IP 地址和 RRSIG 记录(数字签名)的肯定应答;而查询拼写错误的"tustee.ietf.org"时,则会返回经过签名的否定应答:"在 trustee.ietf.org 和www.ietf.org之间不存在任何域名",并附有对应的 RRSIG 签名记录作为证明。

域名 ietf.org 使用了 NSEC 记录机制。当查询 "trustee.ietf.org" 时,会返回一个包含 IP 地址和 RRSIG 记录的肯定应答。而查询拼写错误的 "tustee.ietf.org" 时,则会返回一个带 RRSIG 签名的否定应答:"在 trustee.ietf.org 和 www.ietf.org 之间不存在任何域名"。例如:

请求:

tustee.ietf.org/A

响应:

trustee.ietf.org.        1683        IN        NSEC        www.ietf.org. A MX AAAA RRSIG NSEC

这意味着按照字母顺序排序时,在 trustee.ietf.org 和 www.ietf.org 之间不存在任何域名,从而有效证明了 tustee.ietf.org 并不存在。

RFC5155 定义了一种通过 NSEC3 记录实现存在性否认的模糊化方法。NSEC3 采用类似的逻辑,但会对域名进行哈希处理。例如查询 examplf.com(字母 e 在 f 之前)时,会返回"在哈希值 A 和 B 之间不存在任何记录"的响应,其中 A 是字典序上最接近 examplf.com 哈希值的前一个哈希值,B 则是字典序上最接近的后一个哈希值。

结语

本文是介绍 Cloudflare 如何实现 DNS 及我们 DNS 规划系列文章的开篇。在后续文章中,我们将深入探讨 DNSSEC 的某些优势与不足,同时介绍 DNSSEC 的实用扩展功能(如 DANE),以及如何利用这些技术来保护网站安全,提供比证书颁发机构体系更强大的信任机制。我们还将通过采用率统计数据和发展趋势,分析该技术自标准化以来十年间取得的进展。

DNSSEC 是提升 DNS 可信度与完整性的重要工具,而 DNS 正是现代互联网的基石。截至 2014 年中,DNSSEC 的部署仍处于起步阶段,仅有不到 5% 的域名区域完成签名。尽管存在质疑声音,但其采用率正在持续增长——DNSSEC 正逐渐成为构建更安全、更可信互联网的核心工具,CloudFlare 将持续为其提供支持。

最后修改:2025 年 04 月 19 日
如果觉得我的文章对你有用,请随意赞赏