DNS 是什麼?VPS 網域連線與設定指南
DNS 會決定網域是否連到 VPS。了解 A、CNAME、NS、TTL 紀錄、名稱伺服器與快取,找出 DNS 變更看似失敗的原因。
什麼是 DNS,以及為什麼您的網域目前尚未連到 VPS
DNS(domain name system,網域名稱系統)會將類似 example.com 的名稱轉換為類似 203.0.113.10 的 IP(internet protocol,網際網路通訊協定)位址。瀏覽器無法直接連線到名稱,而是連線到位址,因此每次載入頁面時,都會先提出 DNS 查詢並取得回應。如果您剛購買網域和自己的 VPS,但沒有任何內容載入,原因通常只有兩種:尚未建立將名稱連到伺服器位址的紀錄,或雖然已有紀錄,但傳遞路徑中的某個環節仍提供較舊的回應。
這兩種情況都很正常,也不代表系統發生故障。以下各節會依照您實際遇到的順序說明相關部分,先從最容易浪費時間的問題開始:究竟是哪個控制面板管理您的紀錄。
本節中的所有檢查都會使用 dig;全新安裝的 Ubuntu 或 Debian 預設不會安裝此工具。
sudo apt update && sudo apt install -y bind9-dnsutils註冊商、名稱伺服器、DNS 主機:應該編輯哪一個
這三個名稱代表不同的工作。混淆它們,是編輯後沒有任何變化的最常見原因。
- 註冊商是您購買網域的公司。它的關鍵工作是委派:告訴負責管理您 TLD(頂級網域,亦即
.com部分)的註冊局,哪些名稱伺服器對您的網域具備權威性。 - 權威名稱伺服器保存您 DNS zone 的實際記錄。zone 是您的網域及其下的名稱。
- DNS 主機是營運這些名稱伺服器的服務商。它可能是註冊商、獨立的服務提供者,或是您擁有的伺服器上執行的
bind9。
您在註冊商處購買網域,在 DNS 主機處編輯記錄。如果您已將網域移至其他服務提供者的名稱伺服器,註冊商自己的 DNS 控制台仍會顯示一個 zone,也會儲存您的編輯內容,但網際網路上的任何人都不會向該 zone 查詢。這些記錄確實存在,只是從未被查詢。
找出網際網路實際查詢的位置:
dig example.com NS +short
dig +trace example.com第一個命令會列出目前回應該網域查詢的名稱伺服器。第二個命令會從 root servers 開始沿著 DNS chain 查詢,並列出 TLD servers 提供的委派結果;這就是由註冊商控制的委派設定。如果這些名稱屬於您不認識的服務提供者,您需要使用的控制台就在該服務提供者處。
單次查詢的傳遞過程
共有 4 個參與方,每一方都會保留所獲取資訊的副本。
- 您電腦上的 stub resolver。它不會自行搜尋,只會詢問一台已設定的伺服器,並信任該伺服器的回覆。在 Ubuntu 上,
/etc/resolv.conf通常是指向/run/systemd/resolve/stub-resolv.conf的符號連結,而/run/systemd/resolve/stub-resolv.conf會指定由本機執行、具有自身快取的systemd-resolved,也就是127.0.0.53。 - recursive resolver。這是由 ISP(internet service provider)執行的 resolver,也可以是
1.1.1.1這類公開 resolver,或是您自行執行的 resolver。它負責實際尋找答案。 - root and TLD servers。recursive resolver 會詢問 root server。root server 不知道您的位址,但會回覆
.comservers 的轉介資訊。這些 servers 會回覆您的 nameservers 的轉介資訊。 - authoritative nameserver。它不會詢問其他伺服器,而是從您的 zone 回覆,並將答案標記為具權威性。
dig +trace example.com 會顯示這個過程,因為它會直接從 root 開始,逐一列出每次轉介,而不是詢問快取。這是確認 delegation 與 zone 是否一致的最快方式。
執行伺服器時需要注意的 DNS 記錄
A:將名稱對應至 IPv4 位址。example.com. A 203.0.113.10。這是將網域指向 VPS 的記錄。AAAA:將名稱對應至 IPv6 位址,例如2001:db8::10。只有在服務確實監聽該位址時才發布此記錄。IPv6 網路上的用戶端會先嘗試 AAAA 回應,因此若該位址沒有服務回應,每次存取都會增加延遲。CNAME:將一個名稱別名至另一個名稱。www.example.com. CNAME example.com.會將造訪www的訪客導向裸網域解析到的目標。CNAME 不能位於 apex(裸example.com),因為 apex 必須包含自己的 SOA(start of authority)與 NS 記錄,而 CNAME 不得與任何其他記錄共用名稱。各家供應商會以 ALIAS、ANAME 或 CNAME flattening 等名稱提供替代方案。MX:指定網域的郵件投遞位置。此記錄包含主機名稱與優先順序數字,數字越小越先嘗試。MX 必須指向具有位址記錄的名稱。將 MX 指向 CNAME 無效,部分寄件伺服器會拒絕這種設定。TXT:自由文字,用於驗證與政策設定。郵件驗證記錄(SPF、DKIM、DMARC)以及用來簽發 wildcard 憑證的 ACME(automatic certificate management environment)token 都位於此處。NS:指定負責提供該 zone 的 nameserver。決定全球查詢來源的副本位於 parent zone,來自註冊商的 delegation,而不是位於您自己的 zone 內的副本。
有兩個細節比記錄類型本身更容易造成混淆。以句點結尾的名稱是絕對名稱,因此 www.example.com. 只代表該名稱本身,不會再附加其他內容。大多數管理介面預期您輸入相對名稱,並會自動附加網域;因此在名稱欄位輸入 www.example.com,會產生 www.example.com.example.com,而該名稱無法解析至任何服務。另一個細節是 @,在幾乎所有管理介面中都代表 apex,也就是不含子網域的網域本身。
將 A record 指向 VPS
先取得網際網路看到的伺服器位址:
curl -4 https://ifconfig.me
ip -brief -4 address show接著在 DNS 託管服務中建立一筆記錄:類型為 A,名稱為 @,值設為該位址,TTL(存活時間)設為 300。再為 www 建立第二筆記錄,可以使用相同位址的另一筆 A,或使用指向 apex 的 CNAME。
現在確認它是否能解析。最好從筆記型電腦執行,而不是直接在伺服器上執行:
dig example.com A +short
dig @1.1.1.1 example.com A +short
dig @ns1.your-dns-host.net example.com A +short第一個命令會使用電腦的正常解析路徑,包含快取。第二個命令會略過本機快取,改為查詢公共遞迴解析器。第三個命令會直接查詢權威 nameserver,因此取得的是目前的實際結果,查詢路徑中沒有任何快取。當第三個命令回傳你的位址,而第一個命令沒有回傳時,表示 DNS 已正確設定,目前只是仍在等待舊結果的快取副本過期。
名稱解析沒有載入
名稱解析成功只能證明 DNS 正常,無法證明 Web 伺服器正常。dig 傳回正確位址後,測試連線:
curl -I http://example.comcurl: (6) Could not resolve host: example.com 是 DNS 問題。curl: (7) Failed to connect to example.com port 80 after 21 ms: Connection refused 不是 DNS 問題:名稱已完成解析,封包也已抵達,因此問題在於該連接埠沒有任何程式監聽。請求持續等待後逾時,通常表示防火牆靜默丟棄封包,而不是拒絕連線。此時問題已不再是 DNS,而是由 連接埠與監聽 socket 以及 VPS 上的 ufw 防火牆規則 接手處理。連線完成後,剩餘的頁面載入工作就是 HTTP 正在處理請求。
為什麼瀏覽器仍顯示舊主機
不會有任何內容自動傳播。沒有任何伺服器會將你的變更主動推送給其他人。你儲存變更的瞬間,權威 nameserver 就會保留新值;而先前答案的每份快取副本,會持續有效到各自的計時器到期為止。這個計時器就是 TTL,單位為秒,記錄交付給查詢端時所帶的值。
副本存在於比一般人預期更多的位置:瀏覽器自己的短期快取、電腦上的 stub resolver、該網路使用的遞迴 resolver,以及 VPN 在用戶端安裝的任何 resolver。每個元件都會依收到的 TTL,將副本保留最長該段時間。兩個人在兩個不同網路上,可能連續數小時看到不同答案,而兩台電腦的行為都完全正確。
使用快取 resolver 觀察倒數計時:
dig @1.1.1.1 example.com +noall +answer執行兩次,間隔幾秒。答案中的 TTL 會下降。TTL 歸零時,resolver 會丟棄該記錄,並再次向你的 nameserver 查詢。
還有第二種幾乎沒有人會納入考量的快取:否定答案。當 resolver 得知某個名稱不存在時,也會快取該 NXDOMAIN,時間長度由你之 zone 的 SOA 記錄最後一個欄位決定。
dig example.com SOA +short該行最後的數字就是負面 TTL,通常為 3600。因此,在建立 staging.example.com 之前查詢它,可能會讓你在建立後整整 1 小時都看不到該記錄。請先建立記錄,再查詢它。
變更 nameserver 比變更記錄慢,原因在於 DNS 的運作方式。.com zone 中的 delegation 記錄會以 172800 秒的 TTL 提供,也就是 2 天。因此,已快取舊 nameserver 的 resolver,可能會持續向它們查詢這麼久。「最多等待 48 小時」的建議就是由此而來。這只適用於 nameserver 變更,不適用於一般記錄編輯。
請依 TTL 規劃遷移,不要試圖與它對抗:
- 將記錄的 TTL 降至 300,並儲存。
- 等待超過舊 TTL,讓所有含有舊值的快取副本都已過期。
- 變更位址。
- 流量移轉完成後,將 TTL 調回 3600 或更高,因為低 TTL 會讓每個 resolver 更頻繁地向你的 nameserver 查詢。
若要清除本機目前保留的內容:
resolvectl flush-caches
resolvectl statisticsresolvectl statistics 會輸出包含命中與未命中計數器的快取區段,因此清除後立即進行的下一次查詢會顯示為未命中。瀏覽器會保留獨立的快取,因此即使系統快取已清空,Chrome 仍可能使用舊答案。請在 chrome://net-internals/#dns 清除瀏覽器快取。也請檢查 /etc/hosts,因為其中殘留的內容會優先於該電腦上的 DNS,且只影響該電腦。getent hosts example.com 會顯示系統實際使用的答案,其中也包含 /etc/hosts。
Wildcard 憑證透過 TXT 記錄完成驗證
CA(憑證授權單位)在簽發憑證前,會確認你是否控制該名稱。HTTP-01 challenge 會在 port 80 上,透過該確切主機名稱提供檔案,適合單一名稱。Wildcard 憑證涵蓋 *.example.com,這是一組無固定範圍的主機名稱,CA 無法從中擷取檔案,因此 Let's Encrypt 只會透過 DNS-01 challenge 簽發 wildcard 憑證。你必須在 _acme-challenge.example.com 發布 TXT 記錄,並填入 CA 提供的 token;你對該 zone 的控制權就是驗證依據。
因此,DNS host 會成為憑證續期流程的一部分。Certbot 必須在每次續期時,自動建立並刪除該 TXT 記錄,因此需要你的 DNS provider 提供 API,以及相符的 plugin。驗證失敗時,通常會顯示 DNS problem: NXDOMAIN looking up TXT for _acme-challenge.example.com,表示 CA 查詢時該記錄尚未可見:可能是記錄從未成功儲存,或否定回應仍在 cache 中。完整流程請參閱使用 DNS-01 challenge 的 wildcard 憑證指南。
VPN 接管 resolver 時
VPN(virtual private network)用戶端在連線期間通常會取代系統 resolver,因為若將查詢送往區域網路,該網路就能知道你造訪的每個網站名稱。這是正確行為,但可能在兩個方向上失敗。
如果 tunnel 建立後名稱停止解析,但位址仍可正常連線,表示用戶端安裝的 resolver 無法從 tunnel 內連線。ping 1.1.1.1 成功,而 curl https://example.com 會回傳 curl: (6) Could not resolve host: example.com。反之,如果 tunnel 建立後查詢仍送往你目前所在的網路,表示網路流量已經通過 tunnel 傳送,但區域 resolver 仍會看到你查詢的每個名稱。
resolvectl status這會列出每個 link 目前使用的 resolver,讓你確認 tunnel 安裝了哪個 resolver,以及它是否符合預期。WireGuard tunnel 會從用戶端設定中的 DNS = 行設定此值,而修正 WireGuard 接管 resolver 時的 DNS 設定則詳細說明 systemd-resolved 與 resolvconf 的處理方式。
回應碼及其代表的意義
NXDOMAIN:權威伺服器表示該名稱不存在。請檢查拼字、是否重複輸入網域後綴,以及是否編輯了委派所指向的 zone。NOERROR且ANSWER SECTION為空:該名稱存在,但沒有你要求類型的記錄。例如,只有A存在時要求AAAA,就會得到這個結果。SERVFAIL:解析器嘗試解析,但無法產生回應。最常見的兩個原因是權威伺服器完全沒有回應,以及 DNSSEC(domain name system security extensions)驗證失敗。請使用dig @1.1.1.1 example.com A +cd進行測試,這會停用驗證。如果停用驗證後取得包含+cd和SERVFAIL的回應,表示問題出在簽章。這通常發生在 nameserver 變更後,而父 zone 仍發布舊的 DS(delegation signer)記錄。REFUSED:你查詢的伺服器不會回答這個問題。通常是因為你將dig指向不負責該網域的權威伺服器。;; connection timed out; no servers could be reached:dig 從未連到解析器。這是你端的網路或解析器問題,與該網域本身無關。
ping: example.com: Temporary failure in name resolution 是由 glibc 回報,而不是由 dig 回報的相同類型失敗。
是否應在自己的 VPS 上執行 nameserver?
可以。bind9、knot 或 nsd 都能直接從伺服器提供你的 zone,學到的 DNS 知識也比使用任何控制面板更多。問題在於實務上的風險。網域至少應設定兩個位於不同網路的 nameserver,因此單一 VPS 會成為該網域所有服務的單一故障點,郵件服務也包括在內。若 nameserver 的名稱位於其提供服務的網域內,就必須在 registrar 設定 glue record。glue record 是父 zone 中儲存的 ns1.example.com 位址,否則查詢無法找到起點。當 resolver 無法連線到你的 nameserver 時,不會改用網站作為備援;對該使用者而言,整個網域都會消失。對多數人來說,搭配 API 的代管 DNS 是風險較低的選擇。在 VPS 上為自己的機器執行 caching resolver 是另一項工作,承擔的責任也小得多。
FAQ
為什麼我的 DNS 變更尚未傳播?
實際上沒有任何內容會「傳播」。您儲存變更後,權威 nameserver 立即持有新值;已經查詢過的每個 resolver 則會持續使用快取副本,直到收到的 TTL 到期為止。使用 dig @ns1.your-dns-host.net example.com A +short 直接詢問權威伺服器。如果回傳新地址,表示變更已生效,剩下的只是快取問題。如果您變更的是 nameserver 而非記錄,預期需要更長時間,因為 TLD delegation 會以 two day TTL 發布。
如何找出我的網域實際使用哪些 nameserver?
dig example.com NS +short 會列出目前回應該網域的 nameserver,dig +trace example.com 則會顯示從 root 開始的 referral chain,包括 TLD server 發布的 delegation。如果這些名稱不是您正在編輯管理面板的 provider,那就是問題所在。請在 delegation 指定的 provider 修改記錄,或在 registrar 變更 delegation,讓它指向您要使用的位置。
我的網域可以解析,但網站仍然無法載入。現在該怎麼辦?
只要 dig example.com A +short 回傳您伺服器的地址,DNS 就已完成。之後的問題在於連線。curl -I http://example.com 回傳 Connection refused,表示該連接埠沒有任何服務在監聽。確認 web server 正在執行,且已繫結至公開地址;接著檢查伺服器上的防火牆,以及 provider 控制面板中的獨立網路防火牆。
為什麼我不能在 root domain 上設定 CNAME?
CNAME 表示某個名稱是另一個名稱的別名,而設定 CNAME 的名稱不得再包含其他記錄。root domain 必須包含 SOA 和 NS 記錄才能作為 zone 存在,因此不能同時設定為 CNAME。請在 root domain 使用 A 記錄存放地址,或使用 provider 提供的 ALIAS、ANAME 或 CNAME flattening 功能。這些功能會儲存一個名稱,並以該名稱目前解析到的地址回應查詢。