大约一周前,我在主域名上启用了 DNSSEC。这不是一个主要网站或任何东西——只是我用于电子邮件等的个人域名(TLD:com
;DNSSEC 算法 13;权威 DNS 提供商:Cloudflare)。
在过去 24 小时内,该域名已收到 15,605 次查询。作为响应,它已发出 15,601 个NOERROR
响应代码,总共 4 个NXDOMAIN
响应代码。
NXDOMAIN 响应为何仍然可能存在?什么可能生成这些响应?
就我个人而言,无论我尝试什么查询,都无法触发该代码,并且我的理解是 DNSSEC 至少在理论上应该完全消除此响应代码。
我错了吗?
答案1
总结
Cloudflare 托管域缺乏NXDOMAIN
响应是其特定 DNSSEC 实现(使用所谓的“黑色谎言”)的结果,而不是 DNSSEC 协议本身的设计;因此,对于其他执行 DNSSEC 的提供商,观察结果会有所不同。
初步问题
NXDOMAIN 响应如何仍然可能?
为什么它们不可能实现?无论是否使用 DNSSEC,如果您查询不存在的名称,都会得到NXDOMAIN
回复。
我的理解是 DNSSEC 至少在理论上应该完全消除此响应代码
为什么?你从哪里得到这种感觉?
具有启用 DNSSEC 的域的实时示例
icann.org
现在是否已启用 DNSSEC。如果我查询其下不存在的名称,则会得到NXDOMAIN
:
$ dig NS icann.org +short
b.icann-servers.net.
c.icann-servers.net.
ns.icann.org.
a.icann-servers.net.
$ dig @a.icann-servers.net does-not-exist-foobar.icann.org
; <<>> DiG 9.18.4 <<>> @a.icann-servers.net does-not-exist-foobar.icann.org
; (1 server found)
;; global options: +cmd
;; Sending:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 38891
;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
; COOKIE: 98228e9e0c5ef4e6
;; QUESTION SECTION:
;does-not-exist-foobar.icann.org. IN A
;; QUERY SIZE: 72
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 38891
^^^^^^^^
DNSSEC 是 DNS 的扩展,对于非验证解析器,即使域启用了 DNSSEC,答案也不会有所不同。因此所有返回代码的工作方式都相同。
关于 NSEC/NSEC3/RRSIG 的说明
它所发生的变化是,您可以看到是否添加+dnssec
到dig
(这并不意味着“激活 DNSSEC”,而是意味着“显示 DNSSEC 相关记录 - 那些是RRSIG
、NSEC
和NSEC3
- 因为它们通常不会显示),是AUTHORITY
在 的情况下的部分对或记录NXDOMAIN
给出了进一步的解释:NSEC
NSEC3
;; AUTHORITY SECTION:
icann.org. 1h IN SOA sns.dns.icann.org. noc.dns.icann.org. (
2022070670 ; serial
10800 ; refresh (3 hours)
3600 ; retry (1 hour)
1209600 ; expire (2 weeks)
3600 ; minimum (1 hour)
)
j93jujiqg7ge3616mub4r5bei85poet9.icann.org. 1h IN NSEC3 1 0 5 9714B5ACB8F7A193 (
J9HKD4G746GMUTGGUV6AM37GSJAD6NRR
A NS SOA MX TXT AAAA RRSIG DNSKEY NSEC3PARAM )
tdr1at6eafsrigdrlj6atpb2dge2aof0.icann.org. 1h IN NSEC3 1 0 5 9714B5ACB8F7A193 (
TE4FB4PVMU1GQNPG9P01ID48U1BTN2G4
A RRSIG )
lsrp57e1pe333jadkpdgh3v1i8vs80rd.icann.org. 1h IN NSEC3 1 0 5 9714B5ACB8F7A193 (
LT4I8S7OTQ7ACOSF73M7LHCIC7C1J17I
A RRSIG )
icann.org. 1h IN RRSIG SOA 7 2 3600 (
20220804192816 20220714153322 3425 icann.org.
NMcD1TeozFyCRDlmqFMoM/V/VmWQUmRNIH0/igPzdj2S
hemnQHeXDOudBxsUgE/DpSV4KHsgqLQKdgbQruqCO7Dt
iLK1bCLBZs38LdOadyJs3jWjjuJ9+mEnLXTsqMeeMllw
YFL6pPyo1TfChZm05KJ+DJNw0SHJw3MWBRtV4iI= )
j93jujiqg7ge3616mub4r5bei85poet9.icann.org. 1h IN RRSIG NSEC3 7 3 3600 (
20220724054620 20220703065347 58935 icann.org.
gmo0VP8k9Li9lutMA3uTrMfABMmFBN23GonYo72Twk9l
wGYqFvlU/naN0KKtEd3g+zOiYB0Jb1J1270Dveew/vYa
hTmeMYrwUbEt9gZYCvi74zm6Ss0cQ8uxJ5bZw70nZ7oU
LAtWYVGJMgupfjtne6021AJoLNB1CaMhFwo+TPo= )
tdr1at6eafsrigdrlj6atpb2dge2aof0.icann.org. 1h IN RRSIG NSEC3 7 3 3600 (
20220724101659 20220703045347 58935 icann.org.
hGsUeE4di9yFuDMq8ly1YQEs1OvOFAHVctOQrs6Poixl
STqcErjC20V2CI0YApX6SbiI8AP/dqMjBm3fZh91mtDf
aSrZypfScBEO/KVdlqbW9G+y8VR65ryjTAA7TZIzqN+z
7YyTAESWb8E7T4NCtQPPwYpjl/S9krbEGSiKfaw= )
lsrp57e1pe333jadkpdgh3v1i8vs80rd.icann.org. 1h IN RRSIG NSEC3 7 3 3600 (
20220724151521 20220703105347 58935 icann.org.
P9qwkFoGkCd+m3aDQkzF/g7SJfn/byt6d4zugLzRKuH1
rLmYZdlJNOC+fI1saCZySarsP9KavFSBzw6S9GMLobQJ
hTVpu1ZUkEP9BMOZo28eeRLrGvAbrVb7aB9CWl9TgUMc
2+s4nG87HTvD2TCJHmyPC1mIbBLYmJoa7iGLGiI= )
NSEC3
更复杂(不太人性化),因为它使用域名哈希值。但以上所有内容总结起来就是,我请求的名称不存在,因为它位于两个存在的名称之间(但由于经过哈希处理,无法立即看到),并且不存在通配符(这就是您有三条NSEC3
记录的原因)。RRSIG
记录签名为 1 NSEC3
,因此以上所有内容允许解析名称服务器确实仔细检查是否NXDOMAIN
合法,并且不是由某个路径攻击者引入的,因为所有NSEC3
和RRSIG
记录都符合预期。
使用 NSEC 案例的更简单示例
让我们使用启用了 DNSSEC 的域NSEC
来代替NSEC3
:根本身 :-)
如果我dig @g.root-servers.net foobar. +dnssec
现在这样做,我会得到NXDOMAIN
,同样是出于与上述相同的原因,并且该 TLD 不存在(还没有?)
但让我们看一下结果,特别是一条NSEC
记录:
foo. 1d IN NSEC food. NS DS RRSIG NSEC
这是来自名称服务器的肯定签名(有相应的RRSIG
记录)断言,告诉我foobar
区域中不存在,因为和都foo
存在food
,但中间不存在。并且根据 DNSSEC 排序规则,将在和之间foobar
进行排序,因此上述内容证明不存在。顺便说一句,它证明了许多其他名称不存在,并且某些解析器可以缓存此名称并在不请求任何内容的情况下得出答案。foo
food
foobar
NSEC
为什么?因为如果我知道 之间不存在任何东西foo
,food
我就会立即知道fooa
不存在,也不存在fooa42
或foobie
或fooccc
或类似的东西……
回到CloudFlare的具体案例
CloudFlare 实施“DNSSEC 善意谎言”和“黑色谎言”,参见https://www.cloudflare.com/dns/dnssec/dnssec-complexities-and-considerations/和https://blog.cloudflare.com/black-lies/出于他们自己的各种原因(部分原因是他们进行动态签名生成,他们RRSIG
在请求到来时生成记录,而不是提前生成记录;这是一种折衷,两种情况都有优点和缺点)。
那是什么意思?他们伪造了全部名称,因此几乎没有NXDOMAIN
。
让我们看一个例子:
$ dig dwewgewfgewfee-32cewcewcew-2284.cloudflare.com @ns3.cloudflare.com. +dnssec
; <<>> DiG 9.18.4 <<>> dwewgewfgewfee-32cewcewcew-2284.cloudflare.com @ns3.cloudflare.com. +dnssec
;; global options: +cmd
;; Sending:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9469
;; flags: rd ad; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 4096
; COOKIE: fd8d36048320c848
;; QUESTION SECTION:
;dwewgewfgewfee-32cewcewcew-2284.cloudflare.com. IN A
;; QUERY SIZE: 87
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9469
;; flags: qr aa rd; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; WARNING: recursion requested but not available
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;dwewgewfgewfee-32cewcewcew-2284.cloudflare.com. IN A
;; AUTHORITY SECTION:
cloudflare.com. 5m IN SOA ns3.cloudflare.com. dns.cloudflare.com. (
2282614227 ; serial
10000 ; refresh (2 hours 46 minutes 40 seconds)
2400 ; retry (40 minutes)
604800 ; expire (1 week)
300 ; minimum (5 minutes)
)
dwewgewfgewfee-32cewcewcew-2284.cloudflare.com. 5m IN NSEC \000.dwewgewfgewfee-32cewcewcew-2284.cloudflare.com. RRSIG NSEC
(我删除了RRSIG
记录)。
那么这说明了什么呢?首先:NOERROR
而不是NXDOMAIN
相反,所以解析器告诉我我查询的名称存在(但可能不适用于我询问的类型,A
即默认dig
类型,这是有效的,并且已知为,NODATA
但NOERROR
也没有内容,没有ANSWER
部分,就像名称存在但类型不存在时那样)。
该AUTHORITY
部分特别是该记录告诉我,(实际上是我要求的名称,所以不是前一个,只是我的)NSEC
之间没有名称,并且它可能看起来像一个奇怪的名称,但 1)完全有效(它不是一个有效的主机名,因为意味着字节值 0 必须像DNS 操作那样进行编码,但仍然是一个有效的域名,因为 DNS 规范中的域名可以是任意字节)和 2)是使用 DNSSEC 排序算法,“紧跟”我的名字之后的名称(所以基本上两个名称的范围不包括中间的任何其他名称)。dwewgewfgewfee-32cewcewcew-2284.cloudflare.com.
\000.dwewgewfgewfee-32cewcewcew-2284.cloudflare.com.
\000
\000
RRSIG NSEC
记录末尾的部分意味着名称上NSEC
没有记录类型,A
但有记录类型RRSIG
和NSEC
,这是有道理的,因为我正在查看NSEC
该名称的记录,而且由于我们在 DNSSEC 领域,当然有一个RRSIG
。
因此,这被称为“谎言”,因为名称服务器正在回复您:此名称存在,但此记录类型不存在。无论您请求哪种记录类型(除NSEC
和RRSIG
),名称服务器都会告诉您:“此名称不存在于此记录类型中”。最后,如果它不存在于任何记录类型中(除NSEC
和 之外RRSIG
),那么它(名称)实际上就像根本不存在一样,只是以不同的方式呈现,原因如下所述。
我建议阅读第二个链接,但它解释事情的要点是(我跳过了关于NSEC
/NSEC3
和通配符记录的全部要点,以及关于“最接近的接触”等的所有细节,但这些对于深入研究NSEC
某些东西很重要):
NSEC3 是该问题的一个“接近成功”的解决方案。虽然它确实使区域行走变得更加困难,但并非不可能。
(这就是为什么他们不使用NSEC3
和保留NSEC
但仍然需要另一种解决方案来避免遍历区域并因此枚举所有名称)
否定答案存在两个问题:
首先,权威服务器需要返回上一个和下一个名称。如您所见,这对于 CloudFlare 来说计算成本很高,而且如您已经看到的,它可能会泄露有关区域的信息。
第二,否定答案需要两个 NSEC 记录及其后续两个签名(或三个 NSEC3 记录和三个 NSEC3 签名)来验证一个名称的不存在。这意味着答案比它们需要的要大。
NXDOMAIN
因此,上面的部分就是为什么要避免使用和“模拟”它并获得成功(NOERROR
)但同时对任何查询(任何请求类型的名称+类型)做出负面回应的基本解释。
另一点,同样是 CloudFlare 特有的,即在他们的情况下很难计算“下一个”名称(因为NSEC
实际上给出了两个名称的“范围”,作为两个现有事物之间的链接),因此他们不使用存储中现有的真实下一个名称,而是根据 DNSSEC 算法计算最小的“下一个”,因此出现了上面带有\000.
前缀的奇怪名称,这个名称显然也不存在,因此如果您查询它,您将再次得到相同类型的答复,但这次NSEC
在右侧\001.
或\000.\000.
事实上列出了记录,等等……
再向下:
对于 NXDOMAIN,我们始终返回 \000.(缺失的名称)作为下一个名称,并且由于我们直接在缺失的名称上返回 NSEC,因此我们不必为通配符返回额外的 NSEC。这样,我们只需返回 SOA、SOA RRSIG、NSEC 和 NSEC RRSIG,并且我们不需要搜索数据库或预先计算动态答案。
所有这些所达到的目标是回复更小。这在 DNS 领域非常重要,因为存在各种碎片化问题。从他们的例子中,他们用黑色谎言将 1096 字节减少到 357 字节,减少了近 2/3,这是一项了不起的成就!
对于那些想要做同样事情的人来说,上述所有内容将来都可能成为“标准”,因为他们编写了一份文档,该文档有一天可能会成为 IETF RFC:https://datatracker.ietf.org/doc/html/draft-valsorda-dnsop-black-lies
但请注意,它会产生后果:
NXDOMAIN
是一个重要信号:各种其他内容都是在此基础上构建的,请参阅 RFC 8020“NXDOMAIN:下面真的什么都没有”和 RFC 8198“积极使用 DNSSEC 验证的缓存”,因此不再有此信号可能会产生副作用(并且更改其他递归解析器以尝试找出权威方是否在使用黑色谎言然后考虑它们并不是一个好主意,这将是脆弱的;这一点在上面的草案中已经进行了确切的讨论)- 它还会影响 ENT 或“空非终端”,其中名称必须存在于 DNS 树中,不是因为它附加了任何类型,而是因为它下面有名称;请参阅https://www.ietf.org/archive/id/draft-huque-dnsop-blacklies-ent-01.html有关该主题的更多详细信息
- 没有一个实现是没有错误的,DNSSEC 很复杂,而围绕 DNSSEC 的技巧则更加复杂;现在我不再确定,也找不到参考资料,但我认为一开始就有一个错误,返回的类型(在位图中
NSEC
)没有正确计算,因此破坏了一些东西。如果我确实找到了我认为我所看到的东西,我会尝试更新这个,但我可能是妄想(DNSSEC 很容易出现这种情况……);事实上,我认为这与观察结果有关,即他们所有最初的例子都在NSEC
最后一节中放入了更多的类型,而现在他们只放入了RRSIG
和NSEC
。参见https://indico.dns-oarc.net/event/40/contributions/899/attachments/862/1563/nsec-bitmaps.pdf有关NSEC
位图错误及其后果的实例
啊不,事实上我记得没错,这个NSEC
位图中的一个错误正是最近 Slack 中断的根源 :-),但这不是 Cloudflare 的错,而是 AWS Route53 的问题。请参阅https://www.potaroo.net/ispcol/2021-12/oarc36.pdf有关这些细节,但简而言之:
现在你可以用 NSEC 记录撒谎,[..] 但服务器绝对不应该做的是在 NSEC 记录中返回一个空的位向量。因为一些解析器(包括 Google 的公共 DNS 服务)会将空的 NSEC 位向量解释为声称该域名根本没有资源记录。这不是 Google DNS 的错误。这是对 DNSSEC 规范的完全合法的解释。Slack 遇到的问题是,当使用通配符条目形成响应并且未为通配符资源定义查询类型时,Route 53 服务器返回的 NSEC 响应带有几乎为空的 RR 类型位向量。这是 Route 53 实现中的一个错误。
所以,简而言之,撒谎有时确实会带来不良后果 :-)(和/或:DNSSEC 很复杂,DNS 中的通配符也会引起各种各样的复杂情况;事实上 DNSSEC + 通配符 + CNAME 记录就像是世界末日的 3 个确切迹象......)。
这只是一种做法,其后果(几乎没有 NXDOMAIN 响应)绝对不是协议(DNSSEC)的结果,而只是其实施的结果。所以不要认为这是理所当然的,其他提供商的情况会有所不同。但作为区域的所有者或用户,这真的会改变什么吗?没有那么多。你为什么这么担心NXDOMAIN
响应 :-)?
附言:
答案2
在 Cloudflare 的特殊情况下,他们的权威服务器仍然会对NXDOMAIN
未设置位DO
(不请求 DNSSEC 记录)的查询生成响应。
NXDOMAIN
他们也可能返回其他情况,也可能不返回。
$ dig +norecurse nxdomain.cloudflare.com @ns6.cloudflare.com
; <<>> DiG 9.19.2-1+ubuntu20.04.1+isc+1-Ubuntu <<>> +norecurse nxdomain.cloudflare.com @ns6.cloudflare.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NXDOMAIN, id: 49384
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;nxdomain.cloudflare.com. IN A
;; AUTHORITY SECTION:
cloudflare.com. 300 IN SOA ns3.cloudflare.com. dns.cloudflare.com. 2282614227 10000 2400 604800 300
;; Query time: 3 msec
;; SERVER: 2400:cb00:2049:1::a29f:506#53(ns6.cloudflare.com) (UDP)
;; WHEN: Fri Jul 15 04:33:54 UTC 2022
;; MSG SIZE rcvd: 96
$ dig +dnssec +norecurse nxdomain.cloudflare.com @ns6.cloudflare.com
; <<>> DiG 9.19.2-1+ubuntu20.04.1+isc+1-Ubuntu <<>> +dnssec +norecurse nxdomain.cloudflare.com @ns6.cloudflare.com
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 42126
;; flags: qr aa; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags: do; udp: 1232
;; QUESTION SECTION:
;nxdomain.cloudflare.com. IN A
;; AUTHORITY SECTION:
cloudflare.com. 300 IN SOA ns3.cloudflare.com. dns.cloudflare.com. 2282614227 10000 2400 604800 300
nxdomain.cloudflare.com. 300 IN NSEC \000.nxdomain.cloudflare.com. RRSIG NSEC
cloudflare.com. 300 IN RRSIG SOA 13 2 300 20220716053359 20220714033359 34505 cloudflare.com. VI/f0QNfsim677htUOQ4yZxFK41C2jzhXsF+T5/oFiQtwPIm3m3gLr3Y WB8NUpsje9v+ARFcQUPqM6SKGJ7CJQ==
nxdomain.cloudflare.com. 300 IN RRSIG NSEC 13 3 300 20220716053359 20220714033359 34505 cloudflare.com. 9BuyhrKElvzvzv5w4eOJRikcX3eFUOr9z6IYOgWjwez2tfVaR+P8x9kN uSYporOFom3KxhS3krcq9zbDO7kxdw==
;; Query time: 3 msec
;; SERVER: 2400:cb00:2049:1::a29f:506#53(ns6.cloudflare.com) (UDP)
;; WHEN: Fri Jul 15 04:33:59 UTC 2022
;; MSG SIZE rcvd: 363
(设置DO
并不能保证解析器将验证响应。例如,非验证解析器可能会请求 DNSSEC 记录,以便可以将它们传递给验证客户端,或者测试中的部署可能会记录错误但接受虚假响应。)