在 DNS 名称解析中,浏览器如何确定众多 DNS 服务器中最近可用的 DNS 服务器?
我知道有 13 个根服务器,但是我的 ISP 的 DNS 服务器如何知道要联系哪个根 DNS 服务器?
Mad*_*ter 12
你的浏览器没有。您的浏览器将使用标准系统调用来解析主机名(我相信通常是getaddrinfo()
),这些通常会依次检查 的内容/etc/resolv.conf
以查找配置的解析名称服务器,并查询它们。他们将依次将您的桌面操作系统的查询转发到上游服务器(缓存任何回复)或自己执行递归解析。请注意,上述链中的大多数步骤都是可配置的,因此您的浏览器实际上将在本地确定;但上面的场景是典型的。
正是该链中的递归解析域名服务器(无论是您本地配置的权威域名服务器,还是一些 ISP 的服务器)需要知道如何找到根服务器,它们通过预先配置的区域文件来完成for .
(通常通过查询可用的根名称服务器来定期更新)。
编辑:它没有。它将依赖于实现,但在我的情况下(BIND),它只是选择一个并查询它。只要它及时得到答案,它就会从那里递归下去。是什么让您认为正在进行任何类型的测距操作?
小智 11
在 DNS 名称解析中,浏览器如何确定众多 DNS 服务器中最近可用的 DNS 服务器?
正如其他答案所示,您的浏览器或其他客户端程序不会进行此选择。客户端程序通过调用称为解析器的库来请求名称服务解析。
解析器确定它应该联系哪些服务器来询问查询。它取决于解析器的实现,但通常它会按顺序查询已配置的递归解析器列表(通过静态配置或通过诸如 DHCP 之类的机制接收它们。)
总而言之:您的(用户级)程序要求解析器进行名称解析,解析器会询问通过某种配置机制提供给它的名称服务器。
我知道有 13 个根服务器,但是我的 ISP 的 DNS 服务器如何知道要联系哪个根 DNS 服务器?
这也是依赖于实现的。我将描述它如何与 BIND 一起工作,因为
首先,让我们先谈谈递归域名服务器如何知道选择哪些域名服务器与特定域进行通信。对于从名称服务器的根(“.”)级别可访问的每个域,管理该域的管理员在包含的父域中发布记录类型为 NS(即名称服务器)的资源记录集,以公开委托给名称服务器在资源记录集中指定解决与该域有关的查询的责任。
该系统的优点之一是它允许对域名系统和递归服务器需要先验的唯一域进行分布式分层委派。Knowledge 是根级别,服务器配置为了解该级别。过去最常见的是通过 BIND 在启动时加载的“提示”文件为根指定 NS RRset,但现在有一段时间,根服务器使用的 IP 地址已在 BIND 中预定义。【题外话:你仍然可以通过指定一个根提示区来覆盖内置,实际上d.root-servers.net的地址最近发生了变化,新的位置不会反映在内置列表中,直到新的构建和分发包含新信息的 BIND 版本。目前,包含 D 根服务器新 IP 地址的版本处于测试阶段。]
无论如何,这里的关键是每个域都关联了一个 NS 记录 RRset,其中包含该域公开宣布的名称服务器。你应该试着自己看一些。让我们看一下根:
$ dig . ns +edns=0 @f.root-servers.net.
Run Code Online (Sandbox Code Playgroud)
我将剪掉答案部分,其中将包含以不可预测的顺序返回的 NS RRset(我在这里略加掩饰——顺序通常由我正在与之交谈的名称服务器的配置决定. 不同的根可能会以不同的顺序回答,但所订购的项目应该是相同的。)
;; ANSWER SECTION:
. 518400 IN NS h.root-servers.net.
. 518400 IN NS j.root-servers.net.
. 518400 IN NS c.root-servers.net.
. 518400 IN NS l.root-servers.net.
. 518400 IN NS e.root-servers.net.
. 518400 IN NS a.root-servers.net.
. 518400 IN NS f.root-servers.net.
. 518400 IN NS k.root-servers.net.
. 518400 IN NS i.root-servers.net.
. 518400 IN NS d.root-servers.net.
. 518400 IN NS m.root-servers.net.
. 518400 IN NS b.root-servers.net.
. 518400 IN NS g.root-servers.net.
Run Code Online (Sandbox Code Playgroud)
这些是根 (".") 域的所有名称服务器,我们可以向其中任何一个询问有关根域的问题。如果我们向他们询问有关不在根域中的内容的问题,我们将收到一个错误,或者更有可能是对另一组名称服务器的推荐(例如“example.com?我不回答有关 example.com 的问题。 . 尝试询问 .com 域名服务器——他们在那边......”)
那么,BIND 如何知道来自 NS RRset 的哪个名称服务器将给予它最快的响应?
答案是:最初没有。但在其默认行为下,它会随着时间的推移不断学习并决定通常以最短的往返时间询问服务器。
往返时间和候选名称服务器的选择 BIND 依赖到 RRset 中的名称服务器的往返时间 (RTT) 来选择应接收其查询的名称服务器。第一次将域的 NS RRset 添加到缓存时,集合中的所有记录都被分配了一个小的随机往返时间,大约为几毫秒。在初始启动之后,当需要将查询定向到为给定域委派的名称服务器时,BIND 检查其缓存并(希望)找到 RRset。它从集合中选择具有最低 RTT 时间的服务器并进行查询。查询完成后,BIND 更新 NS RRset 的 RTT,如下所示:
让我们通过一个例子来看看这是如何工作的。我的递归解析器第一次遇到域 example.com 时,它会将 example.com 的 NS RRset 加载到其缓存中。假设 example.com 的管理员为 example.com 宣布了三个名称服务器,因此 NS RRset 如下所示:
example.com NS servera.example.com
example.com NS serverb.example.com
example.com NS serverc.example.com
Run Code Online (Sandbox Code Playgroud)
为了这个例子,我们还假设你的解析器需要以下时间来接收来自这个集合中每个服务器的响应:
servera -- 30 ms
serverb -- 45 ms
serverc -- 50 ms
Run Code Online (Sandbox Code Playgroud)
现在第一次加载 example.com NS RRset 时,RTT 权重以小的随机值作为准备。因此,在我们询问 example.com 名称服务器之前,RTT 表可能如下所示:
servera -- 8 ms
serverb -- 9 ms
serverc -- 7 ms
Run Code Online (Sandbox Code Playgroud)
我们第一次查询 example.com 时,我们将去 serverc 并提出我们的问题。Serverc 需要 50 毫秒来响应,因此在我们的查询完成后,我们更新我们的 RTT 表,使其现在显示:
servera -- 7 ms // reduced by a small fraction
serverb -- 8 ms // reduced by a small fraction
serverc -- 50 ms // updated to reflect the actual round trip time.
Run Code Online (Sandbox Code Playgroud)
下一次我们显然会选择 servera,因为它现在的往返时间最短。在仅对 example.com 域进行几次查询之后,我们应该有一个相当不错的想法,哪个名称服务器为我们提供最快的响应,然后我们将在大多数情况下更喜欢该服务器。
为什么大部分时间而不是所有时间?我之前提到的“RRset 中的所有其他服务器的 RTT 都减少了一小部分”是怎么回事?好吧,事实证明,虽然我们想要更喜欢最快的服务器,我们不想永久注销其他服务器。也许服务器 c 几乎在所有时间都是最快的服务器,但在我们第一次设置其 RTT 时,它异常繁忙。也许服务器暂时停止服务,导致 RTT 非常高(在我们尝试查询它超时之后),但我们想在它恢复服务后再次开始询问它。通过每次向下调整其他服务器的值,它们迟早会比我们更喜欢的服务器的平均 RTT 低。当发生这种情况时,我们将向他们的方向抛出一个查询,如果时间更好,那就太好了。
归档时间: |
|
查看次数: |
7974 次 |
最近记录: |