跳轉到

2.1 DNS 原理:遞迴查詢、TTL 與全球分散式資料庫#

本節目標#

  • 理解 DNS 誕生的歷史動機:為什麼 1983 年的網際網路需要放棄單一 hosts.txt
  • 掌握 DNS 的樹狀命名空間與委派(delegation)模型
  • 能完整推演一次「遞迴 vs 迭代」查詢的封包流程
  • 認識 TTL 的語意、常用記錄型別,以及 DNSSEC 為何存在

歷史:從 hosts.txt 到分散式資料庫#

在 DNS 出現之前,整個 ARPANET 的主機名稱對照表只有一份:史丹福研究院(SRI-NIC)維護的 HOSTS.TXT 檔案。每台主機定期從 SRI 下載整份檔案。1980 年代初,這個設計瀕臨崩潰:

問題 說明
單點故障 SRI-NIC 當機,全網名稱解析失效
流量瓶頸 所有主機輪番下載,SRI 頻寬吃緊
一致性延遲 修改要等全網同步,可能有數天落差
命名衝突 沒有層級機制,名稱是全域扁平的

Paul Mockapetris 在 1983 年發表 RFC 882/883(後被 RFC 1034/1035 取代),提出 DNS:一個階層式、分散式、可快取的資料庫。它不是靠「一份大表」,而是靠「每個區域的管理者只負責自己那一層」。這個設計放到四十年後的今天依然成立——Cloudflare 的權威 DNS 服務,本質上就是當年設計的商業化實現。

樹狀命名空間#

DNS 名稱空間是一棵以空標籤(root)為根的樹:

                    (root, ".")
                    /   |    \
                 com   org    tw ...
                /  \          /
           google  cloudflare  edu
              |                  \
        blog.example.com     ntu

blog.example.com. 這個完整的 FQDN(Fully Qualified Domain Name)由右至左逐層變寬:

層級 節點 誰管理
根 . IANA / 根伺服器營運組織(13 個字母身份,數千台 anycast 節點)
TLD com / tw Verisign、TWNIC 等註冊管理機構
網域 example.com 你(透過 Registrar 註冊取得)
子網域 blog 你自由定義,想幾層就幾層

關鍵洞察:每一層不是「知道全部答案」,而是「知道往哪裡問」。根不知道 blog.example.com 的 IP,但知道 .com 的伺服器在哪;.com 的伺服器知道 example.com 的權威 DNS 在哪——這就是委派(delegation)。

遞迴 vs 迭代:一次查詢的完整旅程#

DNS 查詢有兩種角色:

  • 遞迴查詢(Recursive):客戶端把責任整包丟給 resolver(如 8.8.8.8、Cloudflare 1.1.1.1),resolver 必須「問到底」。
  • 迭代查詢(Iterative):resolver 對每層權威伺服器只問一次,對方回「下一個該問誰」。

Resolver 內部其實是「接收遞迴、發出迭代」:

[瀏覽器]          [本機 resolver / ISP]        [權威 DNS 伺服器群]
   |                    |                          |    
   | 1.遞迴查詢          |                          |
   | blog.example.com   |                          |
   |------------------->|                          |
   |                    | 2.問根: blog.example.com? |
   |                    |-------------------------> (root)
   |                    |   回答: 去問 .com (NS)     |
   |                    |<-------------------------|
   |                    | 3.問 .com 權威            |
   |                    |-------------------------> (gtld)
   |                    |   回答: 去問 ns.example.com|
   |                    |<-------------------------|
   |                    | 4.問 example.com 權威     |
   |                    |-------------------------> (權威)
   |                    |   回答: A 203.0.113.7     |
   | 5.回傳 IP + 快取    |<-------------------------|
   |<-------------------|                          |
   | 6.用 IP 建立 TCP 連線                           |

步驟 5 之後,resolver 會把答案快取起來——這就是 DNS 能撐住全網流量的秘密:絕大多數查詢根本到不了權威伺服器。

TTL:快取的租約期限#

每筆 DNS 記錄都附帶 TTL(Time To Live),語意是「這個答案你最多可以信任 N 秒」:

TTL 設定 效果 適合情境
300 秒(5 分鐘) 變更快速生效,查詢負載高 遷移 IP 期間、DDNS
3600 秒(1 小時) 一般網站的平衡點 常態營運
86400 秒(1 天) 權威負載最低,但改錯要等一天 超穩定的 IP

工程上重要的一課:TTL 是租約,不是指令。把 TTL 從 86400 改成 300 後,舊 TTL 仍會在快取裡停留最多 24 小時——所以任何 IP 遷移都要「先降 TTL、等一個舊 TTL 週期、再改 IP」。Cloudflare 代理(橘雲)開啟時,對外 TTL 固定為 300 秒且由 Cloudflare 控管,這是我們選 Cloudflare 託管 DNS 的便利之一。

常用記錄型別#

型別 語意 範例
A 名稱 → IPv4 位址 example.com → 203.0.113.7
AAAA 名稱 → IPv6 位址 example.com → 2001:db8::7
CNAME 別名,指向另一個名稱(解析時再追查) www.example.com → example.com
TXT 自由文字,用於 SPF 驗證、憑證簽發證明等 "v=spf1 include:_spf.google.com ~all"
NS 指定該區域的權威 DNS 伺服器(委派的錨點) example.com. NS ns1.cloudflare.com.
MX 收該網域信件的郵件伺服器優先序 10 mail.example.com.

兩個容易踩的規則:

  1. CNAME 不能與其他記錄共存:example.com 若被 CNAME 指走,就不能再有 MX。這也是為什麼根網域(apex)通常用 A/AAAA 而不是 CNAME——DNS RFC 的歷史限制。Cloudflare 的 CNAME Flattening 技術在回應時把 CNAME 攤平成 A 記錄,繞過了這個限制。
  2. 查 CNAME 是一次新的解析流程:alias 不是答案,是「下一個問題」。

用 dig 實際觀察#

$ dig +noall +answer +authority blog.example.com

blog.example.com.   300  IN  A     203.0.113.7
example.com.        3600 IN  NS    ns1.cloudflare.com.
#   ^ TTL            ^ IN 是 class "Internet"  ^ 答案

300 就是快取租約——你自己架伺服器時看到的所有 DNS 行為,都可以用 dig 驗證,不用猜。

DNSSEC:替 DNS 加上簽章#

DNS 誕生時沒有任何認證機制:任何攔截到查詢的人都可以回一個假 IP(DNS cache poisoning / 劫持)。DNSSEC(RFC 4033-4035)的解法是公鑰簽章鏈:根的 KSK 簽 .com 的 key,.com 簽 example.com 的 key,層層簽下去,resolver 用 DS 記錄逐級驗簽。它不加密內容,只保證「記錄沒被竄改」。

Cloudflare 在 DNS 面板可一鍵啟用 DNSSEC,再把產生的 DS 記錄提交給你的 Registrar 即完成鏈結——這一步在 2.2 節會實作。

小結與練習#

本章建立的心智模型:DNS 是層層委派 + 結果快取(TTL 租約)的全球分散式資料庫;遞迴與迭代只是責任劃分的角色差異;TTL 決定變更生效速度;記錄型別決定「名稱指向什麼」。

練習:

  1. 在本機用 dig +trace www.wikipedia.org 觀察逐級委派過程,數一數總共向幾台伺服器發了查詢。
  2. 解釋為什麼根伺服器只有 13 個 IP,卻能服務全世界的首跳查詢?(提示:anycast)
  3. 你的網站要從 A 伺服器遷移到 B 伺服器,停機期間想盡量縮短。請規劃完整的 TTL 操作時程表。
  4. 為什麼 example.com 的根網域不能直接設 CNAME 指到 blog.example.com?Cloudflare 用什麼技術解決?