作者:徐秉義(Albert Hsu)
在本文上集介紹架設 Caching-only DNS Server、DNS 客戶端工具使用介紹、架設內部專用的 DNS Server(正向解析)。
在本文中集介紹架設內部專用的反解 DNS Server、DNS Server 與 DHCP 整合應用(Dynamic DNS)。
在本文下集介紹架設 DNS slave server、zone transfer 運作以及相關調整與設定。
在本文特集將會介紹 DNS server 安全防護設定、forwarders 設定、acl 與 view 設定、網域名稱購買以及設定等等。
在先前的文章介紹是以『先求有、再求好』方式,架設『能夠使用、提供功能』的 DNS Server 為主,至於安全性方面仍待加強,底下就先從 zone transfer 安全性開始談起。
限制 zone transfer 來源主機
先前有談到過預設建置的主機是『允許任何來源主機做 zone transfer 動作』,這樣會導致隨便一台主機都可以將所有紀錄探查出來,如此感覺起來較不安全,一般我們建議設定成『master 主機允許 slave 來做 zone transfer』且『slave 主機不允許 zone transfer』。
在 master 主機限制 zone transfer 來源只能是 slave
要做到這個限制的關鍵參數是『allow-transfer』。
編輯 master 主機 named.conf 檔案,加入一行『allow-transfer { 172.18.0.191; };』(172.18.0.191 是 slave 主機 IP)。
上述這一行擺放的位置是在 options 區段的話,影響範圍到所有的 zone;若只是擺放在某個 zone 區段的話,就只針對這個區段才有效果(例如只放在 ol 的 zone)。
下圖是將『allow-transfer { 172.18.0.191; };』這行放在 options 區段的快照。
改好設定檔案記得重新啟動 named(指令「/etc/init.d/named restart」)使她生效。

測試時分別到 slave 主機(IP 是 172.18.0.191)以及『非』slave 主機執行指令「dig ol axfr @172.18.0.35」,應該只有 slave 主機能夠向 master 主機 zone transfer 資料,其他『非』slave 主機向 master 做 zone transfer 應該要失敗才對,如下圖會有『Transfer failed.』訊息。

溫馨提示:查詢反解 zone transfer 指令也可使用 dig,例如「dig -x 172.18 axfr @172.18.0.35」。
在 slave 主機限制不開放 zone transfer
編輯 slave 主機 named.conf 檔案,加入一行『allow-transfer { none; };』,此行的設定意思是『任何一台來源主機都不允許 zone transfer』。

設定好了之後同樣也是要重新啟動 named 以及測試能否被 zone transfer(應該要不行才是正確的)。
溫馨提示:先前我們並未在 slave 主機開啟 TCP 53 埠,所以原本就無法 zone transfer 成功(因為防火牆擋住)。
在有防火牆以及應用程式的設定檔案雙重保護下,就算是防火牆不小心開放 TCP 53 埠,還有應用程式這一層的保護(依然不允許 zone transfer)。
應用 named chroot 機制提昇安全性
在指令「yum list | grep bind」中會看到一個名為『bind-chroot』套件,能夠提昇 DNS Server 的安全性。
使用指令「yum install -y bind-chroot」把她裝起來吧!

觀察安裝 bind-chroot 後的 DNS Server
使用指令「ps ax | grep named」觀察到『/usr/sbin/named -u named -t /var/named/chroot』重點在於『-t 選項以及其後面銜接的 /var/named/chroot 參數』。

在這個情況下,實際 DNS Server 相關設定與資料擺放的位置是在 /var/named/chroot/ 目錄下。
利用 ls -l 指令觀察原本設定檔案 /etc/named.conf 變成軟連結到 /var/named/chroot/etc/named.conf
利用 ls -l 指令觀察原本 zone 紀錄檔案 /var/named/data/ol.db 變成軟連結到 /var/named/chroot/var/named/data/ol.db
利用 ls -l 指令觀察原本 zone 紀錄檔案 /var/named/data/172.18.db 變成軟連結到 /var/named/chroot/var/named/data/172.18.db

觀察 /var/named/chroot/ 目錄下,有個精簡的根目錄結構,精簡到只能運行 named 而已(如下圖)。

真正的設定檔案以及 zone 紀錄檔案都已經改成放在 /var/named/chroot/etc/named.conf、/var/named/chroot/var/named/data/{ol.db,172.18.db},未來若要修改設定或是 zone 紀錄檔案,建議直接修改 /var/named/chroot/ 目錄下的資料就可以了。
有 bind-chroot 的情況下比較安全是因為 named 運行期間是 chroot 到 /var/named/chroot/ 目錄下在跑的,所以 named 也就無法存取原先的根目錄,就算是遇到 named 資訊安全漏洞的問題,被攻擊的範圍會比較小,也比較不會影響整台 Linux 運作。
溫馨提示:筆者建議剛接觸學習 DNS Server 的時候,一開始先不要安裝 bind-chroot 的用意,是讓學習的難度降低,等到學的差不多都懂了再補裝上去即可。
關於 recursion 設定
本文曾在上集介紹過 dns 查詢的流程,基本上 DNS client 端發問都是 recursion 查詢,預設的 DNS Server 也是允許 recursion 查詢的。有些 DNS Server 可能為了增加安全性而將 recursion 功能關閉;接下來先說明 DNS Server 開放 recursion 查詢與不開放 recursion 查詢的差異如下:
開放 recursion 與拒絕 recursion 差異
在開放 recursion 查詢的情況下,Client 端來問的所有查詢,DNS Server 都『盡力』回答出來,不論這個答案是 Server 自己提供的資訊,或是向別台 Server 問出來的解析;相反地在拒絕 recursion 查詢的情況下,就只會回答自己管理的 zone 解析以及根主機資訊。
| 開放 recursion 查詢 | 不僅回答自己管理的 zone 解析,還幫忙向其他 Server 詢問 |
| 拒絕 recursion 查詢 | Server『僅僅』回答自己管理的 zone 解析以及根主機資訊 |
舉例來說:向我們自行架設的 DNS Server 詢問 www2.babyface.com.tw 解析,預設是開放 recursion 查詢的,所以就算這個查詢不是我們管理的 zone 也會代為詢問出解析(如下圖,指令「dig www2.babyface.com.tw @ns1.ol」)。

筆者向 Yahoo 的 DNS Server(ns1.yahoo.com)使用指令「dig www2.babyface.com.tw @ns1.yahoo.com」此 Server 就沒有回答 www2.babyface.com.tw,應該是因為她拒絕 recursion 查詢的關係。

若是向 Yahoo 的 DNS Server(ns1.yahoo.com)使用指令「dig www.yahoo.com @ns1.yahoo.com」(www.yahoo.com 應該是她管理的紀錄吧!)此 Server 就會回答 www.yahoo.com 解析。

溫馨提示:是不是她管理的 zone(以及紀錄)可由 TTL 是否減少而快速探查或是仔細看 dig 指令回應內容中的『flags:aa』來判斷(先前 recursion 查詢成功的 flags:為 ra)。
關閉 recursion 時機
至於甚麼時機會將 recursion 的功能關閉 ,一是為了讓 DNS Server 更加地安全,只回應需要回答的查詢;另一個考量的原因是避免浪費無謂的頻寬,去回答不一定需要回應的查詢。
通常建議開放 recursion 給我們信任的 client 端(信任的 client 端通常是內部主機;對於 ISP 業者來說則是她的客戶),對其他 client 端則可以關閉 recursion 查詢功能。
設定開不開啟 recursion
設定開不開放 recursion 可使用『allow-recursion』(類似 allow-transfer 格式)或『recursion yes』(或是 no)來做。
例如編輯 named.conf 加入『recursion no;』即可關閉 recursion 功能。

上述的方法是整個關掉(或是開啟),若是針對某些來源 IP 來做開放,使用 allow-recursion 會比較方便。
例如:編輯 named.conf 加入『allow-recursion { 172.18.0.0/16; };』設定來源 IP 是 172.18 網段才允許 recursion 查詢。

溫馨提示:『recursion』、『allow-recursion』都只能設定在 options 區段,不能設定在 zone 區段。
forwarders 應用
開放 recursion 查詢的 Name Server 可搭配 forwarders 選項功能,此功能將 Client 端 DNS 查詢 forward(轉送)給某(幾)台 DNS Server 來得到回應,設定 forwarders 選項的原因不外乎是希望得到更快速 DNS 查詢回應。
選項 forwarders 範例
例如開啟 named.conf 檔案,在 options 區段加入『forwarders { 168.95.1.1; 168.95.192.1; };』如此設定會將 DNS 查詢 forward 給 ISP 的 Name Server 168.95.1.1 與 168.95.192.1 這兩台,請注意兩個 IP 之間的分隔符號是『;』分號。
記得重新啟動 named 使設定生效。

設定 forwarders 選項比較需要注意到的是,別錯誤設定指向到較遠的 Name Server 去,例如:明明是使用 Seednet ISP 線路卻設定 forwarders 到 Hinet Name Server 的話(應該就近 forward 到 Seednet Name Server 查詢才對),這樣錯誤的設定反而會造成反效果,查詢時的反應速度可能比起不設定 forwarders 還要慢呢!
溫馨提示:遇到更換 DNS Server 對外 IP 的時候,倘若 ISP 業者也有更換的話,最好檢查一下 forwarders 的設定是否適當。
檔案語法檢查工具
在編輯 named.conf 與 zone 紀錄檔案的時候,難免會出現輸入錯字或是語法有誤的情況而不自知,建議使用 named-checkconf 指令來檢查 named.conf 檔案內容的正確性;以及使用 named-checkzone 指令來檢查 zone 紀錄檔案內容是否正確。
語法檢查工具使用範例
指令「named-checkconf」使用方法就是直接執行即可,有錯誤立刻就會顯示出來,參數頂多加上設定檔案 named.conf 位置(有做 chroot 的話建議搭配 -t 選項以及 /var/named/chroot 參數),如果檔案存放路徑特殊的話才會需要多下參數。
至於 zone 紀錄檔案的檢查比較複雜一些,例如指令「named-checkzone ol /var/named/chroot/var/named/data/ol.db」用來檢查 ol zone 紀錄檔案;「named-checkzone 18.172.in-addr.arpa /var/named/chroot/var/named/data/172.18.db」用來檢查 172.18.Y.Z 反解網域。

自行定義 acl
我們可以在 named.conf 中替某些 IP 或網段定義成名稱,以方便後續的應用,要這樣做的話是使用 acl 這個選項,至於後續的應用,例如使用『allow-transfer』、『allow-recursion』或是『allow-query』這些參數。
使用 acl 範例
『acl slave { 172.18.0.191; };』定義 slave 這個名稱是 172.18.0.191 這個 IP。
『acl example { 172.19.0.0/16; 10.; };』定義 example 這個名稱是 172.19.0.0/16 以及 10.開頭的這個兩個網段(使用 /16 或直接『.』結尾都可以用來表達網段)。
『acl except { ! 192.168.2.0/24; };』定義 except 這個名稱是『除了 192.168.2.0/24 這個網段之外』(應用 ! 驚嘆號可用來『反向選擇』;使用 /24 代表遮罩 255.255.255.0)。
例如定義好 acl slave 這個名稱以後,先前設定的『allow-transfer { 172.18.0.191; };』可以改寫成『allow-transfer { slave; };』。

內建的 acl 名稱
還記得我們曾經在 slave 主機 named.conf 設定 allow-transfer 選項成 none 嗎?這個『none』就是內建的 acl 名稱之一,代表著『沒有一個 IP 是』的意思,除了 none 以外,內建的 acl 名稱還有:
『any』代表任何來源主機/IP。
『localhost』代表 DNS 主機本身所使用的 IP,包括 eth0、eth1、ppp0、lo 等等。
『localnets』代表 DNS 主機所使用的 IP 網段,同樣包括 eth0、eth1、ppp0、lo 這些介面。
例如設定 named.conf 選項『allow-query { any; };』是允許所有來源 IP 來查詢 DNS 紀錄。
使用 view 功能
bind 9 版 view 實用功能是能夠依照不同的來源 IP/網段,回答不同的解析答案。
舉個例子來說:假設我們管理 foo.com.tw 這個 zone,區域網路網段 IP 是 192.168.2.0/255.255.255.0,若是希望來自 192.168.2.0/24 網段發出詢問 www.foo.com.tw 紀錄,解析成 192.168.2.168 這個 IP;而其他外部 IP(例如:4.5.6.7 這個 IP)來查詢 www.foo.com.tw 則是回應成公開 IP(例如:211.21.50.85)。
以往要達到上述功能,都是架設兩台 Name Server 來達成,一台對內解析、一台對外解析,至於為何需要內外解析不同,最常遇到是因為 NAT(Network Address Translate)架構造成這個需求;假如說更講究的再 master/slave 配置一下,總共就需要管理四台 Name Server!
簡而言之,導入 bind 9 view 功能有著內外兩台合併成一台的優勢。
view 功能範例
使用 view 功能習慣性會先用 acl 定義網段名稱以後,在使用 view 來做出不同的來源 IP 詢問,回應不同解析的需求。
底下是一個相當精簡『有 view 功能』的 named.conf 檔案內容:
options {
directory "/var/named";
};
acl lan { 192.168.2.0/24; };
view "inside" {
match-clients { lan; };
zone "foo.com.tw" in {
type master;
file "foo.com.tw.in.db";
};
};
view "outside" {
match-clients { any; };
zone "foo.com.tw" in {
type master;
file "foo.com.tw.out.db";
};
};
『acl lan { 192.168.2.0/24; };』定義 lan 是 192.168.2.0/24 網段
"inside" 是給內部看的 view 區段
在 inside 的 view 中 match-clients { lan; }; 意思是符合的來源 IP 是 lan 這個 acl 名稱,也就是 192.168.2.0/24 這個網段。
zone "foo.com.tw" 內的 file 是 "foo.com.tw.in.db" 這個檔案,寫的解析應該有一筆需要解成內部的 www 指到 192.168.2.168(依照先前舉的例子來設定)。
"outside" 是給外部看的 view 區段
在 outside 的 view 中 match-clients { any; }; 意思是符合所有來源 IP(除了先前的 inside 那個 view 中 match-clients 的 lan 以外)。
zone "foo.com.tw" 內的 file 是 "foo.com.tw.out.db" 這個檔案,寫的解析應該有一筆需要解成外部的 www 指到 211.21.50.85(同樣也是依照先前舉的例子來設定)。

接下來是輸入 zone 紀錄檔案內容兩個(一個 foo.com.tw.in.db、一個 foo.com.tw.out.db),重新啟動 named 並使用不同的來源 IP client 端測試結果是否如預期。
溫馨提示:在有 view 情況下 master/slave 之間 zone transfer 變得比較複雜些,因為被 view 隔開成兩個相同名稱的 zone(例:foo.com.tw)如果都需要 transfer 的話,我們可以在 slave 主機 named.conf 中分別針對內外兩個 foo.com.tw zone 設定 transfer-source 選項來指明 transfer 的來源 IP(此時 master/slave 主機應該會有兩個以上的 IP,而且分別都要互相連線的到才可以)。
對外公開網域名稱的管理
我們一開始設定管理的是個不需對外的 ol 網域,至於談到要管理對外公開的網域名稱(例:foo.com.tw),直覺方式是仿造先前學習的 ol 網域,仿製成 XXX.com.tw 的 zone,別以為做出 XXX.com.tw 以後全世界就能查的到喔!還有兩件事情要做:一個是『主機對外服務(用到公開 IP)』另一個是『處理網域名稱授權的事情』。
要讓全世界都能夠詢問,勢必要將主機對外(使用 Public IP 或是 NAT 轉址進來皆可),將主機對外了以後,全世界並不會『主動』向這台(或是這兩台;一台 master、一台 slave)詢問他管理的 zone,所以還要向上層處理『向下授權』的事情才妥當,處理『向下授權』需要費用並且設定正確後,全世界才能夠正常地詢問到我們所管理以 XXX.com.tw 結尾的相關紀錄(例如:www.XXX.com.tw 指向 3.4.5.6)。
主機對外服務
將主機對外服務不是難事,花錢買線路並調整成正確的 IP 即可(通常買的是固定 IP 喔),底下主要探討是依照中小企業購買網際網路線路的情況,配合 DNS Server 配置。
類型一:『一條線路、僅僅一個 IP』那就只能一台對外,很可能只架設 master 而沒有 slave,就算有架 slave 也無法同時對外(不會有人想要輪流對外吧?)。
類型二:『一條線路、多個 IP』建議架成 master/slave 架構,兩台皆對外服務,保有一台主機掛掉,另一台主機能夠繼續提供服務的優勢。
類型三:『多條線路、多個 IP,同一機房地點』分散在不同線路的兩台主機,可保有其中一條線路中斷,另一條線路的主機能夠繼續服務之優勢。
類型四:『多條線路、多個 IP,不同機房地點』分散在不同地點、不同線路的兩台主機,可保有其中一個機房地點大停電(或是大災難),另一個地點的主機能夠繼續服務之優勢。
網域名稱申購與設定
在台灣要購買網域名稱,通常是到『http://www.twnic.net.tw/』進入後左上角先查看看想要用的網域名稱是否已經被別人買走了(其實就是 whois 指令查到的結果)下圖是此網域名稱尚未被人購買的畫面。

台灣的網域名稱,已經由民間代為銷售,所以可以去以下其中一家購買(如上圖所述)
協志聯合科技股份有限公司(http://reg.tisnet.net.tw) 亞太線上服務股份有限公司(http://rs.apol.com.tw/) 中華電信數據通信分公司(http://nweb.hinet.net) 網路中文資訊股份有限公司(http://www.net-chinese.com.tw) 網路家庭國際資訊股份有限公司(http://myname.pchome.com.tw) 數位聯合電信股份有限公司(http://rs.seed.net.tw) 台灣固網股份有限公司(http://domains.tfn.net.tw/) WebCC Ltd.(http://www.webnic.tw/)
買好以後就會得到一組帳號密碼,用來管理網域名稱的相關資訊,其中跟我們最相關的就是 DNS 管理(也就是 whois 紀錄的修改),填寫的欄位各家大同小異,舉例如下(通常最多五個空白行提供填寫,下圖為兩個空白行):
| DNS 主機名稱 | IP 位址 |
如果是類型一(假設網域名稱 foo.com.tw、公開 IP 是 2.3.4.5),填寫的範例如下:
| DNS 主機名稱 | IP 位址 |
| ns1.foo.com.tw | 2.3.4.5 |
| ns2.foo.com.tw | 2.3.4.5 |
如果是類型二、三、四,這三種類型其實設定類似(假設網域名稱 foo.com.tw、公開 IP 是 2.3.4.5、5.6.7.8),填寫的範例如下:
| DNS 主機名稱 | IP 位址 |
| ns1.foo.com.tw | 2.3.4.5 |
| ns2.foo.com.tw | 5.6.7.8 |
設定好 DNS 管理以後就同等於處理好向上層要求『向下授權』的事情,我們可以使用指令「whois foo.com.tw」來確認修改是否正確。
另外 DNS Server 上的 NS 紀錄與對應的 A 紀錄最好要跟 whois 查出來的一致,運作才會順暢,例如:指令「dig foo.com.tw ns」、「dig ns1.foo.com.tw」與「dig ns2.foo.com.tw」回應的資訊,應該要跟「whois foo.com.tw」顯示的資訊相符。

