从你自己的终端看DNS的运作


对DNS如何工作感到好奇?跟随这些步骤,你会看到域名是如何被解析的,从根域名服务器开始。

一步一步的DNS查询与挖掘

DNS是用来将域名翻译成IP地址的。你可能也听说过,DNS是分布式的--不是让一个服务器知道每个可能的域名的IP地址,而是每个服务器只知道自己的责任区(zone)。

你可能已经听过多次,但它不是一直都有点抽象吗?要看到它的行动,你可以去开始 用手构建你自己的DNS数据包 ,但有一个更简单的方法来逐步跟踪解析过程,而不需要让你的手相当脏。

在你的系统中,你可能已经有了一个叫做 dig   (域名信息挖掘器)的命令行工具。通过挖掘,你可以向你选择的服务器发出DNS查询。

先问根服务器

每个服务器都会知道答案,或者他们会告诉你下一步应该问哪里。解析域名的过程是从 根域名服务器 开始的。你可以通过简单地发出不带参数的命令 dig 来找到这些服务器的列表。响应将包含一个列表,如:。

...

.			628330	IN	NS	h.root-servers.net.
.			628330	IN	NS	e.root-servers.net.
.			628330	IN	NS	g.root-servers.net.

...

有13个根名称服务器(从 a m )用于冗余。它们由独立组织维护,如NASA、VeriSign和美国军队。随意选一个,例如, c.root-servers.net 由Cogent Communications维护。

你可以通过发出以下命令向根服务器询问 example.com 的IP地址。 dig @c.root-servers.net example.com . 这样做的目的是将你的请求编码为一个二进制数据包,然后通过UDP将其发送到用@指定的服务器。

理解答案

答案也是一个二进制数据包,但是dig再次帮助你,输出了一个更容易被人理解的响应内容版本。

;; Got answer:
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 9
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;example.com.			IN	A

;; AUTHORITY SECTION:
com.			172800	IN	NS	f.gtld-servers.net.
...

数据包的开头有一些 标志 ,这里最有趣的是响应中的answer的数量。这里你可能会注意到 "ANSWER: 0". 这意味着该数据包不包含对你问题的直接回答。

在标志之后,二进制DNS数据包由若干部分组成。Dig向你展示这些部分,用注释分开,如 ";;问题部分" , ";答案部分" ";授权部分" 问题部分 只是重复了你的疑问。 答案部分 (这里没有)将包含你要寻找的IP地址。

如果服务器不直接知道答案, 授权部分 告诉你下一步要问哪里。权限部分表示有权回答有关该域的DNS查询的服务器。在上述响应中,你会看到在权威部分结束的一行,有" a.gtld-servers.net。 "

从本质上讲,这个响应意味着" 我不知道example.com的IP地址,但要问这个服务器。 "

咨询当局

要再次向下一个服务器提出这个问题,请做与之前相同的事情,只是这次使用你从响应中了解到的新的名称服务器。 dig @a.gtld-servers.net example.com .

你会得到一个看起来很熟悉的答案。

;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 32078
;; flags: qr rd; QUERY: 1, ANSWER: 0, AUTHORITY: 2, ADDITIONAL: 4
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;example.com.			IN	A

;; AUTHORITY SECTION:
example.com.		172800	IN	NS	a.iana-servers.net.
...

这个服务器再次说 "我不知道,但可以问a.iana-servers.net,他们是这方面的权威。"

再继续连锁一步。 dig @a.iana-servers.net example.com .

;; flags: qr aa rd; QUERY: 1, ANSWER: 1, AUTHORITY: 2, ADDITIONAL: 0
;; WARNING: recursion requested but not available

;; QUESTION SECTION:
;example.com.			IN	A

;; ANSWER SECTION:
example.com.		86400	IN	A	93.184.216.34
...

从标志部分,你可以看到,现在我们有 "ANSWER: 1",意思是这个回答包含了一个答案部分! 事实上,再往下几行,你会发现有一个答案部分包含你要找的IP地址。93.184.216.34.

递归查询

你刚才做的是向非递归服务器发出一系列的DNS查询,每一步都可能指向下一个名字服务器,而不是直接给你答案。

你也可以通过使用 +trace   选项,让dig为你执行这个一步步的解析过程。 dig +trace www.example.com . 在这种情况下,dig会从一个名字服务器迭代到下一个,而不需要你手动发出每条新的命令。

还有一种方法可以得到答案,而不需要在你的机器上做任何跳跃。你可以向一个支持递归查询的名称服务器发出一个 递归查询 。通过递归查询,你让目标名称服务器直接找出最终答案。

这两种查询之间的真正区别是在发送的DNS数据包中的一个位,表明你是否想要最终答案或只是下一跳。在上面的例子中,这并不重要,因为根名称服务器不支持递归。如果需要,你可以通过选项 +norecurse+recurse   来控制这个位标志(这也是默认的)。

例如,Google在容易记住的IP地址8.8.8.8上运行这样一个递归名称服务器。你可以像以前一样用dig来询问答案。 dig @8.8.8.8 example.com . 不过这次你会直接得到答案,因为谷歌的名称服务器为你做了所有的迭代工作(或者很可能已经缓存了答案)。

小结

扮演一个迭代解析器的角色让你很好地感受到名字解析是如何在幕后发生的。

DNS解析从根服务器开始,根服务器将你指向每个顶级域的权威。命令行工具dig允许你向这些名称服务器发出查询,揭示你下一步应该询问哪个名称服务器。重复这个过程,你最终可以了解到你所寻求的IP地址。

对你的新知识感到高兴,在排除DNS的问题时,它可以派上用场。