前言

一直以來都只知道 DNS 是負責將域名(domain name)轉換成 ip 的網路服務,讓人類不需要去記又臭又長又難記的 ip,可以更輕鬆地透過類似門牌的域名來記憶網址.但隨著開發經驗愈來愈多之後,碰到各種網路上的問題,這時候就覺得自己懂的太少了,所以有了這篇來督促自己更深入的了解一下 DNS,以及它背後的其他元件.

主要的四種 DNS servers

dns_servers

圖片參考:cloudflare

DNS server 又分成四種,各司其職的來完成 DNS Lookup

Recursive Resolver

  • 是 DNS Lookup 的第一步
  • 當 client 遞迴的發送請求給 Recursive Resolver,他就會繼續往下一個 DNS server 發送請求來獲取 DNS record,直到 timeout 拋出錯誤或是成功找到 DNS record
  • 為了避免同個 DNS record 每次都被 client 反覆請求,DNS 會有快取的機制以迅速回應相同的 DNS Lookup

若以圖書館來比喻,Recursive Resolver 就像是圖書館的管理員

Root Nameserver

  • 是 DNS Resolve(Translate)的第一步
  • 遵照 Recursive Resolver 想查找的 DNS record,去問下一個 TLD Nameserver

若以圖書館來比喻,Root Nameserver 就像是圖書館的索引(index),指向不同書架上的書

TLD Nameserver

  • TLD(top level domain)是一個網域的頂級網域,以 example.com 的 TLD 就是 com
  • 承接 Root Nameserer 來的請求,更明確的去查找某個 IP 位址

若以圖書館來比喻,TLD Nameserver 就像是圖書館上特定的書架

Authoritative Nameserver

  • DNS Lookup 查找的最後一站
  • Authoritative Nameserver 握有該 DNS record 對應的 IP 位址,查到之後就會將該 IP 位置回傳給 Recursive Resolver(圖書館管理員),以利瀏覽器對該 IP 位址後的 server 發送請求,獲取前端頁面並渲染

若以圖書館來比喻,Authoritative Nameserver 就像是圖書館上某書架上的字典

dns-demo

圖片參考:cloudflare

整體發送請求如下:

  1. 使用者在瀏覽器上輸入 example.com,DNS 請求將會透過網路傳遞到 DNS recursive resolver
  2. recursive resolver 將會再去詢問 root nameserver (.)
  3. root nameserver 回傳頂級網域 TLD .com 給 recursive resolver
  4. recursive resolver 再去詢問 TLD nameserver .com 的位址
  5. TLD nameserver 回傳 .com 的 IP 位址給 recursive resolver
  6. recursive resolver 再去詢問 Authoritative Nameserver example.com 的位址
  7. Authoritative Nameserver 回傳找到對應的 IP 給 recursive resolver
  8. recursive resolver 再把查到的 example.com 的 IP 位址回傳給瀏覽器
  9. 瀏覽器發送 HTTP 請求給該 IP 位址
  10. 將 server 回傳的 HTML 選染在網頁前端

常見的 DNS 名詞

A record vs AAAA record

A record 是用來指向特定 domain 的 IP,其中的 A 代表 address,是 DNS record 中最基本的一類,A record 只負責 IPv4 的 address,如果某網址是 IPv6 的 address,取而代之的是使用 AAAA record

大部分網站都只會有唯一一個 A record,但有時候會有多個 A record 的可能性,擁有多個 A record 的網站就能完成所謂的 round robin load balancing,分散流量到任一個 IP address

CNAME

CNAME 全名是 canonical name,當某網域或子網域是隸屬於另一個網域的話,則 CNAME 就是指向另一個網域的用途,值得注意的是,CNAME 和 A record 最大的差別就是他只指向 domain 而非 IP

舉例來說,假設 blog.example.com有一個 CNAME 指向example.com,當 DNS 查詢遇到blog.example.com網站時,將會繼續往 CNAME 指向的example.com查詢,最終透過example.com的 A record 回傳example.com的 IP,此時我們會稱example.comblog.example.com的 CNAME

blog.example.com --CNAME--> example.com --A record--> IP Address

有時候,subdomains 會具有指向 root domain 的 CNAME.這樣有個好處,當某個 IP Address 的 host name 改變了,只有該 root domain 的 A record 需要改動,其餘子網域指向根網域的 CNAME 都不用更動,另外,CNAME 也有可能指向另一個 CNAME,但是這樣會沒效率,因為多了一道 DNS 的 lookup

ACME-Challenge

ACME 全名是 Automatic Certificate Management Environment,本身是一個通訊協定(protocal),是一種用於自動化證書頒發機構與其用戶服務器之間的交互的通信協議,允許以非常低的成本自動部署公鑰基礎設施(PKI)。而 Let’s Encrypt 就是透過 ACME 的標準來認證該使用者是否具有該網域的擁有權

簡單來說,當 Let’s Encrypt 簽發憑證給我們後,Let’s Encrypt 的伺服器將會用符合 ACME 標準的考驗,來驗證我們是否擁有目前網域的所有權,考驗有以下幾種:

HTTP-01 考驗

以下節錄至 Lets Encrypt 的 官方文件

這是現今最常見的一種驗證方式。Let’s Encrypt 給予 ACME 客戶端一個 token,請 ACME 客戶端將包含 token 和帳號金鑰指紋的檔案,放到網頁伺服器中 http://<YOUR_DOMAIN>/.well-known/acme-challenge/<TOKEN> 的位置。當 ACME 客戶端通知 Let’s Encrypt 這個檔案已經放置完成,Let’s Encrypt 就會試著取得它(可能會從多個主機嘗試取得數次)。如果我們能從你的網頁伺服器取得檔案並驗證其內容,你就通過了這個考驗,你可以接著向我們申請憑證頒發。如果我們的驗證失敗,你就必須重來一次

一般來說,都會以這個方式來考驗,因為設置上較方便

DNS-01 考驗

以下節錄至 Lets Encrypt 的 官方文件

這個考驗會請你在網域的 TXT 紀錄中,放一段特定的文字,來證明你擁有此網域的 DNS 控制權

在 Let’s Encrypt 給予 ACME 客戶端 token 後,客戶端會拿 token 與帳號金鑰進行運算,並產生一段文字,請將這段文字利用 TXT 紀錄放在 DNS 的主機名稱 _acme-challenge.<YOUR_DOMAIN> 底下。

如果要申請的是萬用憑證,就只能使用這種方式來驗證

以上考驗機制有更多說明,請參考 Let’s Encrypt 的官方文件,講解得非常清楚,又有正體中文閱讀起來很輕鬆

結論

本文稍微簡單的整理一下 DNS 的 lookup 機制和其他相關的機制,最終只需要記得以下兩個名詞跟他們的差異就好

  • CNAME: 指向 domain
  • A record: 指向 IP.A record指向 IPv4,AAAA record指向 IPv4
  • ACME Challenge: 用於驗證該網域確實是被某使用者所擁有的一系列考驗

在使用第三方 DNS Provider 時,常會需要設定這些參數來將某網址指向另一個網址,稍微了解這幾個名詞之後,往後設定上會更有感覺,也會更知道自己到底在設定什麼