当我输入 www.google.com 时,dns 查找是如何工作的。据我所知,它首先转到根服务器并找出 .com dns 服务器的位置。接下来它返回该服务器的 ip 地址。接下来从那里找出 google 服务器的位置。现在它返回一个 ip 地址,那就是找到 www.google.com 的地方。
因此,要解决这个问题,需要进行两次 DNS 查找。如果我错了,请纠正我。
答案1
当您开始考虑缓存和任播之类的事情时,DNS解析会变得非常复杂,但现在我们先保持简单。
以下是对 www.google.com 的查询的 dig 片段和 tcpdump 片段,这些查询是针对新启动的名称服务器的,因此未使用缓存。我已修剪了一些时间戳,以便于阅读。
首先,本地名称服务器(此处为 192.168.10.10)向其中一个根服务器(此例中为 h.root-servers.net,128.63.2.53)询问“www.google.com 的 A 记录是什么?” h.root-servers.net 对 www.google.com 没有权威性,但它对 .com 有授权,因此它返回该记录。
192.168.10.10.17203 > 128.63.2.53.53: 29969 [1au] A? www.google.com. (43)
128.63.2.53.53 > 192.168.10.10.17203: 29969- 0/15/16 (719)
;; QUESTION SECTION:
;www.google.com. IN A
;; AUTHORITY SECTION:
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
其次,本地名称服务器从 h.root-servers.net 返回的列表中选择一个名称服务器,并发送相同的查询:“www.google.com 的 A 记录是什么?” 在本例中,查询的名称服务器是 f.gtld-servers.net (192.35.51.30)。f.gtld-servers.net 是 .com 的权威服务器,它已使用区域 google.com 的名称服务器授权做出响应
192.168.10.10.65182 > 192.35.51.30.53: 58632 [1au] A? www.google.com. (43)
192.35.51.30.53 > 192.168.10.10.65182: 58632- 0/4/5 (179)
;; QUESTION SECTION:
;www.google.com. IN A
;; AUTHORITY SECTION:
google.com. 172800 IN NS ns2.google.com.
google.com. 172800 IN NS ns1.google.com.
google.com. 172800 IN NS ns3.google.com.
google.com. 172800 IN NS ns4.google.com.
越来越近了!现在本地名称服务器选择上一个响应中的一个名称服务器并向其询问相同的问题。在本例中,它询问 ns2.google.com (216.239.34.10)。ns2.google.com 响应 www.google.com 实际上是 www.l.google.com 的 CNAME(规范名称)记录
192.168.10.10.4767 > 216.239.34.10.53: 15830 [1au] A? www.google.com. (43)
216.239.34.10.53 > 192.168.10.10.4767: 15830*- 6/0/0 CNAME[|domain]
;; QUESTION SECTION:
;www.google.com. IN A
;; ANSWER SECTION:
www.google.com. 604800 IN CNAME www.l.google.com.
非常接近!现在我们只需要 www.l.google.com 的地址。现在因为我们已经知道 google.com 的名称服务器,所以我们只需询问其中一个。在本例中,我们询问 ns3.google.com (216.239.36.10)“www.l.google.com 的 A 记录是什么?”它响应地址,我们得到了答案:
192.168.10.10.63657 > 216.239.36.10.53: 62511 [1au] A? www.l.google.com. (45)
216.239.36.10.53 > 192.168.10.10.63657: 62511*- 5/0/0 A[|domain]
;; QUESTION SECTION:
;www.l.google.com. IN A
;; ANSWER SECTION:
www.l.google.com. 300 IN A 74.125.232.116
www.l.google.com. 300 IN A 74.125.232.112
www.l.google.com. 300 IN A 74.125.232.115
www.l.google.com. 300 IN A 74.125.232.113
www.l.google.com. 300 IN A 74.125.232.114
好极了!
无论如何,我希望这些足以让你入门。有很多很棒的资源。O'Reilly 的书“DNS 和 BIND”非常有用。
我非常非常推荐安装 dig 来查看 DNS 查询的进展情况。例如,您可以使用 dig +trace 轻松查看主机的委托路径:
; <<>> DiG 9.7.0-P1 <<>> +trace www.google.com
;; global options: +cmd
. 516930 IN NS k.root-servers.net.
. 516930 IN NS g.root-servers.net.
. 516930 IN NS h.root-servers.net.
. 516930 IN NS j.root-servers.net.
. 516930 IN NS a.root-servers.net.
. 516930 IN NS m.root-servers.net.
. 516930 IN NS b.root-servers.net.
. 516930 IN NS f.root-servers.net.
. 516930 IN NS d.root-servers.net.
. 516930 IN NS c.root-servers.net.
. 516930 IN NS l.root-servers.net.
. 516930 IN NS i.root-servers.net.
. 516930 IN NS e.root-servers.net.
;; Received 244 bytes from 127.0.0.1#53(127.0.0.1) in 1 ms
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
;; Received 492 bytes from 202.12.27.33#53(m.root-servers.net) in 45 ms
google.com. 172800 IN NS ns2.google.com.
google.com. 172800 IN NS ns1.google.com.
google.com. 172800 IN NS ns3.google.com.
google.com. 172800 IN NS ns4.google.com.
;; Received 168 bytes from 192.33.14.30#53(b.gtld-servers.net) in 42 ms
www.google.com. 604800 IN CNAME www.l.google.com.
www.l.google.com. 300 IN A 74.125.232.115
www.l.google.com. 300 IN A 74.125.232.113
www.l.google.com. 300 IN A 74.125.232.116
www.l.google.com. 300 IN A 74.125.232.114
www.l.google.com. 300 IN A 74.125.232.112
;; Received 132 bytes from 216.239.34.10#53(ns2.google.com) in 131 ms
注意到它与之前的查询跟踪有多相似吗?希望这能有所帮助。
答案2
由于 DNS 缓存非常多,因此情况会稍微复杂一些。您的本地计算机甚至可能缓存了数据,而查找仅此而已。
您的计算机将查询自己的缓存,如果查询失败,它将查询已告知的主 DNS 服务器。这可能是一个缓存 DNS 服务器,结果可能位于其缓存中,在这种情况下,记录将返回给您,查询结束。它也很可能是一个递归 DNS 服务器,现在将为您的计算机完成后续工作。
如果主 DNS 服务器没有该信息,它将查询根名称服务器,根名称服务器将使用 .com 的 TLD 名称服务器进行响应(在您的示例中)
查询将被发送到 .com TLD 服务器,该服务器将使用 google.com 的权威名称服务器的地址进行响应
系统会向 google.com 的权威名称服务器发送查询,请求 www.google.com 记录。系统会找到该记录并将其返回到主 DNS 服务器,主 DNS 服务器会缓存该记录并将记录返回给您。
答案3
DNS 是分层的,并且如 lain 所说,缓存量很大。也许,一个更复杂的例子可以帮到你。
假设您有一台机器属于一家公司,该公司有多个业务部门,这些部门反映在域结构中。您的机器名为 machine.businessunit1.company.com,即属于 businessunit1.company.com,这是您的主 DNS 后缀。
该业务部门非常庞大,运营着多个 DNS 服务器(dns1.businessunit1.company.com、dns2.businessunit1.company.com)以及一个名为 www.businessunit1.company.com 的网络服务器。
如果您的机器现在要解析 www.businessunit1.company.com,它将首先查找本地 DNS 缓存。即您的机器本身会记住您最近查询的 DNS 条目,因为您很可能再次需要这些结果,例如当您单击网站上的链接时。我不知道您是否可以看到您的机器缓存了什么,但有一个命令可以删除您的机器记住的所有内容(在 Windows 上):ipconfig /flushdns
如果您的机器不记得答案,它会询问 - 正如我之前评论的那样 - 为您的网络适配器配置的 DNS 服务器。最有可能的是,您的管理员将配置 dns1.businessunit1.company.com 和 dns2.businessunit.company.com。这样做的原因是您希望快速回答 DNS 查询,而不会产生大量流量。如果 dns1.businessunit1.company.com 收到您对 www 的查询,它将回答它,因为它对区域 *.businessunit1.company.com 具有权威性。权威意味着该服务器知道所有以“businessunit1.company.com”结尾的 DNS 名称的唯一正确答案。
现在假设您查询 www.businessunit2.company.com。如果您的机器不记得答案,它将再次询问 dns1.businessunit1.company.com。现在,有很多可能性:首先,您的管理员可能很聪明,他们已经预见到 businessunit1 中的人员很可能也希望频繁访问 businessunit2 中的机器。因此,他们已将 dns1.businessunit1.company.com 配置为保存来自 dns1.businessunit2.company.com 的数据副本。dns1.businessunit1.company.com 可以使用此副本来回答您的问题。其次,您的管理员肯定会告诉 dns1.businessunit1.company.com 在不知道您问题的答案时该怎么做:即询问另一个 DNS 服务器。可能,这是 dns1.company.com,但也可能是任何其他 DNS 服务器,包括根服务器。
正如 lain 所说,dns1.businessunit1.company.com 可以自由地记住它从其他 DNS 服务器获得的任何答案。也就是说,如果您请求 www.google.com,它可能需要询问其他服务器,但如果您再次询问,它会记住答案并直接告诉您。
当您输入例如 时,您基本上可以看到 DNS 答案来自哪里nslookup www.google.com
。输出将告诉您服务器以及它是否是权威答案。最有可能的是,它将是非权威的,因为它不是由 Google 的 DNS 服务器回答的,而 Google 的 DNS 服务器负责所有以“google.com”结尾的 DNS 名称。