如何清除 Mac 的 DNS 快取
要清除 Mac 的 DNS 快取,從應用程式 › 工具程式打開終端機,執行下面這一行:
sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder
系統要求時輸入你登入 Mac 的密碼,成功時不會顯示任何內容。重新啟動 Mac 也能清掉快取,Apple 關於 DNS 快取的文章就寫著,可以重新啟動 Mac 來更新快取的資訊。
這篇 Apple 文章已經封存,不再更新。裡面最新的一條是給 OS X Yosemite 10.10.4 和以上版本的 sudo killall -HUP mDNSResponder,dscacheutil -flushcache 則是它列給 Snow Leopard 的指令。Apple 之後沒有發布更新的版本,所以上面那一行兩個都執行:killall 那一半是 Apple 列給目前版本的做法,dscacheutil -flushcache 按它的手冊頁(man dscacheutil)是清除目錄服務快取,手冊也說只該在極端情況下使用,過時的 DNS 回應正好算一種。Mole Mac 不會清除 DNS,這是終端機裡的工作。
DNS 快取是什麼
App 要連到 example.com 時,macOS 得先把這個名稱轉成 IP 位址。在 Mac 上,這次查詢交給 mDNSResponder,它的手冊頁(man mDNSResponder)說,它是代替其他程序執行 DNS 查詢、並保存一份回應快取的常駐程式。
有了快取,每次重複查詢同一個名稱都能省掉一趟往返。每筆回應會依網域 DNS 紀錄允許的時間保留,到期後再重新取得。大多數時候這一切沒人察覺,出問題是在快取裡的回應還沒到期就已經過時了:網站搬到新伺服器、你換了 DNS 伺服器,或某次查詢失敗後,這個失敗結果還在被重複使用。
killall -HUP mDNSResponder 裡的 -HUP 是選擇 killall 要送出哪個訊號,不加的話,killall 會送 TERM(man killall)。Apple 列出的重置 DNS 快取寫法就是 HUP 這種,所以別省略這個參數,也別換成 -9。
什麼時候清除 DNS 有用
| 情況 | 為什麼有用 |
|---|---|
| 網站或伺服器換了位址,你的 Mac 還連到舊位址 | 快取裡的回應還沒到期 |
| 你在網路設定裡換了 DNS 伺服器 | 先前那台伺服器給的回應還留在快取裡 |
你改了 /etc/hosts,變更卻沒生效 |
hosts 手冊頁說這個檔案由 mDNSResponder 讀取,它手上可能還是先前的回應 |
| 一分鐘前某個網站解析失敗,其他裝置都能連上,這台 Mac 還是失敗 | 失敗的查詢可能被快取了 |
什麼時候清了也沒用
清除只會清掉 Mac 自己解析器的快取。下面幾種常見設定都讓它無關緊要:
- 代理伺服器。 流量經過 HTTP 或 SOCKS 代理伺服器時,名稱常常由代理伺服器自己解析。用
scutil --proxy檢查,它會回報目前的系統代理伺服器設定。 - VPN。 VPN 可能安裝自己的 DNS 伺服器,或只把部分網域交給它們解析。
scutil --dns會列出每個使用中的解析器,列有網域的補充解析器只負責那個網域。公司網域連不上時,該查的是 VPN 的 DNS。 - 瀏覽器自己的快取。 瀏覽器可能保留自己的短期 DNS 結果,也會重複使用已打開的連線。清除後把瀏覽器完全結束再重新打開,只重新載入分頁是不夠的。
- 上游快取。 路由器和 DNS 服務供應商也會快取回應,清除 Mac 的快取無法讓它們早一點取得新紀錄。
- 網站本身真的掛了,或在你的網路上被封鎖。換一個網路的其他裝置也連不上的話,原因不在你這台 Mac 的 DNS。
如果只是網頁很慢、不是連不上,DNS 快取很少是瓶頸,更可能的原因見Mac WiFi 偶爾卡頓和找出哪個 App 正在占用 Mac 網路。
檢查 Mac 實際解析出什麼
用系統解析器查詢,得到的就是 App 拿到的回應:
dscacheutil -q host -a name example.com
dscacheutil 手冊頁說,-q 透過標準呼叫執行查詢,結果可能來自快取,也可能即時取得。
接著直接詢問 DNS 伺服器:
dig example.com
dig 不經過 macOS 的解析器。它的手冊頁說它使用 /etc/resolv.conf 裡列出的伺服器,而 macOS 上這個檔案附有一段說明,表示系統裡大多數程序做 DNS 解析時不會參考它。如果 dig 回傳新位址、dscacheutil 回傳舊位址,差別就出在 Mac 的快取或解析器設定上,清除一次應該就能解決。如果兩邊都回傳舊位址,代表上游的紀錄還沒更新。
查看 Mac 正在使用哪些 DNS 伺服器:
scutil --dns
手動設定的伺服器在系統設定 › 網路裡:選取一個網路服務,按一下詳細資訊,再按一下 DNS(Apple)。
怪罪快取之前,先檢查 /etc/hosts
/etc/hosts 裡列出的任何名稱都會覆蓋 DNS。開發工具、廣告阻擋工具和一些舊教學有時會在裡面加幾行,然後就放著不管。查看它:
cat /etc/hosts
正常的檔案只有幾行 localhost,以及以 # 開頭的註解。如果看到那個出問題的網域,那一行就是它這樣解析的原因。只修改那一行,用透過 sudo 執行的編輯器,留一份原始檔案,改完再清除快取。不要刪掉 localhost 那幾行。
確認結果
- 執行清除指令。
- 對出問題的網域再執行一次
dscacheutil -q host -a name example.com,檢查位址。 - 結束並重新打開出問題的瀏覽器或 App。
- 還是不行的話,對照
dig、scutil --dns和scutil --proxy,看看是哪一層在回應。
不要這樣做
- 不要定期清除 DNS,也不要把它當成加速技巧。有內容的快取讓查詢更快,清空之後接下來幾次反而更慢。
- 不要刪除
/etc/hosts,也不要更改它的權限。 - 使用 VPN 或管理描述檔的公司或學校 Mac,不要沒問過管理者就換 DNS 伺服器,內部名稱可能會解析不到。
- 不要為了「測試 DNS」去改代理伺服器或 VPN 設定。先弄清楚是哪一層在回應。
常見問題
如何清除 Mac 的 DNS 快取?
在終端機執行 sudo dscacheutil -flushcache; sudo killall -HUP mDNSResponder 並輸入密碼。重新啟動 Mac 也能清除。
目前的 macOS 清除 DNS 用什麼指令?
Apple 已封存的文章給 OS X 10.10.4 和以上版本列的是 sudo killall -HUP mDNSResponder,之後也沒有發布更新的版本。前面再加上 sudo dscacheutil -flushcache 是常見寫法,它只會清除快取資料。
清除 Mac 的 DNS 會一併清除瀏覽器的快取嗎?
不會。它只清除 macOS 解析器的快取。把瀏覽器結束再重新打開,它才不會繼續使用自己的 DNS 結果或已打開的連線。
清除之後,網站為什麼還是連到舊位址?
檢查 /etc/hosts、代理伺服器或 VPN,再看看 dig 有沒有顯示新位址。如果上游的 DNS 紀錄還沒更新,本機怎麼清除都沒用。
Mole 可以清除 DNS 快取嗎?
不行。Mole Mac 沒有清除 DNS 的功能,請執行上面的終端機指令,或重新啟動 Mac。