xChar
·a year ago

最近看到大神的一篇关于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


首发于个人博客:方寸之间

Loading comments...