如果我的 DNS 记录中有主机example.com
和,但没有任何记录,这在某些情况下是否会导致问题,或者出于某种原因,这是不好的风格或礼仪?我已经像这样设置了 Web 服务器,一切似乎都运行良好,但我只是想检查一下我是否遗漏了什么。leaf.intermediate.example.com
example.com
intermediate.example.com
答案1
TL;DR:是的,中间子域名需要存在,至少在查询时,根据 DNS 的定义;但它们可能不存在于区域文件中。
首先要消除的一个可能混淆;“空非终端”的定义
您可能混淆了两件事,其他答案似乎也一样。即查询名称时发生的情况以及您如何配置名称服务器和区域文件的内容。
DNS 是分层的。任何叶节点的存在,指向它的所有组件都必须存在,也就是说,如果查询它们,负责的权威名称服务器应该无错误地回复它们。
正如解释的那样RFC 8020(这只是对一贯规则的重复,但一些 DNS 提供商需要提醒),如果对于任何查询,权威名称服务器回复 NXDOMAIN(即:此资源记录不存在),则意味着此资源“下方”的任何标签也不存在。
在您的示例中,如果对的查询intermediate.example.com
返回NXDOMAIN
,则任何适当的递归名称服务器都会立即回复NXDOMAIN
,leaf.intermediate.example.com
因为如果其中的所有标签都不作为记录存在,则该记录就不可能存在。
这在之前的RFC 4592关于通配符(与此无关):
域名空间是树结构。树中的节点要么
拥有至少一个 RRSet,要么有共同拥有
至少一个 RRSet 的后代。只有当节点有后代时,它才可能没有 RRSet
;此节点是空非终端。没有后代的节点为叶节点。不存在空叶节点。
.US 域名实例
让我们从历史上具有大量标签的 TLD 中选取一个实际示例,即.US
。选择网上的任意示例,让我们使用www.teh.k12.ca.us
。
当然,如果您查询此名称,甚至teh.k12.ca.us
可以返回A
记录。这里没有结论可以满足我们的目的(中间甚至有一个 CNAME,但我们不关心它):
$ dig www.teh.k12.ca.us A +short
CA02205882.schoolwires.net.
107.21.20.201
35.172.15.22
$ dig teh.k12.ca.us A +short
162.242.146.30
184.72.49.125
54.204.24.19
54.214.44.86
现在让我们进行查询k12.ca.us
(我没有查询它的权威名称服务器,但这实际上不会改变结果):
$ dig k12.ca.us A
; <<>> DiG 9.11.5-P1-1ubuntu2.5-Ubuntu <<>> k12.ca.us A
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 59101
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1480
;; QUESTION SECTION:
;k12.ca.us. IN A
;; AUTHORITY SECTION:
us. 3587 IN SOA a.cctld.us. hostmaster.neustar.biz. 2024847624 900 900 604800 86400
;; Query time: 115 msec
;; SERVER: 127.0.0.10#53(127.0.0.10)
;; WHEN: mer. juil. 03 01:13:20 EST 2019
;; MSG SIZE rcvd: 104
我们从这个答案中学到了什么?
首先,这是成功的,因为状态是NOERROR
。如果是其他情况,具体来说,NXDOMAIN
则teh.k12.ca.us
,也www.teh.k12.ca.us
不会存在。
其次,ANSWER 部分为空。没有A
记录k12.ca.us
。这不是错误,此A
记录不存在此类型 ( ),但可能存在其他记录类型,或者此记录是 ENT,又称“空非终端”:它是空的,但它不是叶子,它“下面”有东西(请参阅定义RFC 7719),正如我们已经知道的(但通常解决方案是自上而下的,所以我们会在进入下一级之前达到这一步,而不是像我们在这里为了演示目的所做的那样相反)。
这就是为什么事实上,作为一种快捷方式,我们说状态代码是NODATA
:这不是一个真正的状态代码,它只是意味着NOERROR
+ 空的 ANSWER 部分,这意味着这种特定记录类型没有数据,但其他记录类型可能有。
如果您使用下一个“向上”标签(即名称)进行查询,则可以重复相同的实验并获得相同的结果ca.us
。
查询结果与区域文件内容
那么混乱从何而来?我相信它可能来自一些错误的想法,即 DNS 名称中的任何点都意味着有委派。这是错误的。换句话说,您的example.com
区域文件可以像这样,而且它完全有效且正常工作:
example.com. IN SOA ....
example.com. IN NS ....
example.com. IN NS ....
leaf.intermediate.example.com IN A 192.0.2.37
有了这样的区域文件,查询此名称服务器时,您将获得上面观察到的行为:查询intermediate.example.com
将返回NOERROR
空答案。您无需在区域文件中专门创建它(如果出于其他原因不需要它),权威名称服务器将负责合成“中间”答复,因为它看到它需要这个空的非终端(以及任何其他“中间”的非终端,如果有其他标签的话),就像它看到叶名称一样leaf.intermediate.example.com
。
请注意,事实上,这在某些地区是一种普遍存在的情况,但您可能看不到它,因为它针对的是人们接触不到的更多“基础设施”记录:
- 在反向区域中,例如
in-addr.arp
或ip6.arpa
,特别是最后一个。您将拥有类似1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.a.1.d.e.1.6.8.0.0.0.0.0.0.2.6.2.ip6.arpa. 1h IN PTR text-lb.eqiad.wikimedia.org.
和 的记录,显然每个点都没有委托,每个标签也没有附加资源记录 - 在
SRV
记录中,例如_nicname._tcp.fr. 12h IN SRV 0 0 43 whois.nic.fr.
,一个域可以有许多_proto._tcp.example.com
和_proto._udp.example.com
SRV
记录,因为根据设计,它们必须具有这种形式,但同时_tcp.example.com
和_udp.example.com
将保持为空非终端,因为从未用作记录 - 事实上,对于各种协议(例如 DKIM),还有许多其他基于“下划线标签”的特定名称构造情况。DKIM 要求您拥有 DNS 记录,例如
whatever._domainkey.example.com
,但显然它本身永远不会被使用,因此它将保持为空的非终端。DANE中的记录(例如:)或记录(例如:)_domainkey.example.com
也是如此TLSA
_25._tcp.somehost.example.com. TLSA 3 1 1 BASE64==
URI
_ftp._tcp IN URI 10 1 "ftp://ftp1.example.com/public"
名称服务器行为和中间回复的生成
为什么名称服务器会自动合成这样的中间答案?DNS 的核心解析算法,详见RFC 1034 第 4.3.2 节是的原因,让我们拿它来总结一下我们在向上述权威名称服务器查询名称时的案例intermediate.example.com
(这是QNAME
下面的协议):
- 在可用区域中搜索与 QNAME 最近的祖先区域。 如果找到这样的区域,则转到步骤 3,否则转到步骤 4。
名称服务器发现区域example.com
是 QNAME 的最近祖先,因此我们可以转到步骤 3。
我们现在有这个:
- 开始在区域中逐个标签地进行匹配。 [...]
a. 如果整个 QNAME 都匹配,我们就找到了该节点。 [...]
b. 如果匹配结果超出权威数据的范围,则我们有一个引荐。当我们遇到一个节点,其 NS RR 标记沿区域底部的切口时,就会发生这种情况。[..]
c. 如果在某个标签处无法匹配(即不存在相应的标签),则查看是否存在“*”标签。[..]
我们可以消除情况 b 和 c,因为我们的区域文件没有委派(因此永远不会引用其他名称服务器,没有情况 b),也没有通配符(所以没有情况 c)。
这里我们只需要处理情况 a。
我们开始在区域中逐个标签地向下匹配。因此,即使我们有一个很长的sub.sub.sub.sub.sub.sub.sub.sub.example.com
名称,在某个时候,我们也会遇到情况 a:我们没有找到引用,也没有找到通配符,但我们最终找到了我们想要结果的最终名称。
然后我们应用案例 a 的其余内容:
如果节点上的数据是 CNAME
这不是我们的情况,所以我们跳过这一步。
否则,将所有与 QTYPE 匹配的 RR 复制到答案部分并转到步骤 6。
无论我们选择哪种 QTYPE(A
、AAAA
、 NS
等),我们都没有 RR,因为intermediate.example.com
它没有出现在区域文件中。所以这里的副本是空的。现在我们完成第 6 步:
仅使用本地数据,尝试添加可能对查询的附加部分有用的其他 RR。退出。
这对我们来说并不相关,因此我们成功了。
这恰恰解释了观察到的行为:这样的查询会返回NOERROR
但也不会返回任何数据。
现在,您可能会问自己:“但是如果我使用任何名称,那么another.example.com
按照上述算法,我应该得到相同的答复(没有错误)”,但NXDOMAIN
在这种情况下观察结果会报告。
为什么?
因为整个算法如下:
以下算法假设 RR 组织成几个树结构,每个区域一个,缓存另一个
这意味着上述区域文件被转换成这棵树:
+-----+
| com | (just to show the delegation, does not exist in this nameserver)
+-----+
|
|
|
+---------+
| example | SOA, NS records
+---------+
|
|
|
+--------------+
| intermediate | no records
+--------------+
|
|
|
+------+
| leaf | A record
+------+
因此,按照算法,从顶部开始,你确实可以找到一条路径:(com > example > intermediate
因为路径com > example > intermediate > leaf
存在)但是对于another.example.com
, 在树中com > example
找不到标签后,作为的子节点。因此我们落入了上面的选择 c 的一部分:another
example
如果“*”标签不存在,则检查我们正在寻找的名称是查询中的原始 QNAME 还是我们由于 CNAME 而跟踪的名称。如果名称是原始的,则在响应中设置权威名称错误并退出。否则直接退出。
标签*
不存在,并且我们没有遵循CNAME
,因此我们处于以下情况:set an authoritative name error in the response and exit
,又名NXDOMAIN
。
请注意,以上所有内容在过去确实造成了混乱。这收集在某些 RFC 中。例如,请参见这个意想不到的地方(DNS 规范如此难以理解的乐趣)定义通配符:RFC 4592“通配符在域名系统中的作用”尤其是第 2.2 节“存在规则”,我的回答开头也部分引用了,但这里更完整:
空非终结符 [RFC2136,第 7.16 节] 是指不拥有资源记录但拥有子域的域名。第 2.2.1 节中的
“_tcp.host1.example.”就是一个空非终结符示例。RFC
1034 第 3.1 节中的这段文字介绍了空非终结符:# The domain name space is a tree structure. Each node and leaf on # the tree corresponds to a resource set (which may be empty). The # domain system makes no distinctions between the uses of the # interior nodes and leaves, and this memo uses the term "node" to # refer to both.
括号中的“可能为空”指定
明确识别空非终端,并且空非终端
“存在”。拘泥于文雅地阅读上述段落可能会导致这样一种
解释:所有可能的域都存在——最多
为域名建议的 255 个八位字节的限制 [RFC1035]。例如,
www.example. 可能有一个 A RR,就实际而言
,它是域树的叶子。但该定义可以
理解为 sub.www.example. 也存在,尽管没有数据。进一步说,所有可能的域都存在,从根开始向下。由于 RFC 1034 也在 4.3.1 节中定义了“权威名称错误,表明名称不存在”,所以这显然不是原始定义的意图,因此需要在下一节中更新定义。
然后下一节的定义就是我在开头引用的那段。
请注意,RFC 8020(NXDOMAIN
真正含义是NXDOMAIN
,如果你回复NXDOMAIN
,intermediate.example.com
那么leaf.intermediate.example.com
就不存在)之所以被强制执行,部分原因是各种 DNS 提供商没有遵循这种解释,从而造成了严重破坏,或者它们只是错误,例如参见 2013 年在一个开源权威名称服务器代码中修复的这个错误:https://github.com/PowerDNS/pdns/issues/127
人们需要为他们采取特定的对策:这不是积极缓存,NXDOMAIN
因为对于那些提供商,如果你在某个节点获得,它可能仍然意味着你得到了比它下面的另一个节点NXDOMAIN
不同的东西。NXDOMAIN
这使得 QNAME 最小化 (RFC 7816) 无法实现(参见https://indico.dns-oarc.net/event/21/contributions/298/attachments/267/487/qname-min.pdf详细信息请参见此处),而人们希望增加隐私。DNSSEC 中空非终端的存在也在过去造成了一些问题,例如处理不存在的情况(请参阅https://indico.dns-oarc.net/event/25/contributions/403/attachments/378/647/AFNIC_OARC_Dallas.pdf如果感兴趣的话,但你之前确实需要对 DNSSEC 有很好的理解)。
以下两条消息给出了一个提供商必须能够正确地对空非终端执行此规则的问题的示例,它提供了一些问题的观点以及我们为什么在那里:
答案2
我可能误解了 Khaled 的回答,但缺少中间记录绝不会对子区域名称的解析造成问题。请注意,此 dig 输出不是来自或指向teaparty.net
其任何子区域的权威 DNS 服务器:
[me@nand ~]$ dig very.deep.host.with.no.immediate.parents.teaparty.net
[...]
;; ANSWER SECTION:
very.deep.host.with.no.immediate.parents.teaparty.net. 3600 IN A 198.51.100.200
事实上,您应该能够dig
自己做到这一点,并得到答案 -teaparty.net
是一个真实的域,在我的控制之下,并且确实包含该记录。您可以验证在和A
之间没有任何这些区域的记录,并且它不会影响您对上述主机名的解析。very
teaparty.net
答案3
如果您直接查询权威 DNS 服务器,您将毫无问题地得到答案。
但是,如果你通过另一个没有有效缓存的 DNS 服务器进行查询,你将无法获得有效答案。查询intermediate.example.com
将导致NXDOMAIN
错误。
答案4
直接回答这个问题,不,您不需要添加您实际上并未使用的中间名称的记录,但这并不意味着这些名称不存在。
至于这些名称是否存在,这实际上是一个完全不同的问题,我希望提供一个简短且直观的答案。
归根结底,DNS 是一种树结构,域名中的每个标签都是一个树节点。例如,www.example.com.
有标签www
、example
和com
``(根节点),它们是构成通向根路径的树节点。
可能使 DNS 的这一基本性质不明显的是,在管理 DNS 数据时几乎总是看不到树,而且我们通常不直接处理树节点本身,而是通常有一个扁平列表,列出应该存在于不同域名(实际上是树路径,如上所述)的记录数据。
当使用这个扁平列表时,DNS 服务器软件会根据现有记录构建树,如果具有记录的节点之间存在间隙(例如,有 和 的记录,foo.bar.example.com.
但example.com.
没有 的记录bar.example.com.
),则这些节点将被视为空树节点。也就是说,这些是确实存在的域名/节点,树没有损坏,这些节点只是没有任何与之关联的数据。
因此,如果您查询其中一个空节点,您将得到一个NODATA
响应(NOERROR
status +SOA
权限部分),表示请求的记录类型在此节点不存在。如果您查询实际上不存在的某个名称,您将得到一个NXDOMAIN
响应,表示请求的域名在树中不存在。
现在,如果您想了解详细信息,请阅读 Patrick Mevzek 非常详尽的回答。