第三章:检查DNSSEC

您已经看到了不同类型的记录,并对信任链的工作原理有了基本的了解,但没有什么能取代对现实世界实现的观察。DNS信息是公开的,因此我们可以研究其他域如何实现DNSSEC。

首先配置缓存解析器以验证DNSSEC,然后我们将检查各种输出。

第三章:检查DNSSEC客户端和 DNSSECDNS故障排除工具解析程序配置dig(1) 要素DNS错误挖掘DNSSECDNSSEC与权威服务器禁用验证

客户端和 DNSSEC

大多数桌面系统都有一个存根解析器(stub resolver)——它们将DNS查询发送到缓存递归名称服务器,但不处理响应或缓存它们。他们不会自行验证DNSSEC。如果本地递归名称服务器声称DNS响应已签名,那对他们来说就足够了。

如果攻击者位于缓存名称服务器和客户端之间的网络上,他们可能会欺骗该递归服务器的结果。技术上最正确的解决方案是让存根解析器验证DNSSEC,但这还没有成为标准。

一些应用程序正在通过使用DNS over TLS(DoT)或DNS over HTTPS(DoH)安全地联系缓存解析器来解决缺少存根解析器DNSSEC验证的问题。我们将在第9章讨论这些。

如果您希望Unix工作站验证DNSSEC,请启用本地名称服务器并将其配置为仅接受来自本地主机的查询。一些Linux确实在桌面上验证DNSSEC。

DNS故障排除工具

客户端工具不会验证DNSSEC,但您需要一个客户端来查询验证解析器。我们将重点介绍使用最广泛的DNS工具 dig(1) 。它由BIND的作者开发,通常符合标准。如果您是dig的常规用户,请确保您没有任何选项可以在 .digrc 中隐藏调试输出。

另一个流行且可靠的工具是由NLNet Labs开发的 drill(1) ,正是这些人给我们带来了Unbound和NSD。命令行选项与 dig 不同,但如果你对 drill 很熟悉,就没有理由切换。

排除DNS故障时,避免使用 host(1)nslookup(1)host 命令用于非常简单的检查,缺乏 digdrill 的细节和自由裁量权(discretion)。 nslookup 命令已被弃用、放弃、复活、杀死、重建、重新实施、重新放弃、部署,被委托给某些骇人听闻的村庄外的一家废弃工厂,被判犯有一项移动违规行为和二百七十四项恶意逗留罪,并被集成到Microsoft Windows中。(The nslookup command has been deprecated, abandoned, resurrected, slain, rebuilt, re-implemented, re-abandoned, deployed, consigned to an abandoned factory outside the village of Something Awful, found guilty of one moving violation as well as two hundred seventy-four counts of Malicious Lingering, and integrated into Microsoft Windows.)我无法判断您正在使用的nslookup的无数版本中的哪一个,也无法判断该实现的质量。我可以告诉你,一些声称可以验证DNSSEC的nslookup其实并没有实现此功能。不要使用它。

还有其他工具。BIND 9.10引入了 delv(1) ,这是一种支持DNSSEC的下一代 dig(1) 。Knot DNS提供 kdig(1) ,Unbound有 unbound-host(1) 。只要它不是 host(1)nslookup(1) ,就使用对您最方便的工具。

解析程序配置

大多数解析器都可以通过一个简单的选项、复选框或其他简单的切换来启用DNSSEC验证。BIND的现代版本默认执行DNSSEC验证,但随着这些知识不断从我的脑海中消失,我更喜欢在 named.conf 中明确声明支持。

将此语句放入全局选项中,然后重新加载 named(8)

验证DNSSEC需要使用 dig(1) 等客户端。

dig(1) 要素

Dig是检查DNS数据最常用的工具,因此我将在详细的示例中使用它。像 drill 这样的工具以不同的格式显示相同的信息,所以如果你喜欢另一种工具,请遵循这些概念,而不是确切的格式和选项。配置 /etc/resolv.conf 以指向您的验证解析器。

让我们运行一个基本查询,并从DNSSEC的角度研究结果。

我们首先看到我们使用的dig版本(9.16.16)和查询的主要主题。Dig的版本号与其附带的BIND版本相匹配。命令行上使用的任何其他选项也会显示在此处。基本DNS在UDP上运行,因此DNS使用id号来匹配对查询的响应。

HEADER 行声明dig正在执行什么类型的操作,以及DNS服务器是否返回错误。此特定请求是QUERY,NOERROR的状态意味着服务器为您提供了答案。NOERROR并不意味着答案是新的、权威的,或者不会从缓存中过期。它只是表明它有答案。

flags 行提供了有关查询的具体详细信息。如果你正在调试DNS,更不用说DNSSEC了,这些标志就是你的新伙伴。他们确切地说明了发生了什么。您将看到的标志包括 qraardraadcd

我们的示例有标志 qrrdraad 。这是对查询的响应。我们要求递归,递归是可用的。最后,这是一个DNSSEC验证的响应。

QUERY条目显示了我们的要求。我们发送了一个查询。

ANSWER字段显示了我们收到了多少回复。在这里,我们得到一个答案。如果有多条记录,正如您查询“any”记录时常见的那样,记录数量将显示在此处。如果它为零,则您要查找的记录类型不存在。

ADDITIONAL字段表示存在额外内容。

接下来的几行用于扩展DNS(Extended DNS —— EDNS),或使用较大UDP数据包的DNS。我们使用的是扩展DNS的版本0。到目前为止,只定义了一个 flagdo ,用于DNSSEC OK。当客户端专门请求DNSSEC验证时,它会被设置,在正常查询中不会出现。最后,我们看到客户端和服务器之间的网络可以处理多达4096字节的UDP数据包。这已经足够了。

如果您正在运行支持RFC 8914的现代dig,并查询具有相同支持的递归服务器,您将在EDNS语句下方看到任何扩展DNS错误(extended DNS errors —— EDE)。如果存在,这些错误将确切地告诉您名称服务器拒绝响应的原因。

在 Question 部分,dig重复查询。

最后,答案。Dig为您的查询提供了完整的RRSet。主机 mwl.io 只有一个IP,所以你会得到一个答案。我们还可以获得有关查询执行方式和处理位置的调试信息。

如果要查看区域中的DNSSEC信息,请添加 +DNSSEC 标志。我还添加了 +nocomments 来删除不必要的细节。

RRSIG记录的存在表明此区域已使用DNSSEC签名。然而,仅仅因为区域被签名并不意味着你的递归服务器验证了答案。只有广告标志的存在表示验证。

如果你想看到DNSSEC记录存在,但不关心哈希和密钥的长字符串,请添加 +nocrypto 标志。

DNS错误

在本例的HEADER部分, status 字段显示NOERROR。dig出去了,找到了数据,并把它反馈给了我们。一切正常。也许我们得到了一个有用的答案。也许我们没有。但这个系统奏效了。状态错误表示系统不工作。

您可能会看到SERVFAIL的状态。名称服务器没有对此查询的缓存响应,无法从权威服务器获取响应。传统上,这意味着权威服务器要么停机,要么配置错误。但是,当一个区域具有DNSSEC时,当您的名称服务器收到答案但无法验证时,您将收到SERVFAIL。

如果您要查找的特定记录不存在,并且该名称不存在,则名称服务器将返回NXDOMAIN。这是一份权威声明,表明你问的具体问题不存在。没有主机 www2.mwl.io ,如果你要求它,我的权威服务器会说“不,NXDOMAIN。”

NXDOMAIN不同于没有所需类型记录的权威答案。还记得响应早期的ANSWER字段吗?您可能会得到一个权威的答案,说NOERROR,但答案为0。这表示存在具有该名称的记录,但不是您请求的排序。假设我要求提供 www.mwl.io 的MX记录:

没有错误,但我的查询没有答案。没有MX记录,但A和AAAA记录确实存在。Dig说“我能找到记录,但不是你想要的那种。”这并不意味着主机 www.mwl.io 没有收到邮件,只是它没有自己的MX记录。传入邮件将使用该区域的MX记录。

2020年10月,RFC 8914定义了各种新的DNS错误消息和添加更多错误消息的可扩展方法。这些错误包括“DNSSEC虚假”(DNSSEC Bogus)和“伪造答案”(Forged Answer)等消息,这将降低诊断DNS问题的难度。他们将在未来几年出现。

挖掘DNSSEC

要查看区域的DNSSEC信息,请添加 +dnssec 选项。在这里,我使用验证解析器检查 isc.org 上的DNSSEC记录。由于这些人是DNSSEC专家,我希望他们的区域能够正常工作。

两个选项有助于使输出更清晰。添加 +multi 将输出拆分为多行。 +nocrypto 选项不会隐藏DNSSEC记录,但会省略您可能无论如何都不想读取的关键信息。

我们收到了 ad 标志,因此这是经过身份验证的数据。答案已通过DNSSEC验证。进一步向下查找签名,如RRSIG(资源记录签名)记录所示。

如果验证解析器无法验证RRSIG记录,则返回SERVFAIL错误。对于最终用户来说,这似乎是主机从互联网上消失了。这样的区域被称为伪区(bogus)。我在第6章中展示了各种故障以及如何诊断它们。

如果您请求,非验证解析器将显示区域的DNSSEC记录,但它不会验证该签名。这就是非验证解析器非验证的原因。即使签名无效,非验证解析器也总是返回权威服务器为该区域提供的任何数据。或者,如果你愿意的话:非验证解析器的行为与往常一样。

DNSSEC与权威服务器

向ISC的权威服务器询问 isc.org 区域并检查标志。

这是该区域的权威服务器,但其响应不包括 ad 标志。你确实会得到 aa 标志,它代表权威的答案。这个直接来自消息来源的权威答案不知何故没有经过验证。直接来自主名称服务器的响应不应该是加密安全的吗?

直接来自权威服务器的权威答案不应是经过身份验证的数据。为您计算DNSSEC验证不是权威名称服务器的工作。这是验证解析器的工作。权威服务器通过提供签名供他人验证来完成其工作。

将解析器与权威服务器分离是强烈推荐的最佳实践。不要试图通过在权威服务器上测试验证来排除区域上的DNSSEC故障,否则将无法正常工作。

禁用验证

当权威名称服务器被破坏时,以及当DNSSEC验证失败时,您的解析器将返回SERVFAIL。在进行故障排除时,您必须能够区分这两种类型的错误。找出错误类型的最简单方法是使用 +cd 选项禁用DNSSEC验证。

我建议您在实际排除故障之前,先看看这在测试环境中是如何工作的。Comcast为此提供了域名 dnssec-failed.org 。在这个域名上运行dig。

如预期的那样,SERVFAIL错误,没有其他结果。现在,在禁用检查的情况下尝试相同的查询。

禁用DNSSEC时收到响应表示域的签名无效。

现在您可以检查DNSSEC数据了,让我们弥补权威名称服务器中的一个弱点。