面向 Web 开发人员的 DNS
想象一下,你回到办公室,打开浏览器,访问 172.217.172.197 查看电子邮件。然后你访问 140.82.112.4 查看同事提出的一些代码更改建议。接着,你打开你最喜欢的聊天客户端,连接到 84.17.44.180。如果你还没搞明白:这太糟糕了。这是一个没有域名的世界。
我们更习惯于输入 gmail.com、github.com 和 chat.freenode.net,但就像你需要朋友的电话号码才能给他们打电话一样,你的网络浏览器也需要知道服务器的 IP 地址来请求页面。幸运的是,我们有一个系统可以查找给定域名的 IP 地址,它运行得非常顺畅,我们几乎不需要考虑这个问题。
这也意味着我以前根本不知道它到底是如何工作的,所以每当有人跟我谈论更改 DNS 设置时,我都会感到恐惧;“它就像互联网上的电话簿”并不能帮助我理解记录缓存如何影响递归查找。
如果你曾经有过这种感觉,我想帮你摆脱它。也许你是一名 Web 开发者,就职于一家公司,该公司拥有一支由网络工程师组成的支持团队,负责维护应用层以下的所有功能;又或许你正处于一个被要求了解从色彩理论到算法等所有知识的职位。无论哪种情况,你都应该对 DNS 如何帮助网站访问者连接到你的应用有一个基本的了解。
⌨️ 找到地址记录www.ianjmacintosh.com
假设我要访问www.ianjmacintosh.com。为了让我的浏览器看到该网站,我的浏览器需要知道要从哪个 IP 地址发出请求。首先,我的浏览器会检查它是否已经缓存了www.ianjmacintosh.com
它的 IP 地址记录。这条记录叫做地址记录,或者A 记录。如果我手头没有 A 记录,我的浏览器就会向我的DNS 解析器请求一条。DNS 解析器会向客户提供他们所请求的任何记录,每个主要的 ISP 都会提供一个 DNS 解析器。我将演示如何使用命令行工具(域名信息搜索器dig
的缩写)手动从 Google 的公共 DNS 解析器和其他名称服务器请求记录。
dig 执行 DNS 查询并显示返回的答案。大多数 DNS 管理员使用 dig 来排除 DNS 问题,因为它灵活、易用且输出清晰。它预装在大多数 Mac OS X 和 Linux 系统上,但 Windows 用户需要手动安装。如果您在其他操作系统(例如 Android 或 iOS)上阅读本文,可以尝试使用基于 Web 的 dig 客户端(例如我随机找到的这个)进行操作。但如果您先阅读本文,稍后在本地安装了 dig 的计算机上运行命令,可能会受益匪浅。
尝试你的第一个dig
查询:
dig @8.8.8.8 www.ianjmacintosh.com A +short
此调用会8.8.8.8
向 Google 公共 DNS 解析器查询 IP 地址,以获取www.ianjmacintosh.com
其A
地址记录。+short
查询选项要求 dig 提供简洁的答案。
这个简洁的答案是这样的:
54.207.147.214
18.230.52.212
这些是 Google 的 DNS 解析器告诉我如果需要的话应该联系的 IP 地址www.ianjmacintosh.com
。
即使您现在停止阅读,至少您了解了如何快速获取与域名关联的 IP 地址。
DNS树
假设你的本地文件系统上有这样一个路径:/Users/alice/projects/next-great-american-novel
。next-great-american-novel
目录位于projects
目录中,目录中位于目录alice
,目录中位于Users
目录,目录中位于根/
目录()。计算机科学家将这种抽象概念称为树。
com
、ianjmacintosh
和之间的关系www
是相同的,尽管书写方式是从右到左而不是从左到右。我们不是遍历本地文件系统上的目录,而是查询远程系统上的 DNS 服务器。这些服务器称为名称服务器。
为了获得 的 A 记录www.ianjmacintosh.com
,DNS 解析器会询问它已经信任的域名服务器com
,该服务器将它指向另一个知道所有信息的域名服务器ianjmacintosh.com
,该服务器将它指向另一个知道所有信息的域名服务器www.ianjmacintosh.com
。
实际上,这并不完全准确;DNS解析器和域名服务器有时会在本地缓存记录,甚至无需发出请求。如果域名服务器缓存了 的记录ianjmacintosh.com
,它会从那里开始,而不是向上查找www.ianjmacintosh.com
或pozo.ianjmacintosh.com
或 的其他子域名的记录ianjmacintosh.com
。
此外,有时域名服务器会代替请求者进行适当的后续查询,从而省去请求者的麻烦。下一个服务器也可能执行相同的操作,使发出请求的域名服务器无需再次发出请求。这种操作可以无限循环下去,称为递归搜索。
通常情况下,这很有用,因为它有助于分散查找记录所需的工作,但在我们的例子中,我们不想分散这项工作!我们想自己完成所有工作。所以我们将使用 dig 来告诉名称服务器我们想要获取 A 记录www.ianjmacintosh.com
,但我们不希望使用递归。
⌨️8.8.8.8
使用查询选项查询www.ianjmacintosh.com
ʼ 的地址(A
)记录+norecurse
dig
以下是我们将在本文中使用的语法:
dig [@server] [name] [type] [queryopt...]
我将使用键盘表情符号 (⌨️) 来表示我希望你使用 执行的查询dig
。我会用简单的英语描述它们,你的练习是调用实际的命令。在与我的代码进行比较之前,请尝试自己编写每个命令。
💁🏻♂️ 如果不运行命令,试图在脑子里理解这一切是如何运作的,既困难又愚蠢。如果可以的话,请使用命令行继续学习,充分利用本文。
尝试自己编写一个命令,www.ianjmacintosh.com
使用 +norecurse 查询选项来查询 8.8.8.8 的地址记录。下面是我使用的调用方式 👀
dig @8.8.8.8 www.ianjmacintosh.com A +norecurse
这些参数和选项是:
8.8.8.8
是要查询的服务器:Google 的公共 DNS 解析器。我将 放在@
前面,因为这是 dig 文档 (man dig
) 规定的。如果省略此[@server]
参数,dig 将/etc/resolv.conf
查询其中列出的域名服务器。www.ianjmacintosh.com
是要查找的资源记录的名称。A
是我们要查询的记录类型——我们正在寻找“A”记录(地址记录)。如果省略此[type]
参数,dig 仍会执行 A 记录查找,但我始终希望在展示示例时尽可能详细和清晰。+norecurse
是查询选项,用于关闭递归(和迭代)。简而言之:这会告诉服务器不要为我们做任何额外的工作。如果省略此项[queryopt]
,您正在查询的服务器可能会消除我们进行额外练习来查找资源的需要。由于我们正在尝试练习,所以这很糟糕!- 注意:你可能注意到我省略了该
+short
选项。本文的其余部分将使用详细报告。
总而言之:此命令指示 dig 查询名为类型的8.8.8.8
记录,并要求服务器不要递归搜索。www.ianjmacintosh.com
A
阅读回复并发现你收到了错误
dig 将返回如下报告:
; <<>> DiG 9.10.6 <<>> @8.8.8.8 www.ianjmacintosh.com A +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 25344
;; flags: qr ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;www.ianjmacintosh.com. IN A
;; Query time: 40 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Tue Nov 24 15:42:43 -03 2020
;; MSG SIZE rcvd: 50
与其费力理解这些,不如直接跳到标题部分 ( ->> HEADER <<-
),看看它的内容status: SERVFAIL
。这是“服务器故障”的缩写,表示由于名称服务器本身存在问题,名称服务器无法处理此查询。您提交的查询本身并没有问题,但它无法给您真正的答案。如果它提供了答案,它会显示一个很大的标题为 的部分,ANSWER SECTION
其中包含我们请求的记录。它ANSWER: 0
在下面一行中明确说明了SERVFAIL
。
简而言之,这份报告显示,Google 的公共 DNS 解析器没有 的地址记录www.ianjmacintosh.com
。如果您再次运行此命令并添加该+short
选项,则会得到空的响应。
我们之前运行时之所以能得到答案dig
,是因为我们没有关闭递归,而 Google 的公共 DNS 解析器帮我们做了一些额外的工作。这些额外的工作始于访问所谓的“根域名服务器”。
顶级域名com
是 (发音为“root”)的一部分.
,就像www.ianjmacintosh.com
是 的一部分ianjmacintosh.com
,以及ianjmacintosh.com
是 的一部分一样com
。为了明确显示域名的根,DNS 通常在显示域名时使用尾随点,例如:www.ianjmacintosh.com.
这称为“完全限定域名”(FQDN),并且该尾随点.
的含义与/
绝对路径(例如/Users/alice/projects/next-great-american-novel
)中的前导点相同:root。
任何搜索都需要从某个地方开始,因此我们对www.ianjmacintosh.com
地址记录的搜索需要从根目录开始。我们寻找的是名称服务器记录,而不是地址记录——我们不会尝试.
在浏览器中打开它。因此,我们需要将[type]
参数从A
“地址”改为NS
“名称服务器”。
⌨️ 查询ʼ8.8.8.8
的.
名称服务器(NS
)记录+norecurse
dig @8.8.8.8 . NS +norecurse
这些参数和选项是:
8.8.8.8
是 Google 的公共 DNS 解析器.
是所有域名的根NS
是“名称服务器”的缩写+norecurse
仍然阻止服务器为我们做练习
总而言之:此命令指示 dig 查询名为类型的8.8.8.8
记录,并要求服务器不要递归搜索。.
NS
从响应报告中找到根服务器
; <<>> DiG 9.10.6 <<>> @8.8.8.8 . NS +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 51781
;; flags: qr ra ad; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;. IN NS
;; ANSWER SECTION:
. 86755 IN NS a.root-servers.net.
. 86755 IN NS b.root-servers.net.
. 86755 IN NS c.root-servers.net.
. 86755 IN NS d.root-servers.net.
. 86755 IN NS e.root-servers.net.
. 86755 IN NS f.root-servers.net.
. 86755 IN NS g.root-servers.net.
. 86755 IN NS h.root-servers.net.
. 86755 IN NS i.root-servers.net.
. 86755 IN NS j.root-servers.net.
. 86755 IN NS k.root-servers.net.
. 86755 IN NS l.root-servers.net.
. 86755 IN NS m.root-servers.net.
;; Query time: 34 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Wed Nov 25 17:39:56 -03 2020
;; MSG SIZE rcvd: 239
哇!这才像话!🎉
首先,检查一下标头中显示的status: NOERROR
。没有错误!在下一行,ANSWER: 0
之前显示的位置现在显示ANSWER: 13
。我们得到了一个ANSWER SECTION
包含 13 个不同根域名服务器的正确信息,其中任何一个都应该能够响应对 的域名服务器记录的查询com
。
随机选择一个并在下次查询中使用它。
顺便说一句,您可以使用域名,而不是使用 IP 地址作为服务器发送下一个查询的目标。dig 会在发送查询之前,在后台悄悄地向您的 DNS 解析器询问其 IP 地址。8.8.8.8
您可以使用而不是 。您可以使用dns.google
而不是。198.41.0.4
a.root-servers.net
⌨️ 向 DNS 根服务器查询com
sNS
记录(使用+norecurse
)
dig @a.root-servers.net com NS +norecurse
这些参数和选项是:
a.root-servers.net
是我们请求顶级域名的名称服务器记录的服务器com
。com
是我们要求的记录的名称NS
是“名称服务器”的缩写+norecurse
避免a.root-servers.net
进行递归搜索
com
从报告中获取名称服务器
; <<>> DiG 9.10.6 <<>> @a.root-servers.net com NS +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16916
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 13, ADDITIONAL: 27
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;com. IN NS
;; AUTHORITY SECTION:
com. 172800 IN NS e.gtld-servers.net.
com. 172800 IN NS b.gtld-servers.net.
com. 172800 IN NS j.gtld-servers.net.
com. 172800 IN NS m.gtld-servers.net.
com. 172800 IN NS i.gtld-servers.net.
com. 172800 IN NS f.gtld-servers.net.
com. 172800 IN NS a.gtld-servers.net.
com. 172800 IN NS g.gtld-servers.net.
com. 172800 IN NS h.gtld-servers.net.
com. 172800 IN NS l.gtld-servers.net.
com. 172800 IN NS k.gtld-servers.net.
com. 172800 IN NS c.gtld-servers.net.
com. 172800 IN NS d.gtld-servers.net.
;; ADDITIONAL SECTION:
e.gtld-servers.net. 172800 IN A 192.12.94.30
e.gtld-servers.net. 172800 IN AAAA 2001:502:1ca1::30
b.gtld-servers.net. 172800 IN A 192.33.14.30
b.gtld-servers.net. 172800 IN AAAA 2001:503:231d::2:30
j.gtld-servers.net. 172800 IN A 192.48.79.30
j.gtld-servers.net. 172800 IN AAAA 2001:502:7094::30
m.gtld-servers.net. 172800 IN A 192.55.83.30
m.gtld-servers.net. 172800 IN AAAA 2001:501:b1f9::30
i.gtld-servers.net. 172800 IN A 192.43.172.30
i.gtld-servers.net. 172800 IN AAAA 2001:503:39c1::30
f.gtld-servers.net. 172800 IN A 192.35.51.30
f.gtld-servers.net. 172800 IN AAAA 2001:503:d414::30
a.gtld-servers.net. 172800 IN A 192.5.6.30
a.gtld-servers.net. 172800 IN AAAA 2001:503:a83e::2:30
g.gtld-servers.net. 172800 IN A 192.42.93.30
g.gtld-servers.net. 172800 IN AAAA 2001:503:eea3::30
h.gtld-servers.net. 172800 IN A 192.54.112.30
h.gtld-servers.net. 172800 IN AAAA 2001:502:8cc::30
l.gtld-servers.net. 172800 IN A 192.41.162.30
l.gtld-servers.net. 172800 IN AAAA 2001:500:d937::30
k.gtld-servers.net. 172800 IN A 192.52.178.30
k.gtld-servers.net. 172800 IN AAAA 2001:503:d2d::30
c.gtld-servers.net. 172800 IN A 192.26.92.30
c.gtld-servers.net. 172800 IN AAAA 2001:503:83eb::30
d.gtld-servers.net. 172800 IN A 192.31.80.30
d.gtld-servers.net. 172800 IN AAAA 2001:500:856e::30
;; Query time: 401 msec
;; SERVER: 198.41.0.4#53(198.41.0.4)
;; WHEN: Wed Nov 25 18:12:00 -03 2020
;; MSG SIZE rcvd: 828
蟋蟀!信息量好大!我们收到了13个机构的记录com
,还有一部分包含了所有机构的IP地址。
这 13 台域名服务器都记录了下所有注册域名的记录com
。真的!
⌨️com
向名称服务器询问ianjmacintosh.com
其名称服务器记录(+norecurse
像往常一样)
dig @192.31.80.30 ianjmacintosh.com NS +norecurse
192.31.80.30
是我们请求顶级域名的名称服务器记录的服务器com
。- 我本来可以轻松地使用
d.gtld-servers.net
它并让 dig 在后台找到它的 IP 地址,但由于我已经有了 IP 地址,所以我使用了它。
- 我本来可以轻松地使用
ianjmacintosh.com
是我们要求的记录的名称NS
是“名称服务器”的缩写+norecurse
避免192.31.80.30
进行递归搜索
ianjmacintosh.com
从报告中获取名称服务器
; <<>> DiG 9.10.6 <<>> @192.31.80.30 ianjmacintosh.com NS +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 30145
;; flags: qr; QUERY: 1, ANSWER: 0, AUTHORITY: 4, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;ianjmacintosh.com. IN NS
;; AUTHORITY SECTION:
ianjmacintosh.com. 172800 IN NS dns1.p03.nsone.net.
ianjmacintosh.com. 172800 IN NS dns2.p03.nsone.net.
ianjmacintosh.com. 172800 IN NS dns3.p03.nsone.net.
ianjmacintosh.com. 172800 IN NS dns4.p03.nsone.net.
;; Query time: 411 msec
;; SERVER: 192.31.80.30#53(192.31.80.30)
;; WHEN: Wed Nov 25 18:37:01 -03 2020
;; MSG SIZE rcvd: 135
这四个域名服务器中的任何一个都可以为我提供 的更多记录信息www.ianjmacintosh.com
。请选择一个用于您的下一个查询,我们快完成了!
⌨️ianjmacintosh.com
向名称服务器查询www.ianjmacintosh.com
ʼ 的A
记录 ( +norecurse
)
dig @dns1.p03.nsone.net www.ianjmacintosh.com A +norecurse
dns1.p03.nsone.net
是我们请求顶级域名的名称服务器记录的服务器com
。- 你可以看到我又偷懒了,让 dig 找到
dns1.p03.nsone.net
- 你可以看到我又偷懒了,让 dig 找到
www.ianjmacintosh.com
是我们要求的记录的名称A
是“address”的缩写+norecurse
避免dns1.p03.nsone.net
进行递归搜索——并不是说必须这样做
💰 找到www.ianjmacintosh.com
; <<>> DiG 9.10.6 <<>> @dns1.p03.nsone.net www.ianjmacintosh.com A +norecurse
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 25003
;; flags: qr aa; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;www.ianjmacintosh.com. IN A
;; ANSWER SECTION:
www.ianjmacintosh.com. 20 IN A 18.230.52.212
www.ianjmacintosh.com. 20 IN A 54.207.147.214
;; Query time: 31 msec
;; SERVER: 198.51.44.3#53(198.51.44.3)
;; WHEN: Wed Nov 25 18:40:39 -03 2020
;; MSG SIZE rcvd: 82
你成功了!你获取了托管服务器的 IP 地址www.ianjmacintosh.com
。在答案部分,你会看到和我们第一次挖掘报告中看到的相同的 IP 地址:18.230.52.212
&54.207.147.214
为了好玩,您可以使用+trace
查询选项运行 dig 来观察 dig 自动迭代所有这些步骤:
dig www.ianjmacintosh.com +trace
结论
哇,真是太多了!每当你尝试访问网站时,你的电脑都会在后台自动完成所有这些操作。恭喜你,现在你对 DNS 的了解已经远远超过了大多数人。
还有很多东西需要学习,但这是一个很好的起点。我计划撰写后续文章,探索更多 DNS 的奥秘,包括什么是 CNAME、如何更新记录,以及如何处理一些常见的配置错误。
如果您只是浏览了本文,没有运行任何命令,并且希望对 DNS 更加熟悉,那也没关系!希望您能尽快回来阅读本文并逐步完成相关步骤。在此之前,以下是一些快速入门指南:
- DNS 就像“互联网的电话簿”,只是在最模糊的类比意义上;它更像一棵树,回答查询需要从根部到分支再到分支
- DNS 代表“域名系统”
- 默认情况下,DNS 消息通过端口 53 传递
- dig 是一个有用的 DNS 诊断工具,是 BIND 的一部分
- BIND 代表“伯克利互联网名称域名”,是最初在加州大学伯克利分校开发的域名工具集合
- BIND 最引人注目的应用程序是其非常流行的名称守护进程服务器(容易混淆的称为
named
“name D”,是“name dameon”的缩写),它可以响应 DNS 请求
附加信息
为什么域树是从右到左书写的(subdomain.domain.com
),而路径是从左到右书写的(/users/~imacintosh/articles/dns-for-web-developers
)?
好问题。我还没找到满意的答案。问答论坛上的常见解释指出,电子邮件地址(user@host
)的工作原理与此类似,只是从更具体到更不具体。Jon Postel在 1982 年“网络工作组”会议上的记录表明,该小组试图做出那些实施挑战最少的决策。这似乎就是这样一个决定,但我不明白其中的原因。
不管怎样,蒂姆·伯纳斯·李在一次采访中提到,如果他能回到过去,做些不同的事情,他会把域名整理com.domain.subdomain
好。🤷🏻♂️
所以基本上整个互联网都是在 13 个不同的根 DNS 服务器上运行的?
不!这其实是 13 个不同的 IP 地址,但响应这些请求的服务器数量要多得多;在我撰写本文时,已经有超过 1300 个服务器,而且它们分布在世界各地。根服务器主页上有一张清晰的地图,显示了它们的位置。如果您想了解多个系统如何共享一个 IP 地址,可以查找“任播”。
如果18.230.52.212
是服务器托管的 IP 地址www.ianjmacintosh.com
,为什么我访问您的网站时会收到奇怪的错误消息而不是?
18.230.52.212 的服务器服务于很多网站,不仅仅是我的网站。该服务器需要知道你请求的是哪个网站。当你在浏览器中访问www.ianjmacintosh.com时,它会告诉 18.230.52.212 的服务器访问www.ianjmacintosh.com。当你访问18.230.52.212时,它可能并不知道你想要访问什么。
文章来源:https://dev.to/ianjmacintosh/dns-for-web-developers-5fe