讓 macOS 根據不同 Domain 選擇 DNS 伺服器

TL;DR

/etc/resolver/ 下建立與目標 Domain 同名的設定檔。

背景

由於在 macOS 設定 DNS resolver 的時候,OS 選擇查詢的 resolver 可能不是按照順序的,所以只要有任何一個 resolver 搶先回 NXDOMAIN 就會讓你的查詢找不到 Domain,這對一些有非公開網域或偷偷自定網域的人們來說十分的困擾。

一般來說,我們可能會想讓 Domain Server 分成內外兩組,把只有自己查得到的 domain 讓內部的 DNS 來解析,剩餘的其他網域則是讓外部的 DNS 來解析就好了,省去讓內部 DNS 做 recursive 的麻煩。

但由於 macOS DNS resolving 的設計(或我們說 BSD 的設計),使得直接將全域 DNS 設定為內部優先,外部次之的這件事情變得無法進行,此時可以利用手動設定的方式來達到將不同 domain 指定到不同 DNS 的目的。

resolver(5)

man 5 resolver[1] 裡面有提到一件事情,/etc/resolv.conf 記錄的是「主要的」DNS resolver 設定[2],但其實所有的設定除了會從 /etc/resolv.conf 讀取以外,還會從 /etc/resolver/ 目錄下面讀取[3]

對於這個目錄裡面的設定檔除了與 resolv.conf 格式一致以外,還有一個限制是檔名必須與要搜尋的 domain 同名,在關於 domain 的這個設定值的說明是這樣說的:

Domain

Domain name associated with this resolver configuration. This option is normally not required by the Mac OS X DNS search system when the resolver configuration is read from a file in the /etc/resolver directory.
In that case the file name is used as the domain name.

However, "domain" must be provided when there are multiple resolver clients for the same domain name, since multiple files may not exist having the same name.

也就是說,我們可以在 /etc/resolver/ 下建立於我們想要額外設定個別網域的 resolver 設定檔。方法也很簡單,我們接下來就來嘗試做點實驗:

/etc/resolver/

假定我們想要個別設定的網域為 davy.home(當然,這個網域實際上並不存在於這個世界上),那麼我們只需要建立 /etc/resolver/davy.home[4] 這個檔案即可,內容如下:

domain davy.home
search davy.home
nameserver 10.10.10.10
nameserver 10.10.10.100

在這個範例中,我設定了兩組 nameserver 分別是 10.10.10.1010.10.10.100,大家可以根據自己的實際情況設定。

雖然文件中寫說 domain 在 macOS 中不是必須的,但我還是按照填寫的規則寫上了 davy.home,各位讀者可以自行嘗試將此欄位移除是否仍然會生效。

接下來我們會清除 macOS 的 DNS cache 並檢查看看設定後的結果是否與我們想像的一樣:

# killall -HUP mDNSResponder
$ scutil --dns
DNS configuration
...
resolver #8
  domain   : davy.home
  search domain[0] : davy.home
  nameserver[0] : 10.10.10.10
  nameserver[1] : 10.10.10.100
  flags    : Request A records
  reach    : 0x00000002 (Reachable)
...
$

透過 scutil[5] 可以確認系統的 resolver 已經特化出給 davy.home 使用的設定了,此時大家就可以在不改變 Global resolver 的情況下來穩定查詢 davy.home 了。

結語

透過獨立 DNS resolver 的設定讓我們可以指定不同網域的查詢方式,也可以讓我們的 Domain Server 減去了不必要的 recursion 的負擔,對於我們這種可能會有一些實驗用的私人網域來說,比起其他系統會循序查詢 resolver 的方式真的是方便了不少。


  1. 此處指的是 macOS 的 resolver(5) 條目,可以直接透過 man 5 resolver 查閱內容,或參考 FreeBSD 收錄的檔案內容 ↩︎

  2. 原文為 "Note that the /etc/resolv.conf file, which contains configuration for the default (or "primary") DNS resolver client, is maintained automatically by Mac OS X and should not be edited manually. Changes to the DNS configuration should be made by using the Network Preferences panel." ↩︎

  3. 原文為 "These are at present located by the system in the /etc/resolv.conf file and in the files found in the /etc/resolver directory." ↩︎

  4. 預設情況下 /etc/resolver/ 這個目錄並不存在,大家自行新增即可 ↩︎

  5. 關於 scutil 的使用說明可以從 man 8 scutilFreeBSD 的收錄的說明查閱 ↩︎