在本文上集介紹架設 Caching-only DNS Server、DNS 客戶端工具使用介紹、架設內部專用的 DNS Server(正向解析)。
在本文中集介紹架設內部專用的反解 DNS Server、DNS Server 與 DHCP 整合應用(Dynamic DNS)。
在本文下集將會介紹架設 DNS slave server(包括正解、反解)、zone transfer 運作以及相關調整與設定。
若以先前架好的 DNS Server 來說,對於人數與主機數量都不多的中小企業環境,以這樣子的主機提供服務算是游刃有餘,照我們的經驗看來 Linux DNS Server 鮮少發生當機或軟體故障情況,反而比較要擔心是來自於硬體故障所造成的服務停擺,好在 DNS 通訊本身就有著良好的備援機制,允許我們架設多台(通常是兩台)Server 提供客戶端主機 DNS 查詢的需求,達成兩台 DNS Server 相互備援的功能。
架設兩台 DNS Server 以後,如果每一 zone 都設定成 master 的話,更改紀錄的時候就要一台一台來改,這樣子改會比較麻煩,所以通常建議配置成 master/slave 架構,架構完成以後只要更改 master 的紀錄就可以了,此時 slave 也會自動更新紀錄,管理上也比較方便;談到兩台之間 record 資料傳輸與同步的方式,是使用 zone transfer 來達成,接下來我們就以『架設 slave server』順便了解 zone transfer 運作。
準備一台 slave server 後,接下來我們就要在這台主機上,解說並測試 zone transfer。
zone transfer 動作主要是將某個 zone 的所有 record(紀錄)一次都抓回來,我們測試的方法是在 slave 主機使用指令「host -l ol 172.18.0.35」來向 Master 主機 172.18.0.35 做 ol 網域的 zone transfer 動作,此次 zone transfer 並沒有成功,原因是 Master 主機『TCP 53 埠』尚未開啟。

因為 zone transfer 的功能要用到,所以在 Master 主機使用「system-config-securitylevel」將 TCP 53 埠開啟。

回到 slave 主機再次測試即可正常,資料顯示如下圖。

請注意如果說 DNS Server 沒有特別調整的話,預設值是『允許任何主機來做 zone transfer 的』,這樣所有 record 就會被有心人士全部探查到,是不夠安全的作法,等到 master/slave server 都設定差不多了以後,我們再來關心 zone transfer 安全性的事情。
確定 slave 主機可以 zone transfer master 主機 ol 網域資料後,就可以開始在 slave 主機上新增 ol 網域且角色為 slave 的設定。
在 slave 主機開啟 /etc/named.conf 『模仿 master 主機的設定』增加檔案內容如下:
options {
directory "/var/named"; // 之後的 record 都是放在 /var/named/ 目錄下
};
zone "ol" in {
type slave; // 這次要當 slave 不是當 master
file "slaves/ol.bak"; // record 檔案位於 /var/named/slaves/ol.bak
// allow-update { localhost; }; // slave 不需要允許動態更新,所以這行註解起來
masters { 172.18.0.35; }; // 指明 master 是 172.18.0.35 這個 IP 的主機
};
以上輸入 zone "ol" 這一段是用來新增 ol 網域這次的角色為 slave(檔案內容中 type slave)。

特點一:這次是當 slave ,也就是『type slave』。
特點二:也就因為設定了『type slave』所以要指明 master 主機在哪裡;使用 masters 參數設定找 master 主機(IP 為 172.18.0.35),例如『masters { 172.18.0.35; };』那行的設定。
特點三:『file "slaves/ol.bak"』將 zone transfer 回來的資料放在 /var/named/slaves/ 目錄下的 ol.bak 檔案,不直接放在 /var/named/ol.bak 的原因主要是權限問題(待會再詳述)。
另外 DDNS 是找 master 更新即可,所以 slave 就可以把 allow-update 那行設定註解起來(關於 DDNS 請參考本文中集)。
寫好了之後接著重啟 named(指令「/etc/init.d/named restart」)會從 master 主機 zone transfer 有關 ol 網域的資料,然後寫入 /var/named/slaves/ol.bak 這個檔案內容。

與上一期的 DDNS 狀況類似,做 DDNS 時使用帳號 named 寫入 /var/named/data/ 這個目錄;而做 zone transfer 後的資料,所使用的權限也是 named 這個帳號,寫入 /var/named/slaves/ 這個目錄。
使用指令「ps ax | grep named」觀察到 named 執行期間用了『-u named』這個選項,意思是使用帳號 named 存取資料。
觀察 /var/named/ 目錄下有個 slaves/ 目錄,權限剛好是 named 這個帳號可以寫入,所以我們在 /etc/named.conf 中,zone "ol" 區段內使用 file "slaves/ol.bak"; 就是將檔案放在能夠擁有讀寫權限的這裡。

假如將上例 file "slaves/ol.bak"; 設定成 file "ol.bak"; 的話(意思是檔案 /var/named/ol.bak 在此情況下會造成寫入失敗),重新啟動 named 後,

觀察 /var/log/messages 的尾端(例如使用指令「tail /var/log/messages」)會有『dumping master file: tmp-ZoXK7PLGoU: open: permission denied』的類似訊息,主要是 zone transfer 回來的資料,要寫到 ol.bak 的時候,寫入的權限不足所造成。

slave 主機只需要能夠被 DNS 一般查詢即可,並不需要提供 zone transfer 功能,意味著只需要開啟 UDP 53 埠,至於 TCP 53 埠(主要用在 zone transfer)應該是不用開啟(除非特殊需要)。
slave 主機在 firewall 設定完成後,使用其他台 client 主機 dig 指令測試一下,應該是沒有甚麼問題的,例如指令「dig @172.18.0.191 ns1.ol」,是向 slave 主機(IP 172.18.0.191)詢問 ns1.ol 的紀錄,依下圖來看回答是有紀錄的(會跟 master 主機的資料一樣)。

在『架設正解 slave server』完成之後,此時 slave 知道 master 的主機資訊(主機名稱 ns1.ol 使用 IP 是 172.18.0.35);但是 master 還不曉得 slave 的主機資訊(主機名稱 ns2.ol 使用 IP 是 172.18.0.191),這時候要到 master 主機加上兩筆紀錄:一筆是『slave 主機是 Name Server 紀錄』另一筆是『slave 主機的 A 紀錄』。
在新增紀錄的期間,因為我們先前使用 DDNS(動態 DNS)的關係,觸動了 SELinux 顧及主機安全的保護機制,就順道一併說明如下:
在本文中集時提到,使用 DDNS 的時候,會產生結尾為 .jnl 的檔案(journal),也就是『日誌』檔案,也因為這個日誌檔案的關係,使得當我們要修改紀錄的時候,要先停止 named 的運作(讓 jnl 同步回去原來的檔案),再去更改原來檔案的紀錄內容,改完後於 named 啟動前,記得把 jnl 檔案砍掉,運作會比較正常。
經由動態更新後的 ol 網域她 SOA 序號會比原先紀錄檔案內的序號大(我們可以利用指令「dig ol soa」來觀察『當下』SOA 紀錄的序號會比原先在 ol.db 檔案內的序號大(下圖內 2008081512 大於 2008081511)。

例如我們要在 master 主機修改 ol 網域紀錄資料時,要先將 named 停止運作(使用指令「/etc/init.d/named stop」),這時在 jnl 的最新資料,就會回寫到紀錄檔案,原以為事情就這樣搞定,但卻被 SELinux 阻擋住而回寫失敗。
jnl 檔案回寫失敗後,會在相同目錄下(/var/named/data/)產生 tmp-XXXXXXXXXX 檔案,觀察 ol.db 檔案 SOA 紀錄的序號會發現這依然是舊的檔案(還是 2008081511)。

觀察 /var/log/messages 的尾端(指令「tail /var/log/messages」)會看到因權限不足所造成的寫入失敗訊息『dumping master file: rename: data/ol.db: permission denied』,以及 SELinux 阻擋的相關資訊與因應之道『For complete SELinux messages. run sealert -l 10f19abd-f4ba-4a6a-9b0c-473d9fd3cf4e』。

接著照 SELinux 所說的執行指令「sealert -l 10f19abd-f4ba-4a6a-9b0c-473d9fd3cf4e」,其中會看到使用 setsebool 相關的一行指令「setsebool -P named_disable_trans=1」用來關閉 SELinux 針對 named 服務的保護,就會允許 named 的 jnl 檔案回寫紀錄檔案。

執行指令「setsebool -P named_disable_trans=1」在重新啟動 named(兩次)之前與之後,觀察 /var/named/data/ 目錄下的檔案 security context 與檔案權限,應該都能夠使得 named 正常讀寫(tmp-XXXXXXXXXX 也可以清掉囉)。

本文介紹的 DDNS 比較建議使用在信任的內部網路區域,用在 Internet 的話就顯得不夠安全,若要提供給較安全的 Internet DDNS 服務,可以考慮使用 DDNS 本身有比較安全的機制,這機制促使客戶端更新 DDNS 資料時需要 key 與密碼,甚至搭配 key 利用 named.conf 中 update-policy 參數限定用哪個 key 才能 update 哪些資料,達到既方便又安全的動態 DNS 服務。
了解 DDNS 與 SELinux 所造成的一些狀況以及處理方法後,接下來在 master 主機新增 NS 紀錄指向到 ns2.ol、ns2.ol 的 A 紀錄指向到 slave 主機的 IP 172.18.0.191,完成後 slave 主機就叫做 ns2.ol 了。
首先把 named 停掉(因為 DDNS jnl 的關係,改紀錄前要停 named)使用指令「/etc/init.d/named stop」。
編寫紀錄檔案 /var/named/data/ol.db 加上『 NS ns2.ol.』、『ns2 A 172.18.0.191』一筆是 ns2.ol 主機正式加入 NS(Name Server 行列、另一筆是 slave 主機命名 ns2.ol 的 A 紀錄指向 IP 172.18.0.191。
還有就是紀錄檔案的 SOA 序號 2008081512 記得至少要加一,例如增加成 2008081513。
重啟 named 之前記得砍掉 jnl 檔案(指令「rm /var/named/data/ol.db.jnl」)。
改完把 named 啟動(使用指令「/etc/init.d/named start」)並測試新增的紀錄是否正常。

如果忘記砍掉 jnl 檔案就啟動 named 的話,會在 /var/log/messages 尾段看到『zone ol/IN: journal rollforward failed: journal out of sync with zone』錯誤訊息,可能會發生整個 zone 資訊都變得查不到的怪現象。

剛才加上兩筆紀錄重新啟動 named 後,master 主機會『notify』(通知)ns2.ol 主機來做紀錄資料的更新,在 master 主機序號大於 slave 主機的情況下,slave 紀錄資料就會更新,更新成功後兩台的序號就會相同(例如:2008081513)。
使用編輯紀錄檔的方式更改 DNS 紀錄較適用於沒有 DDNS 情況下,在有 DDNS 的情形下要先停用 named 改完還要砍掉 jnl 檔案再啟動 named 著實麻煩,其實我們也可以應用動態更新的指令 nsupdate 增減 DDNS 紀錄,我們就以新增 ol 網域一個名為 test 的 A 紀錄指向 IP 172.18.0.103 介紹如下:
在 master 主機使用指令「nsupdate」進入 nsupdate 運作模式下,
輸入「server 127.0.0.1」意思是要向主機 127.0.0.1 要求資料更新,因前一集有設定過『allow-update { localhost; };』,所以會被允許。
輸入「zone ol」意思是要更新 ol 網域。
輸入「update add test.ol 21600 A 172.18.0.103」新增 test.ol 其 TTL 為 21600 的 A 紀錄指向 172.18.0.103。
輸入「send」送出。
輸入「quit」結束,離開 nsupdate 模式。

既然正解 slave server 完成後,反解的部份就順便處理一下。
已經有先前打好的基礎觀念,對於測試反解 zone transfer 應該是易如反掌。
指令「host -l 18.172.in-addr.arpa 172.18.0.35」針對主機 172.18.0.35(也就是 master)做 172.18.Y.Z 網域反解 zone transfer,正常訊息如下圖。

在 slave 主機開啟 /etc/named.conf 參考『master 主機 named.conf 設定』以及『此檔案 ol 網域 slave 設定』 增加檔案內容如下:
zone "18.172.in-addr.arpa" in {
type slave; // 這次要當 slave 不是當 master
file "slaves/172.18.bak";// record 檔案位於 /var/named/slaves/172.18.bak
// file "172.18.bak"; // record 檔案放這 /var/named/ol.bak 會寫入失敗
// allow-update { localhost; }; // slave 不需要允許動態更新,所以這行註解起來
masters { 172.18.0.35; }; // 指明 master 是 172.18.0.35 這個 IP 的主機
};

與正解的 ol 網域 slave 設定非常類似,差別只在 zone 名稱變成『18.172.in-addr.arpa』與 file 的檔案名稱改成『172.18.bak』(依舊是放在 slaves/ 目錄下)。
寫好接著重啟 named 後,觀察是否有正確地產生檔案 172.18.bak,再使用 dig 向 slave 主機做測試,例如指令「dig -x 172.18.0.35 @172.18.0.191」。
我們其實還有兩個小動作尚未完成,說明如下:
這次直接使用 nsupdate 來增加這兩筆紀錄,取代編輯檔案的方式,順便介紹反解網域的 DDNS 更新方法如下:
在 master 主機使用指令「nsupdate」進入 nsupdate 運作模式下,
輸入「server 127.0.0.1」
輸入「zone 18.172.in-addr.arpa」意思是要更新 172.18.Y.Z 反解網域。
輸入「update add 18.172.in-addr.arpa 21600 NS ns2.ol」新增反解網域 NS 紀錄指向到 ns2.ol。
輸入「update add 191.0.18.172.in-addr.arpa 21600 PTR ns2.ol」新增 172.18.0.191 反解 PTR 紀錄指向到 ns2.ol。
輸入「send」送出。
輸入「quit」結束,離開 nsupdate 模式。

另一種不用停止 named 就可以編輯修改 DDNS 紀錄檔案的方式適用於 bind 9.3 以後的版本,例如:可先使用指令「rndc freeze ol」(凍結住 ol 網域)此時變得無法 DDNS 更新(如下圖『update failed: REFUSED』訊息)但卻是最適合直接修改紀錄檔案的時候,待更改完成後再「rndc unfreeze ol」(解凍結)即可。

為了讓內部區域網路使用 DHCP 的客戶端主機能夠在 ns1.ol 故障的時候,名稱解析自動改用 ns2.ol 這台 DNS Server,需要修改 DHCP Server 發配出去的名稱解析伺服器,將原來只詢問 ns1.ol 的設定,改成 ns1.ol 問不到的時候問 ns2.ol,接下來編輯 DHCP Server 設定檔案 /etc/dhcpd.conf 修改內容如下:
將原來的這一行『option domain-name-servers 172.18.0.35;』
改成這樣『option domain-name-servers 172.18.0.35, 172.18.0.191;』(加上 ns2.ol 的 IP 172.18.0.191)
記得重新啟動 dhcpd 使之生效(指令「/etc/init.d/dhcpd restart」)。

到現在為止我們架設的 DNS 主機都是放在區域網路內,沒有直接對外服務的風險,所以前三篇文章都是以實用性為主,比較沒有顧慮到安全方面的防護,在下一期的文章中,主要就是追加介紹 DNS 主機安全相關的常見調整設定實戰應用。