06-1. DNS 域名解析
深入理解網際網路的電話簿:DNS 如何將域名轉換為 IP 位址
🌐 DNS 域名解析
🎯 什麼是 DNS?
💡 比喻:網際網路的電話簿
你記得朋友的名字(www.google.com)
但不記得他的電話號碼(142.250.185.46)
DNS 就是幫你查電話簿的服務
名字 → 電話號碼
域名 → IP 位址DNS(Domain Name System) 是一個分散式的命名系統,負責將人類易讀的域名(如 www.example.com)轉換為機器可識別的 IP 位址(如 93.184.216.34)。
為什麼需要 DNS?
沒有 DNS 的世界:
# 訪問 Google 需要記住 IP
curl http://142.250.185.46
# 訪問 Facebook 需要記住 IP
curl http://157.240.3.35
# 訪問 YouTube 需要記住 IP
curl http://172.217.160.110
問題:
1. 難以記憶
2. IP 可能改變(網站搬家)
3. 一個網站可能有多個 IP(負載平衡)有 DNS:
# 使用易記的域名
curl https://www.google.com
curl https://www.facebook.com
curl https://www.youtube.com
DNS 自動幫你找到對應的 IP!🏗️ DNS 在網路模型中的位置
OSI 7 層模型
┌──────────────────────────────┬─────────────────┐
│ 7. Application Layer (應用層) │ DNS │ ← DNS 在這裡
├──────────────────────────────┼─────────────────┤
│ 6. Presentation Layer (表示層)│ 加密、壓縮 │
├──────────────────────────────┼─────────────────┤
│ 5. Session Layer (會話層) │ 建立、維護會話 │
├──────────────────────────────┼─────────────────┤
│ 4. Transport Layer (傳輸層) │ UDP (主要), TCP│
├──────────────────────────────┼─────────────────┤
│ 3. Network Layer (網路層) │ IP │
├──────────────────────────────┼─────────────────┤
│ 2. Data Link Layer (資料鏈結層)│ Ethernet │
├──────────────────────────────┼─────────────────┤
│ 1. Physical Layer (實體層) │ 網路線、光纖 │
└──────────────────────────────┴─────────────────┘DNS 位於第 7 層(應用層)
- DNS 是應用層協定
- 提供域名解析服務
- 將人類可讀的域名轉換為 IP 位址
TCP/IP 4 層模型
┌─────────────────────────────┬─────────────────┐
│ 4. Application Layer (應用層) │ DNS │ ← DNS 在這裡
├─────────────────────────────┼─────────────────┤
│ 3. Transport Layer (傳輸層) │ UDP (主要), TCP│
├─────────────────────────────┼─────────────────┤
│ 2. Internet Layer (網際網路層)│ IP │
├─────────────────────────────┼─────────────────┤
│ 1. Network Access (網路存取層)│ Ethernet │
└─────────────────────────────┴─────────────────┘DNS 位於第 4 層(應用層)
- 在 TCP/IP 模型中,DNS 是應用層協定
- 主要使用 UDP(Port 53),查詢快速
- 當回應超過 512 bytes 時,使用 TCP(Port 53)
對比表:
| 協定 | OSI 層級 | TCP/IP 層級 | 傳輸層協定 | Port | 用途 |
|---|---|---|---|---|---|
| DNS | Layer 7 | Layer 4 | UDP (主要), TCP | 53 | 域名解析 |
| DHCP | Layer 7 | Layer 4 | UDP | 67/68 | 動態 IP 分配 |
| NTP | Layer 7 | Layer 4 | UDP | 123 | 時間同步 |
重點:
- DNS 是應用層協定(兩種模型都是)
- 主要使用 UDP(快速、低開銷)
- 查詢/回應通常 < 512 bytes → UDP
- 回應 > 512 bytes → 切換到 TCP
- Zone Transfer(區域傳輸)→ TCP
- DoH (DNS over HTTPS) → 使用 TCP Port 443
- DoT (DNS over TLS) → 使用 TCP Port 853
DNS 使用 UDP 的原因:
為什麼 DNS 主要用 UDP?
1. 速度快 ⚡
UDP 無需三次握手
查詢 → 回應(只需 2 個封包)
2. 開銷低 💰
DNS 查詢量極大(全球每秒數億次)
UDP 沒有連線狀態,節省資源
3. 失敗重試 🔄
DNS client 可以自己處理逾時重試
不需要 TCP 的可靠性保證
何時用 TCP?
✅ Zone Transfer(DNS 伺服器間同步)
✅ 回應超過 512 bytes(DNSSEC 簽章)
✅ DoH/DoT 加密查詢🏗️ DNS 架構
階層式結構
💡 比喻:郵遞區號系統
台灣 → 台北市 → 大安區 → 忠孝東路 → 123號
DNS:
. (根) → com. → google.com. → www.google.com. . (Root)
/ | \
/ | \
com. org. tw.
/ \ | |
/ \ | |
google. amazon. wikipedia. edu.tw.
| | | |
www. www. www. ntu.完整域名(FQDN):
www.google.com.
│ │ │ └─ 根域名(通常省略)
│ │ └───── 頂級域名(TLD: Top-Level Domain)
│ └────────── 二級域名
└──────────── 主機名稱DNS 伺服器類型
1. 根 DNS 伺服器(Root DNS Server):
💡 比喻:郵局總部
知道每個國家的郵局在哪裡
全球只有 13 個邏輯根伺服器(A-M)
實際上透過 Anycast 部署了數百個實體伺服器根伺服器列表:
a.root-servers.net (198.41.0.4)
b.root-servers.net (199.9.14.201)
c.root-servers.net (192.33.4.12)
...
m.root-servers.net (202.12.27.33)2. 頂級域名伺服器(TLD DNS Server):
💡 比喻:國家郵局
負責 .com, .org, .net, .tw 等頂級域名
.com → Verisign
.org → Public Interest Registry
.tw → TWNIC(台灣網路資訊中心)3. 權威 DNS 伺服器(Authoritative DNS Server):
💡 比喻:公司總機
公司的電話總機知道所有員工的分機號碼
google.com 的權威伺服器知道:
- www.google.com → 142.250.185.46
- mail.google.com → 172.217.160.37
- drive.google.com → 142.250.185.1104. 遞迴 DNS 伺服器(Recursive DNS Server):
💡 比喻:你的秘書
幫你查電話簿,找到號碼後告訴你
通常是 ISP 提供:
- Hinet: 168.95.1.1
- Google Public DNS: 8.8.8.8
- Cloudflare DNS: 1.1.1.1🔍 DNS 查詢流程
遞迴查詢(Recursive Query)
💡 比喻:問秘書「Google 的電話是多少?」
秘書幫你查好,直接告訴你答案完整流程:
使用者 DNS 解析過程
│
├─ 1. 查詢 www.google.com ──────────────────────────────────────┐
│ │
│ ┌──────────────────────────▼────┐
│ │ 遞迴 DNS (8.8.8.8) │
│ │ ┌──────────────────────────┐ │
│ │ │ 1. 檢查快取(未命中) │ │
│ │ └──────────────────────────┘ │
│ └───────────┬───────────────────┘
│ │
│ ┌───────────▼───────────────────┐
│ │ 2. 查詢根 DNS (a.root-servers)│
│ │ → 回應:查 .com TLD │
│ └───────────┬───────────────────┘
│ │
│ ┌───────────▼───────────────────┐
│ │ 3. 查詢 .com TLD │
│ │ → 回應:查 google.com NS │
│ └───────────┬───────────────────┘
│ │
│ ┌───────────▼───────────────────┐
│ │ 4. 查詢 google.com 權威 DNS │
│ │ → 回應:142.250.185.46 │
│ └───────────┬───────────────────┘
│ │
│<─ 2. 回應:142.250.185.46 ─────────────────────┘
│
├─ 3. 連線到 142.250.185.46 ────────────────────> Google 伺服器詳細步驟:
Step 1: 瀏覽器查詢 www.google.com
Step 2: 遞迴 DNS (8.8.8.8) 查詢根伺服器
查詢:www.google.com 的 IP 是?
根伺服器回應:我不知道,但你可以問 .com TLD (192.5.6.30)
Step 3: 查詢 .com TLD
查詢:www.google.com 的 IP 是?
TLD 回應:我不知道,但你可以問 google.com 的權威 DNS (ns1.google.com)
Step 4: 查詢 google.com 權威 DNS
查詢:www.google.com 的 IP 是?
權威 DNS 回應:142.250.185.46
Step 5: 遞迴 DNS 回應給使用者
142.250.185.46
Step 6: 瀏覽器連線到 142.250.185.46迭代查詢(Iterative Query)
💡 比喻:自己查電話簿
秘書不幫你查,只告訴你「去哪裡查」使用者 → 遞迴 DNS:www.google.com 在哪?
遞迴 DNS → 根 DNS:www.google.com 在哪?
根 DNS → 遞迴 DNS:我不知道,問 .com TLD (192.5.6.30)
遞迴 DNS → .com TLD:www.google.com 在哪?
.com TLD → 遞迴 DNS:我不知道,問 ns1.google.com (216.239.32.10)
遞迴 DNS → ns1.google.com:www.google.com 在哪?
ns1.google.com → 遞迴 DNS:142.250.185.46
遞迴 DNS → 使用者:142.250.185.46📝 DNS 記錄類型
常見記錄類型
1. A 記錄(Address Record):
💡 功能:域名 → IPv4 位址www.example.com. IN A 93.184.216.34
│ │ │ │
│ │ │ └─ IPv4 位址
│ │ └──── 記錄類型
│ └──────── IN (Internet)
└────────────────────────── 域名範例:
# 查詢 A 記錄
dig www.google.com A
# 回應
www.google.com. 300 IN A 142.250.185.462. AAAA 記錄(IPv6 Address):
💡 功能:域名 → IPv6 位址www.example.com. IN AAAA 2606:2800:220:1:248:1893:25c8:19463. CNAME 記錄(Canonical Name):
💡 功能:別名 → 正式名稱
比喻:暱稱 → 本名blog.example.com. IN CNAME example.github.io.
│ │
│ └─ 真正的域名
└────────────────────────────── 別名範例:
www.example.com. IN CNAME example.com.
example.com. IN A 93.184.216.34
查詢流程:
1. 查 www.example.com → CNAME → example.com
2. 查 example.com → A → 93.184.216.34注意:CNAME 限制
❌ 錯誤:根域名不能是 CNAME
example.com. IN CNAME other.com. # 不允許!
✅ 正確:子域名可以是 CNAME
www.example.com. IN CNAME other.com. # 允許4. MX 記錄(Mail Exchange):
💡 功能:指定郵件伺服器example.com. IN MX 10 mail1.example.com.
example.com. IN MX 20 mail2.example.com.
│ │
│ └─ 郵件伺服器域名
└───── 優先級(數字越小優先級越高)範例:
dig example.com MX
# 回應
example.com. 3600 IN MX 10 aspmx.l.google.com.
example.com. 3600 IN MX 20 alt1.aspmx.l.google.com.
# 發送郵件時:
# 先嘗試 aspmx.l.google.com (優先級 10)
# 如果失敗,嘗試 alt1.aspmx.l.google.com (優先級 20)5. NS 記錄(Name Server):
💡 功能:指定權威 DNS 伺服器example.com. IN NS ns1.example.com.
example.com. IN NS ns2.example.com.範例:
dig example.com NS
# 回應
example.com. 3600 IN NS a.iana-servers.net.
example.com. 3600 IN NS b.iana-servers.net.6. TXT 記錄(Text):
💡 功能:儲存文字資訊
用途:SPF、DKIM、網站驗證範例:
# SPF(防止郵件偽造)
example.com. IN TXT "v=spf1 include:_spf.google.com ~all"
# 網站驗證(Google Search Console)
example.com. IN TXT "google-site-verification=abcd1234..."
# DKIM(郵件簽章)
default._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0..."7. PTR 記錄(Pointer):
💡 功能:反向查詢(IP → 域名)46.185.250.142.in-addr.arpa. IN PTR www.google.com.
│
└─ 反轉的 IP (142.250.185.46)範例:
# 反向查詢
dig -x 8.8.8.8
# 回應
8.8.8.8.in-addr.arpa. 21599 IN PTR dns.google.⚡ DNS 快取機制
💡 比喻:電話簿的便利貼
常打的號碼寫在便利貼上,下次不用翻電話簿TTL(Time To Live)
www.google.com. 300 IN A 142.250.185.46
│
└─ TTL = 300 秒(5 分鐘)
意思:這筆記錄可以快取 5 分鐘
5 分鐘後需要重新查詢快取層級:
1. 瀏覽器快取(1 分鐘)
chrome://net-internals/#dns
2. 作業系統快取
Windows: ipconfig /displaydns
Linux: systemd-resolved --statistics
3. 遞迴 DNS 快取(依 TTL)
4. 權威 DNS(不快取,直接回應)清除快取:
# Windows
ipconfig /flushdns
# macOS
sudo dscacheutil -flushcache
sudo killall -HUP mDNSResponder
# Linux
sudo systemd-resolve --flush-caches🛠️ DNS 實戰工具
1. dig 命令
# 基本查詢
dig www.google.com
# 指定記錄類型
dig www.google.com A
dig example.com MX
dig example.com NS
# 簡化輸出(只顯示答案)
dig www.google.com +short
# 追蹤完整查詢過程
dig www.google.com +trace
# 指定 DNS 伺服器
dig @8.8.8.8 www.google.com
# 反向查詢
dig -x 8.8.8.8dig +trace 範例:
$ dig www.google.com +trace
. 518400 IN NS a.root-servers.net.
# → 查詢根伺服器
com. 172800 IN NS a.gtld-servers.net.
# → 查詢 .com TLD
google.com. 172800 IN NS ns1.google.com.
# → 查詢 google.com 權威 DNS
www.google.com. 300 IN A 142.250.185.46
# → 最終答案2. nslookup 命令
# 基本查詢
nslookup www.google.com
# 指定 DNS 伺服器
nslookup www.google.com 8.8.8.8
# 互動式模式
nslookup
> set type=MX
> example.com
> set type=NS
> google.com
> exit3. Python 實作 DNS 查詢
import socket
# 查詢 A 記錄(最簡單)
ip = socket.gethostbyname('www.google.com')
print(f"IP: {ip}")
# 使用 dnspython 庫(功能完整)
import dns.resolver
# 查詢 A 記錄
answers = dns.resolver.resolve('www.google.com', 'A')
for rdata in answers:
print(f"A: {rdata.address}")
# 查詢 MX 記錄
answers = dns.resolver.resolve('gmail.com', 'MX')
for rdata in answers:
print(f"MX: {rdata.preference} {rdata.exchange}")
# 查詢 TXT 記錄
answers = dns.resolver.resolve('google.com', 'TXT')
for rdata in answers:
print(f"TXT: {rdata.strings}")
# 指定 DNS 伺服器
resolver = dns.resolver.Resolver()
resolver.nameservers = ['8.8.8.8', '1.1.1.1']
answers = resolver.resolve('www.example.com', 'A')🔐 DNS 安全性
1. DNS 欺騙(DNS Spoofing)
💡 攻擊:偽造 DNS 回應正常流程:
使用者 → DNS:facebook.com 在哪?
DNS → 使用者:157.240.3.35
攻擊流程:
使用者 → DNS:facebook.com 在哪?
攻擊者 → 使用者:(搶先回應)123.45.67.89(釣魚網站)
DNS → 使用者:(晚一步)157.240.3.35防禦:DNSSEC
2. DNS 快取投毒(Cache Poisoning)
💡 攻擊:污染 DNS 快取攻擊者偽造回應:
example.com → 惡意 IP
如果遞迴 DNS 相信並快取這筆記錄:
所有使用者都會被導向惡意 IP(在 TTL 期間)防禦:
- 來源 Port 隨機化
- Transaction ID 隨機化
- DNSSEC
3. DNSSEC(DNS Security Extensions)
💡 功能:數位簽章驗證 DNS 回應
就像郵件的簽名,確保來源可信運作原理:
1. 權威 DNS 用私鑰簽署記錄
2. 發布公鑰(DNSKEY 記錄)
3. 遞迴 DNS 用公鑰驗證簽章
4. 如果簽章不符 → 拒絕回應查詢 DNSSEC:
# 查詢 DNSKEY
dig google.com DNSKEY +dnssec
# 查詢 RRSIG(簽章)
dig www.google.com A +dnssec4. DoH / DoT(加密 DNS)
DoH(DNS over HTTPS):
傳統 DNS:明文 UDP Port 53
DoH:HTTPS 加密(Port 443)
好處:
- ISP 無法竊聽你查詢什麼網站
- 防止 DNS 竄改設定 DoH(瀏覽器):
Firefox:
設定 → 隱私權與安全性 → 啟用「透過 HTTPS 的 DNS」
伺服器:https://mozilla.cloudflare-dns.com/dns-query
Chrome:
設定 → 安全性 → 使用安全 DNS
選擇:Cloudflare (1.1.1.1) 或 Google (8.8.8.8)DoT(DNS over TLS):
加密 DNS,使用 TLS(Port 853)
設定(Linux):
/etc/systemd/resolved.conf
[Resolve]
DNS=1.1.1.1
DNSOverTLS=yes🎓 常見面試題
Q1:DNS 查詢過程有哪些步驟?
答案:
完整 8 步驟:
瀏覽器檢查快取
- 已訪問過?直接使用快取
檢查作業系統快取
- 檢查 hosts 檔案和系統 DNS 快取
查詢遞迴 DNS
- 向 ISP 或公共 DNS(8.8.8.8)查詢
遞迴 DNS 檢查快取
- 有快取?直接回應
查詢根 DNS
- 詢問 .com TLD 的位置
查詢 TLD DNS
- 詢問 google.com 權威 DNS 的位置
查詢權威 DNS
- 獲得最終 IP 位址
回應給使用者
- 遞迴 DNS 快取結果並回應
記憶口訣:「瀏系遞緩根頂權回」
Q2:A 記錄和 CNAME 有什麼不同?
答案:
| 特性 | A 記錄 | CNAME |
|---|---|---|
| 指向 | IP 位址 | 另一個域名 |
| 用途 | 直接解析 | 別名 |
| 根域名 | ✅ 可用 | ❌ 不可用 |
| 多個值 | ✅ 可以 | ❌ 只能一個 |
| 範例 | example.com IN A 1.2.3.4 | www IN CNAME example.com |
使用場景:
A 記錄:
example.com. IN A 93.184.216.34
# 直接指向 IP
CNAME:
www.example.com. IN CNAME example.com.
blog.example.com. IN CNAME example.github.io.
# 指向另一個域名(別名)為什麼根域名不能用 CNAME?
RFC 1034 規定:
如果一個域名有 CNAME 記錄,就不能有其他記錄
但根域名必須有 NS 和 SOA 記錄:
example.com. IN NS ns1.example.com.
example.com. IN SOA ns1.example.com. admin.example.com. (...)
所以根域名不能用 CNAMEQ3:DNS 負載平衡如何實現?
答案:
方法 1:多個 A 記錄(Round Robin):
www.example.com. IN A 1.2.3.4
www.example.com. IN A 5.6.7.8
www.example.com. IN A 9.10.11.12
DNS 輪流回應不同 IP:
第 1 次查詢 → 1.2.3.4
第 2 次查詢 → 5.6.7.8
第 3 次查詢 → 9.10.11.12
第 4 次查詢 → 1.2.3.4(循環)方法 2:GeoDNS(地理位置):
def resolve_dns(domain, client_ip):
location = get_location(client_ip)
if location == 'Asia':
return '1.2.3.4' # 亞洲伺服器
elif location == 'Europe':
return '5.6.7.8' # 歐洲伺服器
elif location == 'US':
return '9.10.11.12' # 美國伺服器方法 3:智慧 DNS(健康檢查):
servers = [
{'ip': '1.2.3.4', 'healthy': True},
{'ip': '5.6.7.8', 'healthy': False}, # 故障
{'ip': '9.10.11.12', 'healthy': True}
]
def resolve_dns(domain):
# 只回應健康的伺服器
healthy_servers = [s for s in servers if s['healthy']]
return random.choice(healthy_servers)['ip']Q4:DNS TTL 如何設定?
答案:
TTL 設定建議:
| 場景 | TTL | 原因 |
|---|---|---|
| 穩定服務 | 3600-86400 (1小時-1天) | 減少查詢次數 |
| 準備遷移 | 300-600 (5-10分鐘) | 快速切換 |
| CDN | 60-300 (1-5分鐘) | 動態調整 |
| 測試環境 | 60 (1分鐘) | 快速測試 |
範例:
# 穩定的服務(低 TTL 開銷)
www.example.com. 86400 IN A 93.184.216.34
# 1 天內不會改變,減少 DNS 查詢
# 準備遷移(方便快速切換)
www.example.com. 300 IN A 93.184.216.34
# 5 分鐘後可以切換到新 IP
# CDN(動態調整)
cdn.example.com. 60 IN A 151.101.1.69
# 1 分鐘內可以更新遷移步驟:
Step 1: 提前降低 TTL(24 小時前)
www.example.com. 86400 IN A 1.2.3.4
→
www.example.com. 300 IN A 1.2.3.4
Step 2: 等待舊 TTL 過期(等 1 天)
Step 3: 更新 A 記錄指向新 IP
www.example.com. 300 IN A 5.6.7.8
Step 4: 驗證新 IP 運作正常
Step 5: 恢復高 TTL
www.example.com. 86400 IN A 5.6.7.8Q5:如何診斷 DNS 問題?
答案:
常見問題與診斷:
1. 域名無法解析:
# 測試是否是 DNS 問題
ping www.example.com
# 如果顯示「找不到主機」→ DNS 問題
# 使用不同 DNS 伺服器測試
nslookup www.example.com 8.8.8.8
nslookup www.example.com 1.1.1.1
# 如果公共 DNS 可以解析,ISP DNS 不行
# → ISP DNS 快取問題或設定問題2. DNS 傳播延遲:
# 檢查全球 DNS 傳播狀態
# 使用線上工具:whatsmydns.net
# 或手動查詢不同地區的 DNS
dig @8.8.8.8 www.example.com
dig @1.1.1.1 www.example.com
dig @208.67.222.222 www.example.com # OpenDNS
# 如果結果不同 → 正在傳播中3. CNAME 循環:
# 錯誤設定
a.example.com. IN CNAME b.example.com.
b.example.com. IN CNAME a.example.com.
# CNAME 指向彼此 → 無限循環
# 診斷
dig a.example.com
# 錯誤:CNAME loop detected4. 快取問題:
# 清除本地快取
ipconfig /flushdns # Windows
sudo systemd-resolve --flush-caches # Linux
# 檢查快取的 TTL
dig www.google.com
# 回應中的 TTL 會遞減
# 300 → 250 → 200 ... → 0(需要重新查詢)5. DNSSEC 驗證失敗:
# 檢查 DNSSEC
dig example.com +dnssec
# 如果回應包含 SERVFAIL
# → DNSSEC 驗證失敗
# 可能原因:
# 1. 簽章過期
# 2. 時鐘不同步
# 3. 設定錯誤📝 總結
DNS 關鍵要點:
- 分散式架構:根 → TLD → 權威 DNS 🏗️
- 快取機制:TTL 控制快取時間 ⏱️
- 記錄類型:A、AAAA、CNAME、MX、NS、TXT 📋
- 安全性:DNSSEC、DoH、DoT 🔐
記憶口訣:「分(分散)、快(快取)、錄(記錄)、安(安全)」
DNS 查詢流程:
瀏覽器快取 → 系統快取 → 遞迴 DNS → 根 DNS → TLD → 權威 DNS優化建議:
- 使用公共 DNS(8.8.8.8, 1.1.1.1)提升速度
- 適當設定 TTL 平衡快取與靈活性
- 啟用 DNSSEC 提升安全性
- 使用 GeoDNS 實現全球負載平衡
🔗 延伸閱讀
- 上一篇:06-3. 視訊通話架構
- 下一篇:07-2. SMTP/POP3/IMAP
- RFC 1035(DNS 規範):https://tools.ietf.org/html/rfc1035
- DNSSEC:https://www.dnssec.net/