當你更新你的 DNS 時會發生什麼

當你更新你的 DNS 時會發生什麼

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

關於 DNS 的基礎知識,可參考阮大佬的: DNS 原理入門

以下爲正文:


我看到過許多人對更新他們站點的 DNS 記錄以改變 IP 地址而感到困惑。爲什麼這麼慢?你真的會花費2天的時間等待所有的數據更新嗎?爲什麼有的人會看到新的 IP 而有些人會看到舊的 IP?到底發生了什麼?

所以我想快速探索一下當你更新 DNS 時幕後所發生的一切。

DNS 如何工作:遞歸解析器 vs 權威域名服務器

首先,我們需要了解一點關於 DNS 的知識。DNS 服務器有兩種:權威域名服務器(authoritative) 和 遞歸解析器(recursive)。

權威域名 DNS 服務器(也叫根域名服務器)有一個其所負責域的 IP 地址數據庫。比如,目前 github.com 的權威域名服務器是 ns-421.awsdns-52.com。你可以獲取 github.com 的 IP 地址像這樣:

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

遞歸 DNS 解析器本身並不知道某一域名對應什麼樣的地址。它們通過詢問正確的權威域名 DNS 服務器來獲取對應的 IP 地址,接下來緩存這個 IP 地址,以便它們再次訪問。8.8.8.8 是一個遞歸解析器。

當人們訪問你的網站,他們可能會在遞歸解析器上查詢。所以它是怎麼工作的?一起來看!

遞歸 DNS 解析器如何查詢 github.com?

可以通過一個例子來了解當你訪問 github.com 的 IP 地址(A 記錄)時遞歸解析器(比如8.8.8.8)做了什麼。首先,如果它已經緩存了這些數據,那麼將會直接使用緩存中的數據。但是如果所有的緩存都失效了該怎麼辦?它會做如下工作:

  1. 它的源代碼中有根 DNS 服務器的 IP 地址。你可以參閱 [unbound’s source code here](unbound’s source code here) 。假如從 198.41.0.4 開始。下面有一些硬編碼 IP 地址的官方來源: official source ,也稱爲『根提示文件』。

  2. 詢問根域名服務器中的 github.com

    我們可以大致地重現使用 dig 時發生了什麼,告訴了我們一個新的權威域名服務器,一個 IP 地址爲 192.5.6.30.com 域名服務器。

    $ 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(name server) 記錄,另外一個部分包含 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
    

    成功了!我們得到了 github.comA 記錄!現在遞歸域名服務器取到了 github.com 的 IP 地址,並將其返回給了你。它可以僅通過硬編碼幾個 IP 地址(即根域名服務器)來實現所有的這些工作。

如何查看所有的遞歸 DNS 服務器的流程:dig +trace

當我想要了解一個遞歸服務器在解析一個域名時會做什麼,我會運行:

$ dig @8.8.8.8 +trace github.com

它會打印出請求的所有 DNS 記錄(從根 DNS 服務器開始,會經過我們剛剛探討過的4步)。

讓我們來更新一些 DNS 記錄

現在我們知道了 DNS 基本的工作流程,讓我們更新一些 DNS 記錄,看看會發生什麼。

當你更新你的 DNS 記錄時,主要有兩個選擇:

  1. 不修改名稱服務器
  2. 修改名稱服務器

談談 TTLs (time to live)

我們忘記了一些重要的事情!TTLs!你還記得前面說過的遞歸 DNS 服務器將緩存記錄直到這些記錄過期嗎?服務器決定一個記錄是否過期應該去查看它的 TTL 或者”生存時間“。

下面的例子中,github 名稱服務器爲 DNS 記錄返回的 A 記錄的 TTL 是60,意味着 60 秒:

$ dig @205.251.193.165 github.com

github.com.		60	IN	A	140.82.112.4

這是一個非常短的 TTL,從理論上講,如果每個人的 DNS 實現都遵循 DNS 標準,那麼意味着如果 Github 決定改變 github.com 的 IP 地址,每個人都應該在 60 秒內得到新的 IP 地址。讓我們來看看實際情況如何。

選擇1 :更新同一名稱服務器上的一條 DNS 記錄

首先,我更新了我的名稱服務器(Cloudflare)中的一條新 DNS 記錄:一個映射 test.jvns.ca1.2.3.4

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

緊接着就起作用了!根本不用等待,因爲之前沒有緩存過 test.jvns.ca 。但是新紀錄的緩存時間大約爲5分鐘(299秒)。

如果嘗試更改這個 IP 會發生什麼呢?我將 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 仍舊緩存了144秒的 1.2.3.4 。有趣的是,如果我多次查詢 8.8.8.8 將會得到不一樣的結果:有時候返回了新的 IP ,有時候是舊的 IP,我猜測 8.8.8.8 事實上負載平衡到不同的後端,每個後端服務器都有自己的緩存。

等待了5分鐘後,所有的 8.8.8.8 都返回了剛剛新緩存的 5.6.7.8 IP 記錄。Awesome,這實在是太快了!

你不能一直依賴 TTL

與大多數 Internet 協議一樣,並非所有的協議都遵守 DNS 規範。一些 ISP DNS 服務器緩存的時間超過了 TTL 規定的時間,比如兩天而不是5分鐘。人們總是可以在他們的 /etc/hosts 中硬編碼舊的 IP 地址。

在實際使用中我希望我用 5 分鐘的 TTL 更新 DNS 記錄時,大部分客戶端會快速遷移到新的 IP(比如在15分鐘內),然後剩餘的客戶端會在接下來的幾天內陸續更新到新的 IP。

選擇 2:更新你的名稱服務器

剛剛我們瞭解了,當你沒有改變你的名稱服務器時更新了一條 IP 地址,許多 DNS 服務器將很快更新到新的 IP 地址。但是當你更新你的名稱服務器時會發生什麼?讓我們來試試!

我不想更新我博客的名稱服務器,所以我使用我的另一個域名,並在 HTTP zine 示例中使用了它: examplecat.com

之前我的名稱服務器是 dns1.p01.nsone.net。我決定換成谷歌的名稱服務器—— ns-cloud-b1.googledomains.com 等。

當我做了改變,我的域名註冊商有點不高興地彈出消息——”examplecat.com 已更改,將在48小時內生效“。接下來我爲域名設置了一個新的 A 記錄,指向 1.2.3.4

好的,讓我們看看是否有作用

$ 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 ,所以它的緩存中沒有該數據。

名稱服務器 TTLs 的時間更長

之所以我的域名註冊商說”這將會在48小時內生效“,是因爲 NS 記錄中的 TTLs (這是遞歸服務器用來知道該查詢哪個名稱服務器的)要長的多。

新的名稱服務器肯定會返回 examplecat.com 的新 IP 地址

$ 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 來說,更新是非常快的(在幾分鐘內),但是我認爲對一些其它的 TLDs(頂級域名),TLD 名稱服務器可能不會響應的很快。

你的項目的 DNS 解析器庫可能也會緩存 DNS 記錄

TTLs 在實際中不被遵守的另一個原因是:許多程序需要解析 DNS 名稱,並且一些程序會在內存中無期限地緩存 DNS 記錄(直到程序被重啓)。

舉例來說,AWS 有一篇文章: Setting the JVM TTL for DNS Name Lookups 。我還沒有寫過很多用於 DNS 查找的 JVM 代碼。但是稍微搜索一下 JVM 和 DNS,似乎可以配置 JVM,使其無期限地緩存每個 DNS 查找(比如 this elasticsearch issue )。

以上就是全部了!

我希望這篇文章可以幫助你理解當更新你的 DNS 時發生了什麼!

再次做爲免責聲明—— TTLs 不能絕對說明 DNS 的全部流程——一些遞歸服務器顯然不會遵守 TTLs,即使像 8.8.8.8 這樣的主地址也是如此。所以即使你只是用一個短 TTL 更新了一個 A 記錄,實際上還是很有可能在一兩天內仍舊獲得的是舊 IP 地址。

另外,在發佈完這篇文章後,我將 examplecat.com 的名稱服務器修改回了原來的值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章