DNS 是什麼意思?域名解析原理、記錄型別與查詢命令
DNS 是 Domain Name System(域名系統)的縮寫,作用是把 www.example.com 這樣的域名翻譯成伺服器的 IP 位址。網路設定裡的“DNS 位址”指替你完成查詢的遞迴解析伺服器;域名的記錄則儲存在權威伺服器上。查詢結果會按 TTL 快取,所以改了解析不會立刻處處生效。
DNS 是什麼意思?DNS 是 Domain Name System 的縮寫,中文叫域名系統。它是一個分佈在全球的資料庫,負責把人記得住的域名(如 www.example.com)翻譯成機器通訊用的 IP 位址(如 203.0.113.10),也能反過來由 IP 查出域名。瀏覽器開啟網站、伺服器執行 yum update、郵件伺服器投遞郵件,第一步都是一次 DNS 查詢。DNS 使用 53 連接埠,普通查詢走 UDP,應答過大或在伺服器之間同步整個區域時走 TCP。
DNS 位址、DNS 伺服器、DNS 查詢分別指什麼
“DNS”在不同場合指不同的東西,先把三個常見說法分開:
- DNS 查詢:程式發出“這個域名對應什麼位址”的一次請求,以及收到的應答。
- DNS 位址:網路卡設定裡填的那一兩個 IP,比如 223.5.5.5。它的作用是告訴本機:域名查詢發給誰。這個位址指向的是一台遞迴解析伺服器。
- DNS 伺服器:分為兩類,作用完全不同。
| 對比項 | 遞迴解析伺服器 | 權威伺服器 |
|---|---|---|
| 作用 | 替客戶端跑完整個查詢過程,把最終結果返回給客戶端並快取 | 儲存某個域名區域(zone)的記錄,只回答自己負責的域名 |
| 誰來問它 | 電腦、伺服器,DNS 位址裡填的就是它 | 遞迴解析伺服器,按域名的 NS 記錄找到它 |
| 例子 | 運營商 DNS、機房提供的 DNS、223.5.5.5、119.29.29.29 | 解析服務商的 ns1、ns2 伺服器,自建的 BIND |
| 資料從哪來 | 向權威伺服器查詢後快取 | 管理員在解析後台或區域檔案裡錄入 |
| 出故障的表現 | 用它的機器,所有域名都解析失敗或很慢 | 只有它負責的域名解析失敗,所有訪客都受影響 |
所以“給網站做域名解析”是在權威伺服器上加記錄,“給伺服器設定 DNS”是指定遞迴伺服器,兩件事在不同的地方操作,互不替代。
域名解析的過程:遞迴查詢與迭代查詢
以一台伺服器第一次存取 www.example.com、各級快取都為空為例:
- 查本機。程式呼叫系統解析器,先看 hosts 檔案,再看本機快取(Windows 的 DNS Client 服務;Linux 上常見的是 systemd-resolved 或 nscd,沒有執行任何快取服務的 Linux 本機不快取)。命中就直接返回。
- 問遞迴伺服器。本機沒有,就把查詢發給 DNS 位址裡的第一台伺服器,報文裡帶“期望遞迴”(RD)標誌,意思是“請直接給我最終答案”。客戶端和遞迴伺服器之間的這一問一答,叫遞迴查詢。
- 遞迴伺服器問根伺服器。它的快取裡也沒有,就去問根伺服器。根伺服器不知道
www.example.com的位址,但知道 .com 由哪些伺服器負責,返回它們的名字和位址,這種“去問別人”的應答叫轉介(referral)。 - 問 .com 的伺服器。負責 .com 這一級的 TLD 伺服器同樣不給最終答案,只返回 example.com 的 NS 記錄,也就是這個域名的權威伺服器。
- 問權威伺服器。權威伺服器返回
www.example.com的 A 記錄 203.0.113.10,應答裡帶“權威應答”(AA)標誌。 - 快取並返回。遞迴伺服器把結果連同 TTL 存進快取,再返回給客戶端。
第 3 到第 5 步,遞迴伺服器每次拿到的都是“下一步去問誰”的線索,然後自己再去問,這種方式叫迭代查詢。根伺服器共有 a 到 m 13 個名字,每個名字背後透過任播部署了大量節點;遞迴伺服器會把 .com、.cn 這類 TLD(域名字尾這一級)的 NS 快取很長時間,並不是每次查詢都去問根。
dig +trace 只在第一步向本機配置的 DNS 取一份根伺服器列表,之後由 dig 自己從根開始逐級迭代,能看到這條鏈的每一環:
dig www.example.com +trace
輸出按級分段:第一段是根伺服器列表(a.root-servers.net. 等),第二段是 .com 的伺服器,第三段是 example.com 的權威伺服器,最後一段才是 A 記錄。斷在哪一段,問題就在哪一級:如果卡在問 example.com 的權威伺服器那一步,多半是域名的 NS 指向了不存在或不回應的伺服器。
快取與 TTL:為什麼改了解析不立即生效
每條記錄都帶一個 TTL(Time To Live,生存時間),單位是秒,表示這條結果可以被快取多久。遞迴伺服器、作業系統、瀏覽器都可能快取;權威伺服器上的記錄改了,已經快取舊值的地方要等 TTL 到期才會重新查詢。
檢視遞迴伺服器快取裡的結果還剩多少秒:
dig www.example.com @223.5.5.5 +noall +answer
# www.example.com. 2875 IN A 203.0.113.10
第二列 2875 是剩餘 TTL,隔幾秒再查會變小;直接問權威伺服器,看到的則是設定的完整值。
計劃更換伺服器 IP 時,按 TTL 倒推操作時間。假設原記錄 TTL 為 3600 秒:
| 時間 | 操作 | 原因 |
|---|---|---|
| 切換前一天 | 把 TTL 從 3600 改為 300 | 各處快取的舊版本最長還要保留 3600 秒,等它們過期後,快取裡就都是 TTL 300 的版本 |
| 切換時 | 把 A 記錄改成新 IP | 此時任何快取最多再保留 5 分鐘 |
| 切換後 5 分鐘起 | 絕大部分存取到達新 IP | 個別不遵守 TTL 的解析器和客戶端會更久,舊伺服器先保留一段時間 |
| 穩定後 | TTL 改回 3600 或更長 | 減少查詢量,權威伺服器短暫故障時快取還能撐一陣 |
還有一種容易被忽略的快取:否定快取。記錄新增之前有人查過這個名字,遞迴伺服器會把“不存在”(NXDOMAIN)也快取起來,時長取該區域 SOA 記錄本身的 TTL 與 SOA 最後一個欄位中較小的那個(RFC 2308)。表現是“新加的子域名,別人都能解析,我這裡就是查不到”。新增記錄之前不要先去查它;查之前可以看一眼 SOA:
dig example.com SOA +short
# ns1.example.net. admin.example.com. 2026121701 3600 600 1209600 300
最後一個數字 300,就是否定應答最多會被快取的秒數。
DNS 記錄型別對照
| 記錄 | 作用 | 記錄值範例 | 注意 |
|---|---|---|---|
| A | 域名指向 IPv4 位址 | 203.0.113.10 | 一個名字可以有多條,解析器通常輪換返回順序,存取會分散到各個位址 |
| AAAA | 域名指向 IPv6 位址 | 2001:db8::10 | 服務確實能經 IPv6 存取時再新增 |
| CNAME | 別名,指向另一個域名 | www.example.com.cdn.example.net |
有 CNAME 的名字不能再有其他記錄;根域名(@)不能用 CNAME,部分服務商提供 CNAME 拉平或 ALIAS 記錄 |
| MX | 指定接收郵件的伺服器 | 10 mail.example.com | 值是主機名而不是 IP;數字越小優先順序越高 |
| NS | 指定域名由哪些權威伺服器負責 | ns1.example.net | 整個域名的 NS 要在註冊商處修改才生效 |
| TXT | 任意文字 | v=spf1 ip4:203.0.113.10 -all | 用於 SPF、DKIM、域名所有權驗證 |
| PTR | 反向解析,IP 指向域名 | mail.example.com | 歸 IP 的持有者管理,機房伺服器要向機房申請 |
| SOA | 區域的起始授權資訊 | 主伺服器、管理員郵箱、序列號、重新整理與過期時間 | 自建 DNS 有從伺服器時,每次修改都要增大序列號,否則從伺服器不會同步 |
| CAA | 限定哪些證書機構可以為本域名簽發證書 | 0 issue “letsencrypt.org” | 不設 CAA 時任何證書機構都可以簽發 |
用 nslookup 和 dig 查詢 DNS
nslookup 在 Windows 和 Linux 上都有,適合快速查一下;dig(Linux 上在 bind-utils 或 dnsutils 軟體包裡)輸出完整,排查時更好用。
nslookup www.example.com # 用本機配置的 DNS 查詢
nslookup www.example.com 119.29.29.29 # 指定 DNS 伺服器查詢
nslookup -type=mx example.com # 查 MX 記錄
dig www.example.com # 完整輸出
dig @119.29.29.29 www.example.com A +short
dig example.com NS +short # 查這個域名的權威伺服器
dig -x 203.0.113.10 +short # 反向解析
nslookup 的結果上方常有一行 Non-authoritative answer(非權威應答),意思是答案由遞迴伺服器代查或取自快取,而不是權威伺服器親自回答,這是正常現象,不是報錯。
dig 的完整輸出裡,有四處最值得看:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4660
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; Query time: 28 msec
;; SERVER: 223.5.5.5#53(223.5.5.5) (UDP)
- status:這次查詢的結論。
NOERROR表示查詢成功,但 ANSWER 為 0 時說明名字存在、只是沒有這種型別的記錄(比如只加了 A 卻查 AAAA);NXDOMAIN表示域名不存在;SERVFAIL表示解析伺服器沒能完成查詢,常見於權威伺服器不回應或 DNSSEC 驗證失敗;REFUSED表示伺服器拒絕回答,常見於向一台不負責該域名的權威伺服器發起查詢,或者遞迴伺服器只為自己網段的客戶端服務。 - flags:
rd表示請求了遞迴,ra表示伺服器願意遞迴,aa表示這是權威應答。直接問權威伺服器時應當看到aa;問遞迴伺服器時通常只有qr rd ra。 - SERVER:這次實際回答的是哪台伺服器。本機配置了多個 DNS 時,用它確認用的是哪一台;Ubuntu 上顯示 127.0.0.53,說明查詢先交給了本機的 systemd-resolved,再由它轉發出去。
- Query time:第一次查詢通常幾十到幾百毫秒,緊接著再查一次降到個位數,說明第二次命中了快取。
Windows 的 PowerShell 裡可以用 Resolve-DnsName www.example.com -Server 223.5.5.5 查詢,用 ipconfig /displaydns 檢視本機快取,ipconfig /flushdns 清空快取。
建站時 DNS 解析不生效怎麼查
按下面的順序逐項排除,前一項確認沒問題再看下一項:
| 檢查項 | 命令或做法 | 常見問題 |
|---|---|---|
| 1. 域名實際由哪家權威伺服器負責 | 直接問 .com 的 TLD 伺服器:dig example.com NS @a.gtld-servers.net,看 AUTHORITY 段 |
在 A 服務商後台加了記錄,註冊商處的 NS 卻還指向 B 服務商,記錄永遠不會生效 |
| 2. 權威伺服器上有沒有這條記錄 | dig www.example.com @ns1.example.net +norec |
只加了 @ 沒加 www;主機記錄填成完整域名,結果變成 www.example.com.example.com |
| 3. 遞迴伺服器拿到的是不是新值 | dig www.example.com @223.5.5.5,看剩餘 TTL |
舊值或否定應答還在快取裡,等 TTL 到期 |
| 4. 本機有沒有被 hosts 覆蓋 | 檢視 hosts 檔案;Linux 用 getent hosts www.example.com |
測試時寫進 hosts 的條目忘了刪 |
| 5. 解析已經正確,網站還是打不開 | curl -I http://203.0.113.10 -H "Host: www.example.com" |
問題不在 DNS:連接埠沒放行、Web 服務沒繫結這個域名,或內地機房的網站還沒完成 ICP 備案 |
使用了按運營商線路解析(智慧解析)的域名,電信、聯通、移動使用者查到的位址本來就可能不同,排查時要用對應線路的 DNS 去查,不要拿一個結果代表所有訪客。
機房內部要不要自建 DNS
伺服器上了一定數量的機房,內網通常值得部署兩台自己的解析伺服器,解決三件事:
- 內網快取:所有伺服器的 DNS 位址指向內網解析器,重複查詢在本地命中,延遲低,也不受公共 DNS 查詢頻率限制的影響。
- 內部名稱:交換器、PDU、BMC 管理口、監控伺服器用名字存取,位址變了只改一處。內部域名用自己已註冊域名下的子域,如 dc.example.com,不要隨意編造一個域名字尾,以免將來和公網上的真實域名衝突。
- 出口集中:只有這兩台需要存取外部 DNS,出口防火牆的規則更簡單。
下面是 Unbound 做快取兼內部名稱解析的最小配置(/etc/unbound/unbound.conf),位址按實際網段修改:
server:
interface: 10.0.0.53
access-control: 10.0.0.0/8 allow
access-control: 0.0.0.0/0 refuse
local-zone: "dc.example.com." static
local-data: "pdu-a01.dc.example.com. IN A 10.0.10.21"
local-data: "sw-core1.dc.example.com. IN A 10.0.0.2"
unbound-checkconf # 檢查配置語法
systemctl restart unbound
dig @10.0.0.53 pdu-a01.dc.example.com +short
這份配置裡最要緊的是 access-control:遞迴解析伺服器絕不能對公網開放。開放遞迴的伺服器會被利用做 DNS 反射放大攻擊:攻擊者偽造受害者的源位址發出小查詢,你的伺服器把大得多的應答打向受害者,機房出口頻寬也一起被佔用。從機房外的一台機器測一下(位址換成你的 DNS 伺服器公網位址):
dig @198.51.100.53 www.example.com
如果返回了 A 記錄、flags 裡有 ra,就是開放遞迴,要立刻收緊;返回 status: REFUSED 或超時才對。對外提供權威解析的伺服器,同樣要關閉遞迴功能。
自建之後,還要讓每台伺服器知道該填哪個 DNS,這也是客戶常問的問題。答案應當跟著位址段走:同一個段裡的伺服器,用同一組 DNS。Toplink DCIM 的 IP 位址管理 在每個位址段上記錄兩個 DNS 位址,和閘道器、VLAN 放在一起,維運給客戶回覆網路引數時,位址、閘道器和 DNS 從同一條記錄裡讀出。內網建好了自己的解析伺服器,把各段登記的 DNS 改成內網位址即可,不必逐台去記。
常見問題
DNS 位址填錯了會怎樣?
用 IP 位址存取一切正常,但域名全部解析失敗或很慢:網頁打不開、yum 和 apt 報無法解析主機、郵件發不出去。用 nslookup 域名 223.5.5.5 換一個 DNS 查詢,能返回結果就說明是本機 DNS 位址的問題。
hosts 檔案和 DNS 是什麼關係?
hosts 檔案是本機的靜態對照表,Linux 的 /etc/hosts 和 Windows 的 C:\Windows\System32\drivers\etc\hosts 預設都比 DNS 優先。測試新伺服器時常用它臨時把域名指過去,測完要刪掉,否則這台電腦會一直存取寫死的位址。
什麼是 DNS 劫持?
查詢結果在途中或在解析伺服器上被換成了別的位址,表現為同一個域名在不同網路裡解析結果不同、網頁被跳轉。對比權威伺服器和幾個公共 DNS 的結果可以確認;網站一側可以啟用 DNSSEC,訪客一側可以改用 DNS over HTTPS 或 DNS over TLS。