DNSSEC 的复杂性和考虑因素

dnssec logo

DNSSEC 是对 DNS 的一种扩展:它为 DNS 记录提供一个信任机制这是对该互联网核心组成部分之一的重大改变。在本文中,我们研究 DNSSEC 带来的一些问题,以及 Cloudflare 为减少这些问题可能产生的任何负面影响做了什么工作。主要问题是区域内容暴露、密钥管理以及对 DNS 反射/放大攻击的影响。

dnssec logo

区域内容暴露

DNS 被分割成更小的部分,称为区域。一个区域通常从一个域名开始,并包含与子域有关的所有记录。每个区域由一个经理管理。例如,cloudflare.com 是一个包含 cloudflare.com 及其子域(例如 www.cloudflare.com, api.cloudflare.com)所有 DNS 记录的区域。

在 DNS 中没有子域的目录服务,所以如果想知道 api.cloudflare.com 是否存在,您就必须查询 DNS 服务器,该 DNS 服务器最终会查询 cloudflare.com 是否存在 api.cloudflare.com。而 DNSSEC 则不是这样。在某些情况下,启用 DNSSEC 可能会暴露出原本被掩盖的区域内容。并非每个人都关心子域的保密性,区域内容可能已经很容易被猜到,因为大多数网站都有一个 ‘www’ 子域;然而,子域有时被用作登录门户或其他网站所有者希望保持私密的服务。某网站所有者可能不想暴露 “secretbackdoor.example.com”,以保护该站点免受攻击。

x ray specs

DNSSEC 会暴露子域的原因与区域的签名方式有关。一直以来,DNSSEC 被用来为静态区域签名。静态区域是给定域的完整记录集。DNSSEC 签名记录是在一个中心位置使用密钥签名密钥 (KSK) 和区域签名密钥 (ZSK) 创建的,并被发送到权威服务器上发布。该记录集让权威服务器能够回答任何被问到的问题,包括关于不存在的子域的问题。

DNSSEC 保证每个应答都是经过签名的,这不同于标准 DNS:在某个子域不存在时,服务器返回一个未签名的 NXDOMAIN(不存在的域)响应。这是通过一个特殊记录实现的,即作为不存在证明的 NextSECure (NSEC) 记录。NSEC 记录可以用来表示:“在子域 X 和子域 Y 之间没有子域”。通过填补区域内每个域之间的空白,NSEC 提供了一种用静态记录来应答任何查询的方法。NSEC 记录还列出了每个名称存在哪些资源记录类型。

对于静态签名区域,根据定义,存在固定数量的记录。由于每个 NSEC 记录都指向下一个记录,这就形成了一个涵盖所有子域的 NSEC 记录的有限 "环"。任何人都可以逐个查看 NSEC 记录,直到知道所有的子域。这种方法可以用来揭示该区域中的所有名称——从而可能暴露内部信息。

假设有一个名为 example.com、支持 DNSSEC 的区域,其子域为 public.example.com 和 secret.example.com。添加 NSEC 记录将暴露所有子域的存在。

查询 example.com 的 NSEC记录,结果如下:

example.com.NSEC public.example.com.A NS SOA TXT AAAA RRSIG NSEC DNSKEY

查询 public.example.com 得到以下 NSEC 记录:

public.example.com. NSEC secret.example.com.A TXT AAAA RRSIG NSEC

查询 secret.example.com 给出以下 NSEC 记录:

secret.example.com.NSEC example.com.A TXT AAAA RRSIG NSEC

第一个针对 top/apex 区域,回答说名称 “example.com” 存在,下一个名称是 “public.example.com”。public.example.com 的记录显示,下一个名称是 “secret.example.com”,暴露了一个私密子域的存在。“secret.example.com” 说下一条记录是 "example.com",完成了子域的链。因此,通过数个查询,任何人都可以知道该区域的完整记录集。

技术上而言,DNS 记录不应该是秘密的,但在实践中,它们有时被认为是秘密的。子域被用来保持某些内容(如公司的登录页面)私密已有一段时间,突然暴露区域文件的内容可能出乎意料且不被重视。

在 DNSSEC 之前,发现某个区域内名称内容的唯一方法是进行查询,或者试图从一个权威服务器上执行该区域的传送。区域传送 (AXFR) 经常被阻断。作为 NSEC 替代方案的 NSEC3 是为解决区域枚举问题而推出的,但即使是 NSEC3 也可以用来揭示子域的存在。

dnssec nsec stat

.ch 下的大多数域名使用 NSEC3

NSEC3 记录类似于 NSEC 记录,但是,对于答案不存在的查询, NSEC3 提供签名的域名空白范围哈希值,而非签名的域名空白范围本身。这样做是为了防止区域枚举。因此,包含 “example.com” 的区域的 NSEC3 链和 "www.example.com" 可能是(清晰起见,每个 NSEC3 记录显示为 3行):

231SPNAMH63428R68U7BV359PFPJI2FC.example.com。NSEC3 1 0 3 ABCDEF
NKDO8UKT2STOL6EJRD1EKVD1BQ2688DM
A NS SOA TXT AAAA RRSIG DNSKEY NSEC3PARAM
NKDO8UKT2STOL6EJRD1EKVD1BQ2688DM.example.com。NSEC3 1 0 3 ABCDEF
231SPNAMH63428R68U7BV359PFPJI2FC
A TXT AAAA RRSIG

其中

231SPNAMH63428R68U7BV359PFPJI2FC
example.com
的加盐哈希值,
NKDO8UKT2STOL6EJRD1EKVD1BQ2688DM
www.example.com
的加盐哈希值。 这让人想起了密码数据库的工作方式

NSEC3 记录的第一行包含了经过哈希后的区域“名称”,第一行的最后两个参数 "3 ABCDEF" 是哈希的轮数和用于哈希的随机数。“1 0” 代表摘要算法(1 表示SHA-1)和该区域是否使用 Opt-out(0 表示否)。第二行是 "区域内的下一个哈希名称",第三行列出该名称的类型。你可以看到第一条 NSEC3 记录的 “下一个名字” 与第二条 NSEC3 记录上的名称相匹配,该记录上的 “下一个名字” 完成了链条。

对于 NSEC 枚举,你可以通过开始猜测域中可能的名称来创建完整的域列表。如果该区域有大约 100 个域名,则需要大约 100 个请求来枚举整个区域。使用 NSEC3,当你请求一个不存在的记录时,会返回一个签名的 NSEC3 记录,并按哈希值的字母顺序提供下一个存在的区域。检查下一个查询名称候选者是否符合其中一个已知的空白范围,这样任何人都可以通过大约 100 次查询发现完整的链条。有很多工具可以为你进行上述计算,包括 nmap 的一个插件。

有了该区域全部有效名称的哈希值后,即可使用字典攻击来找到真实的名称。短的名称很容易被猜到,通过使用字典,较长的名字可以被显示为存在,而不必用猜测来淹没权威名称服务器。像 HashCat 这样的工具让软件很容易做到这一点,而比特币的流行也大大降低了哈希专用硬件的价格。加密哈希计算设备的作坊式服务产业正在蓬勃发展。特斯拉密码破解器(如下)只是这些现成设备的一个例子。

Tesla cracker

特斯拉破解器

因为哈希法成本低廉,在按设计使用 NSEC3 时,区域私密性仅略有改善;名称的受保护程度与其不可猜测性成正比。

简而言之,NSEC 就像暴露了明文密码,而 NSEC3 就像暴露了一个 Unix 风格的密码文件。这两种技术都不是很安全。如果使用 NSEC3 ,子域的私密性取决于其猜测难度。

这个漏洞可以通过 RFCs 4470 和 4471 (https://tools.ietf.org/html/rfc4470https://tools.ietf.org/html/rfc4471) 中介绍的“DNSSEC 善意的谎言” 技术来缓解;这是 Dan Kaminsky 为演示目的而实施的。当收到对一个不存在的域名的查询时,不是提供下一个真实域的 NSEC3 记录,而是按字母顺序提供下一个哈希的 NSEC3 记录。这并没有破坏 NSEC3 的保证,即在 NSEC3 应答和问题之间没有哈希值按字典顺序符合的域。

只有当签名可以在回答查询时实时计算出来,才能实施 NSEC3 或 NSEC “善意的谎言” 技术。传统上,用于 DNS 解析的静态区域记录是离线创建的,所有带有签名的记录都存储在一个区域文件中。然后,该文件被在线 DNS 服务器读取,使其能够回答有关该区域的问题。

Cloudflare 的 DNSSEC 实施利用 ECDSA 的高效签名生成,对 DNSSEC 记录进行实时签名。

密钥管理

DNSSEC 被设计为在各种模式下运行,每种模式都提供不同的安全、性能和便利性权衡。实时签名解决了区域内容暴露的问题,但导致不太安全的密钥管理。

最常见的 DNSSEC 模式是静态区域的离线签名。这样一来,通过将私钥保存在不与网络连接的机器上,可以有效保护签署系统免受外部威胁。当 DNS 信息不经常变化时,这种运行模式效果良好。

另一种常见的运行模式是集中式在线签名。如果你在限制访问的专用 DNS 签名系统中为数据进行签名,则允许 DNS 数据快速变化并发布。一些运营商在其主 DNS 服务器上运行 DNS 签名。就像静态区域的离线签名一样,这种模式遵循中央签名模式,即单一(或复制的)的中央签名者进行所有的签名操作,数据从它传播到实际的权威 DNS 服务器。

一种更激进的模式是,允许实际的权威 DNS 服务器在需要时对数据进行实时签名,这允许多种新的功能,包括在应答产生的地方签名的地理依赖信息。缺点是,现在密钥材料存储在多台直接接入互联网的不同机器上。在边缘进行实时签名会引入新的问题,如密钥分配,并对节点提出额外的计算要求。

最近,一个被称为 Heartbleed 的缺陷被发现,它在服务器应用程序中打开了一个重大的安全漏洞。它是 OpenSSL 中的一个编码错误造成的,后者导致一个远程内存泄露漏洞。这个漏洞允许远程攻击者从面向互联网的服务器上提取加密密钥。当密钥被用于 DNSSEC 实时签名等活动过程中时,远程内存暴露缺陷只是对私钥安全的众多威胁之一。一台机器在互联网暴露越多,攻击手段就越多。离线签名系统暴露给此类威胁的窗口要小得多。

保持密钥安全的一种方法是使用硬件支持的解决方案,如硬件安全模块 (HSM)。这种方式的主要缺点是成本——HSM 非常昂贵(而且速度慢)。运行地理上分散以接近客户的 DNS 服务器时,这是最棘手的问题之一。在每个服务器上运行 HSM 不仅成本高昂,而且存在法律方面的问题

另一个保护密钥不被远程泄露的解决方案是将加密操作转移到系统的组件中。这种情况下,可以转移加密的自定义 DNS 服务器就有了用武之地。

DNSSEC 的密钥管理类似于 TLS 的密钥管理,也存在类似的挑战。今年早些时候,我们推出了 Keyless SSL ,以帮助提高 TLS 的密钥安全性。我们正在考虑扩展 Keyless SSL,为 DNSSEC 实时签名提供远程密钥服务器的优势。

反射/放大攻击威胁

运行权威 DNS 服务器的运营商经常担心服务器会被用作恶意分布式拒绝服务(DDoS) 攻击的渠道。这是因为 DNS 使用 UDP 这种无状态协议。

在 TCP 中,每个连接都以三方握手开始。这可以确保在开始连接之前,双方的 IP 地址是已知和正确的。在 UDP 中没有这样的握手:信息只是直接发送到一个 IP 地址,且其“来源” IP 地址未经验证。 如果攻击者能够制作一个 UDP 数据包发给服务器,说 “嗨,来自 IP X ”,服务器一般会通过发送 UDP 数据包给 X 来回应。将 X 设为受害者的 IP 地址而不是发送者的 IP 地址,这被称为 UDP “欺骗”。通过欺骗受害者,攻击者可以使响应 UDP 请求的服务器用 "反射 "流量淹没受害者。这同样适用于权威服务器和开放递归解析器。

DNSSEC 也通过 UDP 工作,对 DNS 查询的回答可能非常长,包含多个 DNSKEY 和 RRSIG 记录。这是一个对攻击者有吸引力的目标,因为它允许他们 “放大”其反射攻击。如果向名称服务器发送少量的欺骗性 UDP DNSSEC 请求,受害者将收到大量的反射流量。有时这足以使受害者的服务器不堪重负,并导致拒绝服务。

从根服务器查询一个不存在的顶级域名,返回的响应约为 100 字节,同一查询的签名应答约为 650 字节,即放大系数为 6.5。根服务器使用 1024 比特的 RSA 密钥进行签名,并使用 NSEC 处理否定应答。在使用以 1024 位密钥签名的 NSEC3 的顶级域名服务器查询一个不存在的域名,将产生约 10 的放大系数。还有一些查询可以产生更高的放大系数,最有效的是 "ANY "查询。

像许多服务一样,DNS 也可以通过 TCP 工作。有一个 "截断 "标志,可以发回给解析器以表明要求 TCP。这将解决 DNS 反射问题,但代价是降低 DNS 请求的速度。这个解决方案目前并不实用,因为 16% 的解析器不遵循 TCP 截断标志,且 4%的解析器不尝试第二个服务器

另一个减少响应大小的选择是使用椭圆曲线数字签名算法 (ECDSA) 密钥,而非传统 RSA 密钥。ECDSA 密钥比同等强度的 RSA 密钥小得多,所产生的签名也小得多,使 DNSSEC 的响应小得多,从而降低了放大系数。Google 公共 DNS 在 2014 年底增加了对 ECDSA 的支持。之后其他几个公共 DNS 也纷纷跟进。

对 TCP 和 ECDSA 的支持仍然落后于一般的 DNSSEC 支持,因此可以使用传统的反滥用方法来代替。这包括 资源速率限制 (RRL) 和其他启发式方法。

为了防止反射攻击,Cloudflare 正在研究一种多管齐下的方法。首先,通过使用我们目前在 DNS 服务器中使用的攻击识别启发式和反滥用技术,其次,通过减少 DNSSEC 响应的放大系数。降低最大放大系数的方法包括:只通过 TCP 回复 “ANY ”请求,尽可能使用较小的 ECDSA 密钥,以及减少密钥滚动更新的频率。

结论

Cloudflare 意识到 DNSSEC 在区域私密性、密钥管理和反射/放大风险方面带来的复杂性。通过智能的工程决策,实施运营控制,DNSSEC 的危险是可以预防的。

设置 Cloudflare 很容易



在不到 5 分钟内建立域名。保留您的托管服务提供商。 不需要更改代码。


深受数百万互联网资产的信赖

Logo doordash trusted by gray
Logo garmin trusted by gray
Logo 23andme trusted by gray
Logo lending tree trusted by gray
NCR logo
Thomson Reuters logo
Logo zendesk trusted by gray