DNS的更新是如何工作的?

最近看到大神的一篇关于DNS的文章,感觉很不错,所以自己翻译了一下。

SMJ
loading... read

⚠️ This post was last updated on June 9, 2021 and the content may be OUTDATED!

If you encounter any issues, please feel free to reachout to me!

最近看到大神的一篇关于DNS 的文章,感觉很不错,所以自己翻译了一下。
如有错误,欢迎指正。

我已经看到很多人对更新站点的 DNS 记录以更改 IP 地址感到困惑。为什么这么慢?是否真的需要等待 2 天才能更新所有内容?为什么有些人看到新 IP,有些人看到旧 IP?发生了什么?

这里记录一下更新 DNS 背后所发生了些什么。

DNS 的分类:递归 vs 权威 DNS 服务器

首先,我们需要解释一些有关 DNS 的知识。DNS 服务器有两种:权威服务器和递归服务器。

权威DNS 服务器(也称为名称服务器)具有一个负责其每个域名的 IP 地址数据库。例如,github.com 的权威 DNS 服务器是 ns-421.awsdns-52.com。你可以通过 dig 命令来获取 github.com 的 IP。

dig @ns-421.awsdns-52.com github.com

递归DNS 服务器本身对谁拥有什么 IP 地址一无所知。它们通过询问正确的权威 DNS 服务器来确定域名的 IP 地址,然后缓存该 IP 地址,以防再次被问到。8.8.8.8 是递归 DNS 服务器。

当人们访问你的网站时,他们可能正在对递归 DNS 服务器进行 DNS 查询。那么,递归 DNS 服务器如何工作?让我们来看看!

递归 DNS 服务器如何查询 github.com?

我们来看一个递归 DNS 服务器(如 8.8.8.8)在你请求 github.com 的 IP 地址(A 记录)时的功能的示例。首先–如果已经缓存了某些内容,它将为您提供缓存的内容。但是,如果所有缓存均已过期怎么办?这是发生了什么:

步骤 1:在源代码中硬编码根 DNS 服务器的 IP 地址。您可以在unbound 的源代码中看到这一点。假设198.41.0.4从开始就选择。这是这些硬编码 IP 地址的正式来源,也称为“根目录提示文件”。

步骤 2:向根域名服务器查询github.com

我们可以大致再现发生的情况dig。这给我们提供了一个新的权威名称服务器:.comIP 的名称服务器192.5.6.30

$ dig @198.41.0.4 github.com
...
com.            172800  IN  NS  a.gtld-servers.net.
...
a.gtld-servers.net.    172800  IN  A   192.5.6.30
...

DNS 响应的详细信息比这要复杂一些–在这种情况下,其中有一个具有一些 NS 记录的授权部分,而另一个具有 A 记录的部分,因此您无需进行额外的查找即可获得这些名称服务器 IP 地址。

(实际上,它已经有 99.99%的时间已经缓存了.com名称服务器的地址,但是我们假装实际上是从头开始的)

步骤 3:向.com域名服务器查询有关github.com

    $ dig @192.5.6.30 github.com
    ...
    github.com.        172800  IN  NS  ns-421.awsdns-52.com.
    ns-421.awsdns-52.com.    172800  IN  A   205.251.193.165
    ...

我们有一个新的 IP 地址要询问!这是github.com的名称服务器。

步骤 4:向github.com域名服务器询问有关github.com

    $ dig @205.251.193.165 github.com

    github.com.        60  IN  A   140.82.112.4

OK!我们现在有一个github.comA记录!现在,递归名称服务器具有github.com的 IP 地址,可以将其返回给您。它通过仅硬编码几个IP 地址即可完成所有这些操作:即根名称服务器的地址。

如何查看所有递归 DNS 服务器: dig+trace

当我想查看解析一个域名时递归 DNS 服务器将执行的操作,我运行以下命令:

    $ dig @8.8.8.8 +trace github.com

这显示了它请求的所有 DNS 记录,从根 DNS 服务器开始—我们刚刚完成的所有 4 个步骤。

如何更新 DNS 记录

既然我们了解了 DNS 工作原理,那么让我们更新一些 DNS 记录,看看会发生什么。

更新 DNS 记录时,有两个主要选项:

  1. 保持相同的名称服务器
  2. 更改名称服务器

关于 TTL

这里我们先说明一下 TTL 这个概念,我们之前说过递归 DNS 服务器将缓存记录直到它们过期,而决定记录是否应过期的方式是查看其TTL(Time To Live)

下面的示例中,A 记录 github 的名称服务器为其 DNS 记录返回的 TTL 为60,这意味着 60 秒:

    $ dig @205.251.193.165 github.com
    github.com.        60  IN  A   140.82.112.4

这是一个非常短的 TTL,*从理论上讲,*如果每个人的 DNS 实施都遵循DNS 标准,则意味着如果 Github 决定更改 IP 地址github.com,则每个人都应在 60 秒内获得新的 IP 地址。让我们看看实际情况如何。

选项 1:在相同的名称服务器上更新 DNS 记录

首先,我更新了我的名称服务器(Cloudflare),使其具有新的 DNS 记录:映射test.jvns.ca到的 A 记录 1.2.3.4

    $ dig @8.8.8.8 test.jvns.ca
    test.jvns.ca.        299 IN  A   1.2.3.4

这会立即生效!根本不需要等待,因为test.jvns.ca在可以缓存之前没有 DNS 记录。但是看起来新记录被缓存了大约 5 分钟(299 秒)。

那么,如果我们尝试更改该 IP 怎么办?我将其更改为5.6.7.8,然后运行了相同的 DNS 查询。

    $ dig @8.8.8.8 test.jvns.ca
    test.jvns.ca.        144 IN  A   1.2.3.4

嗯,好像 DNS 服务器的1.2.3.4记录仍在缓存 144 秒。有趣的是,如果我8.8.8.8多次查询实际上却得到不一致的结果–有时它会给我新的 IP,有时会给我旧的 IP,我想是因为 8.8.8.8 实际上将负载平衡到一堆不同的后端,每个后端都有自己的缓存。

我等了 5 分钟后,所有8.8.8.8缓存均已更新,并且始终返回新5.6.7.8记录。不得不说,这相当的快!

你不能总是依靠 TTL

与大多数 Internet 协议一样,并非所有内容都遵循 DNS 规范。某些 ISP DNS 服务器将缓存记录的时间长于 TTL 指定的时间,例如 2 天而不是 5 分钟。人们总是可以在/etc/hosts 中对旧 IP 地址进行硬编码。

在使用 5 分钟的 TTL 更新 DNS 记录时,我期望在实践中会发生的事情是,很大比例的客户端会迅速(例如在 15 分钟之内)移到新 IP,然后会有一些慢的客户端在接下来的几天内会慢慢更新。

选项 2:更新名称服务器

我们已经看到,当您在不更改名称服务器的情况下更新 IP 地址时,许多 DNS 服务器将很快获取新 IP。但是,如果您更改名称服务器会怎样?

我不想更新我的博客的域名服务器,所以不是我用不同的域名然后用在HTTP 杂志作为示例:examplecat.com

以前,我的名称服务器设置为 dns1.p01.nsone.net。我决定将它们切换到 Google 的名称服务器-ns-cloud-b1.googledomains.com等等。

进行更改后,我的域名注册商有点不愉快地弹出了消息-“对 examplecat.com 的更改已保存。它们将在接下来的 48 小时内生效。” 然后,我为该域设置了一个新的 A 记录,使其指向1.2.3.4

OK,让我们看看是否有任何作用:

    $ dig @8.8.8.8 examplecat.com
    examplecat.com.        17  IN  A   104.248.50.87

没变化。如果我询问其他 DNS 服务器,它将返回新 IP 地址:

    $ dig @1.1.1.1 examplecat.com
    examplecat.com.        299 IN  A   1.2.3.4

但是 8.8.8.8 仍然毫无变化。即使我在 5 分钟前刚刚更改它,1.1.1.1 能看到新 IP 的原因大概是以前没有人向 1.1.1.1 询问过 examplecat.com,因此它的缓存中没有任何内容。

名称服务器的 TTL 更长

我的注册服务商说“这将花费 48 小时”的原因是 NS 记录上的 TTL(这是递归名称服务器如何知道要询问哪个名称服务器)更长!

新的域名服务器肯定会返回新的 IP 地址 examplecat.com

    $ dig @ns-cloud-b1.googledomains.com examplecat.com
    examplecat.com.        300 IN  A   1.2.3.4

但是还记得当我们查询github.com域名服务器时发生了什么吗?

    $ dig @192.5.6.30 github.com
    ...
    github.com.        172800  IN  NS  ns-421.awsdns-52.com.
    ns-421.awsdns-52.com.    172800  IN  A   205.251.193.165
    ...

172800 秒是 48 个小时!因此,与不更改名称服务器而仅更新 IP 地址相比,名称服务器更新通常需要更长的时间才能从缓存中到期并传播使用。

域名服务器如何更新?

当我更新的域名服务器时examplecat.com,发生的事情是 .com域名服务器获得了NS新域名的新记录。像这样:

    dig ns @j.gtld-servers.net examplecat.com

    examplecat.com.        172800  IN  NS  ns-cloud-b1.googledomains.com

但是,新的 NS 记录如何到达那里?发生的事情是,我通过在网站上更新域名告诉域名注册商我希望新的域名服务器是什么,然后域名注册商告诉.com域名服务器进行更新。

对于.com,这些更新发生的速度非常快(在几分钟之内),但是我认为对于其他一些 TLD,TLD 域名服务器可能无法尽快应用更新。

程序的 DNS 解析器库可能还会缓存 DNS 记录

实际中可能不遵守 TTL 的另一个原因:许多程序需要解析 DNS 名称,并且某些程序还将无限期地将 DNS 记录缓存在内存中(直到程序重新启动)。

例如,AWS 有一篇关于为 DNS 名称查找设置 JVM TTL的文章。我没有编写太多可以自己进行 DNS 查找的 JVM 代码,但是通过对 JVM 和 DNS 的一些仔细研究,似乎可以配置 JVM,以便它无限期地缓存每个 DNS 查找。(例如此 elasticsearch 问题

p.s. TTL 不能说明 DNS 工作原理的全部–即使像 8.8.8.8 这样的主要 DNS 服务器,某些递归 DNS 服务器也绝对不尊重 TTL。因此,即使您只是用短的 TTL 更新 A 记录,实际上还是很有可能在一两天内收到对旧 IP 的一些请求。

参考

https://jvns.ca/blog/how-updating-dns-works

Sooner or later, everything ends.