Chapter 14 The Domain Name System(網域名稱系統)

壹. DNS 說明

一. DNS的功能簡介

DNS 全名是 Domain Name System, 透過 DNS 系統, 我們可以由一部機器的 domain name 查其 IP, 也可以由機器的 IP 反查它的 domain name, 除此之外 DNS  還與 Mail System 結合, 提供 Mail routing 的功能.

早期這個 domain name 與 IP 的對應表是記在每部機器的 /etc/hosts 這個檔案, 當電腦個數不多還好, 但是電腦數目一多就會發生問題了. 因為用 hosts 記錄有問題, 所以後來發展出 DNS.
 

二. Domain Name Space

整個 INTERNET 上的電腦如此眾多, 如何保證兩部電腦不會有相同的 domain name/IP 是一個很重要的問題.

1. Domain (網域)
將整個 internet 分成許多 domain, 每個 domain 下又細分為許多 domain, 然後這些細分的 domain 視實際需求又再細分成許多 domain, 一直循環下去.
基本上每個 domain 內的 mapping 由一部主機負責管理.

top level domain - com, edu, gov, mil, net, org, int (現在又多出許多 top domain 了如 isp, art 等)


 

2. Delegation (授權)
每個 domain 都可因實際需求再細分成許多 sub domain. 上層的 domain 可以將其分出的某個 sub domain 的 domain name 與 IP mapping 交由另一部機器管理, 這個動作我們稱之為 delegation

3.Forward/Reverse(正解/反解)
在講到 domain name <-> IP mapping, 其實應該看成兩個命名空間:

一個是 domain name -> IP, 稱之為 forward mapping,  在這個命名空間中就是先分成前面提到的那些 top domain, 再細分 sub domain,
比如說 winnie.corp.hp.com -> 15.16.192.152 代表在負責  corp.hp.com 這個 sub domain 的機器上, 可以查到其 mapping table 上有一筆記錄是 winnie -> 15.16.192.152.

另一個是 IP -> domain name 稱為 reverse mapping. 在這個命名空間中, 所有的 IP 組成一個叫作  arpa.in-addr 的 top domain, 然後再依 IP 層層細分, 比如說 15.16.192.152 -> winnie.corp.hp.com 代表在負責 192.16.15.in-addr.arpa(注意是反過來寫, 因為 top domain 要在最後面) 這個 sub domain 的機器上,  可以查到其 mapping table 上有一筆記錄是 152 -> winnie.cop.hp.com

特別值得注意的是:
a. 負責 forward mapping 和 reverse mapping 的機器不一定是同一部
負責 corp.hp.com domain 與負責 192.16.15.in-addr.arpa 的機器不一定是同一部機器, 即使在同一部機器, 如果不注意的話, 兩邊的內容可能也會有不 match 的情形.
b. domain 與 ip subnet 並沒有一對一關係
舉例而言朝陽的 domain 是 cyut.edu.tw, 但是因為朝陽內部機器數多的關係, 所用到的 IP subnet 有 163.17.1 ~163.17.32, 共 32 組 subnet
 

4. Name Server

負責記錄 forward/reverse mapping 的機器會執行一個叫 name server 的軟體, 透過這個軟體回應來自其它機器對 domain name 或 IP 的查詢

   4.1. zone & domain
基本上每個 domain交由一個機器來負責, 更精確地說應該是每個 zone 交由一個 name server 來負責, 所謂 zone 就是把一個 domain 扣掉分給下層負責的部份, 剩下來的就是 zone

    4.2. Primary/Secondary
每個 zone 交由一部 name server負責的作法會有一個問題, 萬一這個 name server 當掉, 可能造成 INTERNET 上其它機器無法取得屬於這個  zone 的資料(就是 domain name 和 ip mapping). 為了避免這種情形, 我們可以把這個 zone 的資料同時交給多部 name server 負責.原本的這部稱為 primary name server, 其它的稱為 secondary name server. Secondary name server 會定期將 primary name server 上 zone 的資料拷貝一份下來備用.

對於上層的 name server 而言, 它只是設定某個 zone 同時 delegate 給好幾個下層 dns server, 但是它並不去分辨誰是真正的 primary, 誰是 secondary. 它只是依據順序尋問, 當第一部負責某個 zone 的 dns server 當掉時, 它會依序找下一個負責的 dns server.

ps: primary/secondary 在新版 name server 程式中改稱為 master/slave
 

三. Name Resolution (名稱解析, 名稱查詢) 的觀念

接下來我們介紹名稱查詢運作時一些重要名詞或觀念

1. Resolver
A resolver is any client that has the ability to query a DNS database for name resolution. This means that all DNS servers, despite their DNS role, can also be considered resolvers since they can resolve names on behalf of the object actually requesting the data.

 

2. Root Name Server
在查詢資料時, 總是要有一個起點, 當一個 local DNS server 收到來自 client 端關於一個 domain name 的查詢, 這個 local DNS server 怎麼知道這個 domain name 的相關資料是記錄在 INTERNET 中的哪一個 DNS 上呢?
答案是向 root name server 尋問. root name server 記錄了各 top domain 分別是由哪些 DNS server 負責. 比如說要找 www.yohoo.com 時, root name server 會告訴 local DNS server 哪部 name server 負責 .com 這個 domain, 然後 local dns 再向負責 .com 的 name server 詢問關於 yohoo.com 是哪部 name server 在負責. 最後 local DNS 就可以向負責 yohoo.com 的 name server 問到有關 www.yohoo.com 的資料.

註: 考量 root name server 會被全世界的 DNS sever 詢問, 負擔很大, 在世界各地共有十多個root name server. 而每個 name server 軟體都附有一個文字檔, 其中記錄了這十多個世界知名的 root name server 的 IP 位址

3.Recursive Query
A recursive query is a request from a host to a resolver to find data on other name servers.

 DNS client 端發出一個查詢給 DNS server, 然後 DNS server 就會不斷地查, 直到答案出來為止, 最後把結果傳回來給 client, 這種查詢稱為 recursive query.

上圖中 DNS client (resolver) 端向 local DNS server 進行 recursive query, 查 girigri.gbrmpa.gov.au 的 IP. local DNS server 會由 root name server 開始問起, 依序找到負責 .au domain 的 DNS server, 負責 .gov.au domain 的 DNS server, 負責 gbrmpa.gov.au domain 的 DNS server, 最後在負責 gbrmpa.gov.au 的 DNS server 問到 girigri.gbrmpa.gov.au 的資料, 然後傳回給 DNS client.

4. Iterative Query
A request for any information a server already has in memory for a certain domain name.

An Iterative DNS query results in a single DNS server being queried, and only getting a single response. If the DNS server has the answer, it sends it. If not it sends a "host/domain not found" error message, but the DNS server does not do any additional resolution. It does not query any other DNS servers.
 

ps:
a. Resolvers in client software such as a web browser, are not designed to hunt down answers about hosts and domains on their own. They rely on the local DNS server to do this for them. For this system of having client software relying on a DNS server to work, a recursive DNS server must be available for these clients.
b. resolver 對 local DNS server 都是 recursive query, 而 DNS server 之間的 query 多是iterative

c. 大部份的 DNS server 都可以接受 recursive 和 iterative 兩種 query 方式, 但是考量負載問題,  root name server 只接受 iterative query.

d. Because recursive lookup takes the DNS server longer and requires more memory to store records, it sometimes is more efficient to separate the DNS services for external (Internet) users from the internal (LAN) users. To do this, a recursive DNS server is provided for the internal users, and a non-recursive or 'iterative' server is provided for Internet users to enable them to resolve ONLY your domain.

 

5. DNS Caching
由前面的敘述我們可以了解由 resolver 發出一個 query 給 local DNS, 到最後 local DNS 把答案傳回來, 中間需要許多次的查詢, 為了節省這些反覆查尋的時間, DNS server 會把查到的結果暫存一陣子, 這麼一來當有其它機器發出相同詢問時, 就可以省下不少的時間.
舉例而言, 在一次詢問 www.cyut.edu.tw 的過程中, local DNS 可以得知
a. 負責 .tw 的 name server IP
b. 負責 .edu.tw 的 name server IP
d. www.cyut.edu.tw 的 IP
除了再次查詢 www.cyut.edu.tw 會變快外(client也會暫存), 查詢和 a, b 相關 domain 的資料也會變快, 因為 local DNS 不必再從 root name server 一層層問下來.

ps: 當 local DNS 記下一些資料以便加速時, 萬一真正的資料有修改時怎麼辦呢? DNS server 針對它負責的 domain 資料有一個 TTL(time to leave)參數, 用來告訴其它 DNS 在 cache 其資料時, 資料只應該 cache 多久. 超過 TTL, 那個 cache 就要視為過期無效.

 

貳. 動手安裝

一. 探索 BIND & NAMED

     BIND 介紹

BIND 是 Berkeley Internet Name Domain 的縮寫, 是目前被使用得最廣泛的 name server system. 原本 bind 的版本一直在 4.8.x, 4.9.x 左右, 後來因為功能上作大幅改進, 並且改掉一些 security hole, 版本一口氣跳到 8.1.x.。

BIND 的主程式是 /usr/sbin/named, 執行的時後會去讀取 /etc/named.conf 這個設定檔 。

    安裝BIND

當您安裝Redhat 時是以Server等級安裝系統,系統並未安裝DNS Server;若您是以Custom等級安裝系統,記得選取「Named Server」及「BIND」相關套件。目前最常使用DNS Server是 BIND8.2,Redhat 光碟已內附,您可不必上網下載,安裝BIND套件步驟如下:
   步 驟:
1. # mount /mnt/cdrom
2. # cd /mnt/cdrom/Redhat/RPMS/。
3. # rpm -Uvh bind-*。

上述的安裝步驟會幫您安裝:bind-8.2-6.i386.rpm、bind-devel-8.2-6.i386.rpm、bind-utils-8.2-6.i386.rpm等三個套件,其中bind-8.2-6.i386.rpm是安裝BIND 8.2主要程式與套件,bind-devel-8.2-6.i386.rpm是安裝BIND的發展套件,bind-utils-8.2-6.i386.rpm則是安裝nslookup等DNS查詢必備工具,頭尾兩項套件缺一不可。

ps. 是否安裝好, 可以用find搜尋看看有沒有named的執行程式(注意看file時間對不對)

安裝好BIND後,DNS Server尚未啟動,即使重新開機後也不會自動啟動,您可使用linuxconf設定Redhat Linux一開機後就自動啟動BIND,請依下列步驟設定:
  步 驟:
1. 以 root身分登入主機。
2. # linuxconf。(啟動linuxconf)
3. 按一下「Control」、「Control panel」。
4. 按一下「Control service activity」項目。
5. 設定「named」項目為啟動,再按下 [Accept] 鍵即可。

※注意:BIND DNS Server的服務名稱固定稱為named,事實上當您啟動named後,DNS Server就開始運作了。

若是要立即啟動DNS Server,可輸入如下命令:
# named & 或是
# /etc/rc.d/init.d/./named start

若是要停止DNS Server服務,則可輸入如下命令:
# /etc/rc.d/init.d/./named stop

 

     BIND的結構

安裝好DNS Server後,若要設定機器的domain name,必須撰寫DNS組態檔及domain正反解對應檔,由於所使用的DNS版本是BIND 8.2,因此以一個class c以下的網域為例,最一般化的DNS組態檔及正反解領域宣告檔必須存在四個檔案,在Redhat裡,內定Name Server 的組態檔為named.conf 固定放置在/etc目錄下,而其它領域宣告檔一般放在 /var/named目錄下,其結構為:

/etc/named.conf ;領域型態組態檔
/var/named/named.ca ;root name server 的位置儲存檔
/var/named/named.domain ;領域正解宣告檔
/var/named/named.domain.arpa ;領域反解宣告檔
 

PS. 一般需安裝catching-nameserver的套件, 才會自動產生上述檔案.
PS. 除了基本的named.conf 檔固定放在 /etc 目錄下外,其餘的宣告檔,目錄及檔名是可以更改的。

在還沒有進行領域正解及反解的設定之前﹐如果root name server 的位置儲存檔已經正確安裝好了, 那麼你的主機已經可以提供DNS的服務了﹗因為它能夠透過 root name server查詢其他 DNS﹐所以您無須再加任何設定﹐就可以利用這台主機為大家提供 Internet 的 DNS 查詢服務, 這樣的 DNS 主機﹐我們稱之為 cache only name server 。

       named.conf 設定

請您用 ntsysv 確定 named 被選擇為開機服務。

首先﹐設定一個最重要的 dns 設定檔﹐它就是 /etc/named.conf 。我將設定檔案列出來﹐然後逐部份進行解釋﹕

// generated by named-bootconf.pl

options {
        directory "/var/named";
        /*
         * If there is a firewall between you and nameservers you want
         * to talk to, you might need to uncomment the query-source
         * directive below.  Previous versions of BIND always asked
         * questions using port 53, but BIND 8.1 uses an unprivileged
         * port by default.
         */
        // query-source address * port 53;
};

註解的符號是“ // ”﹔另外﹐“ /* ”與“ */ ”之間則註解一整段文字。

每一段完整的設定都以“ ”結尾﹐請不要少了它﹗

上面的部份是在這個檔案開頭的 options 設定﹐首先用 directory 指定了 named 的資源記錄( RR - Resource Record )檔案目錄所在位置為﹕“/var/named”﹔也就是說﹐它會到這個目錄下面尋找 DNS 記錄檔案。所以﹐我們在後面部份所指定的檔案﹐就無需使用絕對路徑了﹐但它們一定要放在這個目錄下面。

接下來﹐有一段文字﹐它大致是說﹕如果您要設定的 DNS 伺服器和 client 之間是隔著火牆的話﹐要將“// query-source address * port 53;”前面的註解符號“ // ”拿掉。不過﹐這只對早期的版本有影響﹐而在 bind 8.1 之後則無需擔心這個設定。

接下來再讓我們看下一段句子﹕

//
// a caching only nameserver config
//
zone "." IN {
    type hint;
    file "named.ca";
};

透過這幾行﹐我們為 named 定義了 DNS 系統中的根區域“ . ”(root zone) 的設定﹐同時它是一個 internet ( IN ) 的區域類別( class )。這裡還指定了root zone 的伺服器種類( type ) 為“hint”(也只有這個 zone 會使用這樣的種類)。最後﹐用 file 指定這個區域記錄檔為﹕“named.ca”﹐也就是“/var/named/named.ca”檔案。

在 root zone 後面﹐您應該還會看到如下這兩段﹕

zone "localhost" IN {
    type master;
    file "localhost.zone";
    allow-update { none; };
};

zone "0.0.127.in-addr.arpa" IN {
    type master;
    file "named.local";
    allow-update { none; };

這裡是定義出關於本機名稱的 DNS 解釋﹕第一個 zone 是 localhost 的正解 zone﹐其伺服器種類是 master﹐記錄檔名稱是 localhost.zone (在 /var/named 目錄下面)﹐但這個 zone 不允許客戶主機(或伺服器)自行更新 DNS 的記錄(當然﹐client 主機必須能支援 DNS submit 功能才行)。

第二個 zone 則是本機區域的反解 zone ﹐這部份的解釋留到後面的例子中再作說明。

上面的句子﹐當您安裝好 caching-nameserver 套件之後就被建立起來的。在檔案最後﹐您或許還看到下面這段設定﹕

key "key" {
    algorithm hmac-md5;
        secret "coqJswFdBMdNAItnLOpkmGgmJtccFsoNZZciWqxlGZBMUTOUxb0geYMFRyTT";
};

這是 bind 9.x 版本的新功能﹐用來進行區域轉移或 DNS 更新所用的加密處理。暫不必理會。

 

現在﹐轉到 /var/named 目錄﹐看看裡面有些什麼﹖最起碼﹐您會看到如下三個檔案﹕

named.ca
localhost.zone
named.local

剛才在 named.conf 裡面﹐每一個 zone 所指定的 file 都出現在這裡﹗

   

named.ca

先讓我們看看 root zone 的檔案內容﹕

;       This file holds the information on root name servers needed to
;       initialize cache of Internet domain name servers
;       (e.g. reference this file in the "cache  .  "
;       configuration file of BIND domain name servers).
;
;       This file is made available by InterNIC registration services
;       under anonymous FTP as
;           file                /domain/named.root
;           on server           FTP.RS.INTERNIC.NET
;       -OR- under Gopher at    RS.INTERNIC.NET
;           under menu          InterNIC Registration Services (NSI)
;              submenu          InterNIC Registration Archives
;           file                named.root
;
;       last update:    Aug 22, 1997
;       related version of root zone:   1997082200
;
;
; formerly NS.INTERNIC.NET
;
.                        3600000  IN  NS    A.ROOT-SERVERS.NET.
A.ROOT-SERVERS.NET.      3600000      A     198.41.0.4
;
; formerly NS1.ISI.EDU
;
.                        3600000      NS    B.ROOT-SERVERS.NET.
B.ROOT-SERVERS.NET.      3600000      A     128.9.0.107
;
; formerly C.PSI.NET
;
.                        3600000      NS    C.ROOT-SERVERS.NET.
C.ROOT-SERVERS.NET.      3600000      A     192.33.4.12
;
; formerly TERP.UMD.EDU
;
.                        3600000      NS    D.ROOT-SERVERS.NET.
D.ROOT-SERVERS.NET.      3600000      A     128.8.10.90
;
; formerly NS.NASA.GOV
;
.                        3600000      NS    E.ROOT-SERVERS.NET.
E.ROOT-SERVERS.NET.      3600000      A     192.203.230.10
;
; formerly NS.ISC.ORG
;
.                        3600000      NS    F.ROOT-SERVERS.NET.
F.ROOT-SERVERS.NET.      3600000      A     192.5.5.241
;
; formerly NS.NIC.DDN.MIL
;
.                        3600000      NS    G.ROOT-SERVERS.NET.
G.ROOT-SERVERS.NET.      3600000      A     192.112.36.4
;
; formerly AOS.ARL.ARMY.MIL
;
.                        3600000      NS    H.ROOT-SERVERS.NET.
H.ROOT-SERVERS.NET.      3600000      A     128.63.2.53
;
; formerly NIC.NORDU.NET
;
.                        3600000      NS    I.ROOT-SERVERS.NET.
I.ROOT-SERVERS.NET.      3600000      A     192.36.148.17
;
; temporarily housed at NSI (InterNIC)
;
.                        3600000      NS    J.ROOT-SERVERS.NET.
J.ROOT-SERVERS.NET.      3600000      A     198.41.0.10
;
; housed in LINX, operated by RIPE NCC
;
.                        3600000      NS    K.ROOT-SERVERS.NET.
K.ROOT-SERVERS.NET.      3600000      A     193.0.14.129
;
; temporarily housed at ISI (IANA)
;
.                        3600000      NS    L.ROOT-SERVERS.NET.
L.ROOT-SERVERS.NET.      3600000      A     198.32.64.12
;
; housed in Japan, operated by WIDE
;
.                        3600000      NS    M.ROOT-SERVERS.NET.
M.ROOT-SERVERS.NET.      3600000      A     202.12.27.33
; End of File

在 /var/named 中的 RR 記錄檔裡面的註解符號﹐使用 “ ”符號。

在這個 named.ca 檔案裡﹐如果將註解行拿掉﹐您會發現一共有 13 行是以‘ . ’開頭﹐那就是所謂的 root zone 了﹗

第二欄都是‘ 3600000 ’﹐這是 TTL (Time To Live) 設定﹐也就是在 cache 中保留的時間﹐以秒為單位(所以這裡是 100 小時)。其後的‘ NS ’是“Name Server”的意思﹐是 DNS 記錄名稱之一﹐也就是負責這個記錄的 name server 是哪一台主機(這裡一共由 13 台主機共同負責 root zone 的 NS 服務)。

雖然我們這裡用 NS 指定了 name server 的主機名稱﹐但對電腦系統來說﹐這些名稱必須能解釋為 IP 位址才有用﹐所以﹐這裡分別用 13 個‘ A ’記錄﹐也就是 Address 的意思﹐解釋 [A-M].ROOT-SERVER.NET. 這些主機各自的 IP 位址所在。

問題﹕當 named 剛啟動的時候﹐在 cache 裡面一片空白﹐它怎麼知道 root zone 的 servers 在哪裡呢﹖所以﹐就必須靠這個檔案告訴 named 關於 root zone 的 servers 有哪些﹖以及在哪裡﹖

因為這個檔是以靜態的方式維護的﹐很難保證這個檔的內容永遠都正確﹐如果 root zone 的記錄發生改變了怎麼辦﹖在檔案的開頭註解那裡得知﹐可以在任何時候透過 ftp 或 gopher 取得這個檔案的最新版本。可以按如下步驟進行﹕

ftp FTP.RS.INTERNIC.NET
anonymous
your_account@your.mail.server
cd domain
get named.root
bye
cp /var/named/named.ca /var/named/named.ca.bak
cat named.root > /var/named/named.ca

 

localhost.zone

第二個 zone 的記錄檔是 localhost.zone﹐從 named.conf 中您應該知道它是 zone "localhost" 的記錄檔﹐內容如下

$TTL    86400
$ORIGIN localhost.
@	1D IN SOA       @ root (
		42              ; serial (d. adams)
		3H              ; refresh
		15M             ; retry
		1W              ; expiry
		1D )            ; minimum

	1D IN NS        @
	1D IN A         127.0.0.1

第一行是一個 TTL 設定﹐目前是定義這個記錄檔裡面的各項記錄的預設 TTL 值為 86400 秒(剛好是一天)。您的記錄檔或許沒有這行﹐可以自己補上﹐否則﹐在啟動 named 的時候會碰到一些警告﹔在記錄檔中宣告的所有資源記錄(RR - Resource Record)﹐都一定有一個 TTL 設定﹐如果沒有﹐則使用這裡預設的值。

第二行是一個 ORIGIN 設定﹐說明下面的記錄源出何處(這裡是源出 localhost. 的記錄)。請您加倍留意最後的一個小數點“ .”﹐少了它或多了它﹐記錄名稱完全不一樣﹗在 DNS 記錄中﹐我們稱這樣以小數點結尾的名稱為“ 全域名稱 ”即 FQDN ( Fully Qualified Domain Name ) 。如果缺少了這個點會怎樣呢﹖就會將所屬的 ORIGIN 附加在記錄名稱後面﹔而這 ORIGIN 就是上一個 $ORIGIN 宣告之後的名稱﹐如果在前面找不到 $ORIGIN 宣告﹐那就以 /etc/named.conf 中定義的 zone 名稱為基準。以目前的例子來說﹐如果沒有這個小數點的話﹐“localhost”會變成“localhost.localhost”﹔但如果有小數點的話“localhost.”就只能是“localhost.”。所以﹐這個小點“.”非常重要﹐在以後設定中一定要非常留神﹗(這也初學者最常犯的錯誤之一)

第三行﹐是一個 SOA 記錄的設定﹐在這裡我們看到一個特殊字符“ @ ”﹐它就是 ORIGIN 的意思﹐也就是剛才所定義的 $ORIGIN localhost. 內容﹐可以寫成 localhost. 也可以用 @ 來代替。假如這個檔前面沒有定義 $ORIGIN 的話﹐那這個 @ 的值就以 named.conf 裡的 zone 為準。

在 @ 之後﹐是 TTL 的設定﹐這裡是 1D﹐也就是一天的意思﹐如果您喜歡﹐可以用 86400 (秒) 來設定﹐如果這裡的 TTL 沒有設定﹐則參考前面的 $TTL 值﹐如果前面沒有定義 $TTL﹐那就參考其後介紹的 minium ttl 設定。

可以為每一個 RR 記錄設定其自己的 TTL ﹐只要將數字寫在第二個欄位﹐也就是‘IN’前面就可以了。

在 TTL 之後是一個 IN﹐定義出目前的記錄類型是屬於 internet class 的 (目前的 DNS 還有其它 class 嗎﹖)。

在 IN 之後就是這行 RR 的記錄類別名稱﹐這裡是 SOA ﹐也就是“Start Of Authority”的意思﹐表示目前區域的授權記錄開始。每一個記錄檔只能有一個 SOA ﹐不得重複﹐而且必須是所負責的 zone 中第一個“記錄”。

緊接 SOA 後面﹐指定了這個區域的授權主機和管理者的信箱﹐這裡分別是“ @ ”和“ root ”﹐也就是 localhost. 主機和 root 信箱。這裡要注意的是﹕SOA 的主機名稱必須能夠在 DNS 系統中找到一個 A 記錄 (以後會提到)﹔另外﹐我們平時使用的信箱通常是“user@host”這樣的格式﹐但因為“@”在 DNS 記錄中是個保留字﹐所以在 SOA 中就用“.”來代替了“ @ ”。目前這個信箱是 root. 沒有 指定主機位址, 也就是本機﹐可以寫成 “root.localhost.”但不能寫成“root@localhost.”。

接下來的 SOA 設定﹐是被括在“( )”之間的 5 組數字﹐主要作為和 slave 伺服器同步 DNS 資料所使用的數據﹕

 

以上的數字都是以秒為單位﹐但您也可以用 H(小時)、D(天)、W(星期)來做單位﹐如﹕3H 和 259200 是一樣的。無論您用什麼單位來設定﹐都要遵守下面的規則﹕

expire >= refresh + retry
expire >= 10 * retry

Tips﹕請注意﹕SOA 記錄中這對 “ ( ) ”符號之第一個 “ (”括號一定要和 SOA 寫在同一行﹐而不能用 Enter 斷行到下一行去(有時候您在書本的範例中看到這個符號排在下一行去了﹐那是因為版面的關係而已)﹐而且其左邊最好有一個空白鍵或 tab 建。而最後一個 “ )”括號也不能寫在註解符號 “ ﹔”的右邊。

 

定 DNS 的 RR 記錄檔﹐其格式要求非常嚴格。

a. 如果句子不是以空白鍵、Tab 鍵、 或註解符號 ( ; )開頭﹐也不在 SOA 的 “ ( ) ”之內﹐ 則表示要定義一個“新記錄項 (Entry) ”﹔

b. 如果句子是以空白鍵或 tab 鍵開始的話﹐其設定被視為上一個“記錄項”的內容。所以﹐如果您要為“同一個記錄項”定義多個記錄設定﹐而不想重複打字﹐在接著它的後面幾行用空白或 Tab 來縮排就可以了。

例如: 上面例子中最後這兩行還是關於 localhost. 的設定﹐因為上一個“資料項”為 “ @ ”﹐也就是 localhost. 。當然﹐這兩行句子也可以改寫如下﹕

;; 修改前﹕
	1D IN NS        @
	1D IN A         127.0.0.1

;; 修改後﹕
@	1D IN NS        @
@	1D IN A         127.0.0.1

;; 或﹕
localhost.	1D IN NS        localhost.
localhost.	1D IN A         127.0.0.1

這兩行的意思是說﹕負責 localhost. 這個記錄的 name server ( NS ) 是 localhost. 這台機器﹔而 localhost. 的 IP Address ( A ) 是 127.0.0.1 。DNS 裡面的 A 記錄應該是最常見的記錄類型之一﹐如果在 IPv6 版本中﹐位址記錄名稱則改為 AAAA 。

 

named.local

最後﹐讓我們檢查 named.local 檔案。如果您還沒忘記 /etc/named.conf 的內容的話﹐應知道這個檔案是 zone "0.0.127.in-addr.arpa" 的‘反解’記錄檔﹐它的內容也很簡單﹕

$TTL    86400
@       IN      SOA     localhost. root.localhost.  (
                                      1997022700 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
              IN      NS      localhost.

1       IN      PTR     localhost.

最後一行我們看到一個“ PTR ”記錄﹐它是“Pointer”的意思。 PTR 通常用於反記錄當中﹐將 IP 指向主機名稱(剛好和 A 記錄相反)。或許您會問﹕為什麼這裡是 1 而不是 127.0.0.1 ?

我們知道 127.0.0.1 所對應的主機名稱就是 localhost ﹐因為這裡是反向查詢﹐所以 IP 順序是掉過來寫的﹐於是這個反查詢 IP 就是﹕“ 1.0.0.127.in-addr.arpa. ”﹐由於這裡的 ORIGIN ( @ ) 是“ 0.0.127.in-addr.arpa." ”﹐因為在記錄檔中﹐如果名稱不帶小數點﹐則被補上 $ORIGIN 或 zone 的名稱﹐所以這個 “ 1 ”就成了 1.0.0.127.in-addr.arpa. ”。同樣道理﹐後面的“ localhost. ”如果漏了最後的小點的話﹐則會成為“ localhost.0.0.127.in-addr.arpa. ”﹐這顯然是不對的。假如您喜歡﹐可以將這行句子修改成為下面的樣子﹕

﹔﹔修改前﹕
1       IN      PTR     localhost.

﹔﹔修改後﹕
1.0.0.127.in-addr.arpa.       IN      PTR     localhost.

 

二. 設定 NAMED

當您對 /etc/named.conf 檔案和 /var/named 目錄的設定有初步了解之後﹐讓我們用一個實際例子來看看如何設定自己的 domain name 服務吧。下列表格是Domain name和IP address的對應﹕

Domain 名稱 IP 位址
rh71.siyongc.domain 192.168.100.23
acer.siyongc.domain 192.168.100.20
mdk.siyongc.domain 192.168.100.24
emilie.siyongc.domain 192.168.100.11
rh71.dmz.domain 10.0.1.131
lp64.dmz.domain 10.0.1.130

從上面的資料中﹐我們不難發現有兩個正解 zone 和兩個反解 zone 需要設定﹐分別是﹕

區域名稱 記錄項名稱
siyongc.domain emilie、acer、rh71、mdk
dmz.domain lp64、rh71
100.168.192.in-addr.arpa 11、20、23、24
1.0.10.in-addr.arpa 130、131

因為這些 IP 和 domain 都在內部網路使用﹐所以我們省卻了註冊這關﹐同時也不必擔心授權的問題。但這些資訊也只能在內部網路使用。

一般來說﹐我會先設定“反查詢區域(revers zone)”﹐當然﹐這是個人習慣而已。所以﹐我首先在 /etc/named.conf 上面補上兩個反解 zone 的設定

zone "100.168.192.in-addr.arpa" IN {	// 定義反解區域名稱
        type master;		// 定義伺服器類型
        file "192.168.100.rev";	// 指定記錄檔名稱
};				// 結束區域設定

zone "1.0.10.in-addr.arpa" IN {
        type master;	
        file "10.0.1.rev";
};

 

Tips﹕假如您是 hinet 的固定制 ADSL 用戶﹐可以到 hinet 的網站填寫表格﹐請他們幫忙設定反解﹕

http://hidomain.hinet.net/rever.html

 

再一次碰到反解區域的識別標誌﹕“ .in-addr.arpa ”﹐反解查詢是先從 root 開始(正解也是一樣)﹐然後到 arpa 、到 in-addr 、到第一組 IP 、到第二組 IP 、...... 這樣查詢下來的。所以﹐在設定反區域的時候﹐您一定要將您的 net ID 部份反過來寫﹐例如﹕我的網路為 192.168.100.0/24﹐它的反查詢區域名則是﹕“100.168.192.in-addr.arpa”﹔假如我將 netmask 改為 16 bit ﹐即變成 192.168.0.0/16﹐它的反解區域名就會變成﹕“168.192.in-addr.arpa”。

同時﹐我將這些 zone 都設定為“主 DNS 伺服器”(即﹕master﹐也有人稱之為 primary dns )。

在每個 zone 的最後部份﹐我分別指定了它們各自的記錄檔名稱。它們都存放在 /var/named 這個目錄下面(也就是前面 options 指定的 directory )。檔案的名稱隨您喜歡。

完成上面的設定之後﹐我們就可以到 /var/named 目錄去建立相應的記錄檔案了。根據第一個 zone 的 file 設定﹐我要建立一個 /var/named/192.168.100.rev 檔案﹐其內容如下﹕

$TTL    86400
@  IN  SOA rh71.siyongc.domain. root.rh71.siyongc.domain. (
                                      2001111601 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
@   IN  NS  rh71.siyongc.domain.
@   IN  NS  lp64.dmz.domain.

11  IN  PTR emilie.siyongc.domain.
20  IN  PTR acer.siyongc.domain.
23  IN  PTR rh71.siyongc.domain.
24  IN  PTR mdk.siyongc.domain.

 

而另外一個反解設定檔是 /var/named/10.0.1.rev ﹐我們依樣畫葫蘆就行了﹕

$TTL    86400
@  IN  SOA rh71.siyongc.domain. root.rh71.siyongc.domain. (
                                      2001111601 ; Serial
                                      28800      ; Refresh
                                      14400      ; Retry
                                      3600000    ; Expire
                                      86400 )    ; Minimum
@    IN  NS  rh71.siyongc.domain.
@    IN  NS  lp64.dmz.domain.

130  IN  PTR lp64.dmz.domain.
131  IN  PTR rh71.dmz.domain.

 

我們繼續正解區域的設定。同樣的﹐先在 /etc/named.conf 裡面加上兩個 zone﹕

zone "siyongc.domain" IN {
        type master;
        file "siyongc.domain";
};

zone "dmz.domain" IN {
        type master;
        file "dmz.domain";
};

 

完成後﹐再建立 /var/named/siyongc.domain 這個檔案﹕

$TTL    86400
$ORIGIN siyongc.domain.
@ IN  SOA  rh71.siyongc.domain. root.rh71.siyongc.domain. (
	2001111601 28800 14400 3600000 86400 )
        IN  NS     rh71.siyongc.domain.
        IN  NS     lp64.dmz.domain.
        IN  MX  10 rh71.siyongc.domain.
        IN  MX  20 lp64.dmz.domain.

;; -- default address
@       IN  A      192.168.100.23

;; -- linux servers --
rh71    IN  A      192.168.100.23
        IN  MX  0  rh71.siyongc.domain.
        IN  MX  10 lp64.dmz.domain.
        IN  HINFO  "Petium II 266""Redhat 7.1"
        IN  TXT    "The internet gateway."

mdk     IN  A      192.168.100.24
        IN  MX  0  mdk.siyongc.domain.
        IN  MX  10 rh71.siyongc.domain.
        IN  HINFO  "Petium II 266 dell""Mandrak 8.0"

;; -- Windows desktops --
acer    IN  A      192.168.100.20
        IN  MX  0  mdk.siyongc.domain.
        IN  HINFO  "Petium III 800 acer""Windows ME"

emilie  IN  A      192.168.100.11
        IN  MX  0  mdk.siyongc.domain.
        IN  HINFO  "Petium II 300""Windows 98"

;; -- cnames --
gw      IN  CNAME  rh71
www     IN  CNAME  rh71
ftp     IN  CNAME  rh71
mail    IN  CNAME  rh71

這裡﹐我們在正解記錄檔裡面看到幾個新的記錄類別﹕

因為我這個區域的記錄分別由兩台主機負責﹐所以我這裡指定了兩個 NS 記錄。

您可以只寫“ rh71 ”而不帶小數點結尾﹐就會變成“rh71.siyongc.domain.”﹐這個名稱實際就是我所要的。不過﹐建議您在設定 NS 的時候還是儘量使用 FQDN 。

 

      MX 記錄 :

MX 是‘Mail eXchange’的意思﹐它指定了負責該記錄項(可以為 domain 也可以是 host )的郵件伺服器名稱(最好使用 FQDN )﹐而且該名稱必須是一個 A 記錄(不建議使用 CNAME )。

為每一個區域建立起 MX 記錄﹐利用 DNS 查詢得到的郵件伺服器名稱﹐當郵件伺服器要和對方的區域進行郵件傳遞的時候﹐就可以通過 MX 記錄得到對方的郵件伺服器名稱。以後﹐就算對方更換名稱﹐將 DNS 記錄改改就可以﹐完全無需知會其它郵件主機﹔而外面的郵件伺服器也根本無需認知到這個改變。

另外﹐使用 MX 還有一個功能﹕您可以用多個 MX 同時指定好幾台郵件伺服器名稱﹐從而提供備援或平行處理服務。在我這個例子中﹐我就分別為‘siyongc.domain’這個區域指定了兩個 MX 記錄﹕‘rh71.siyongc.domain.’和‘lp64.dmz.domain.’。但您有沒有發現它們前面都有一個數字﹖

數字的作用: 當外面的郵件伺服器通過 DNS 查詢到我們的郵件伺服器﹐如果發現超過一台主機負責郵件交換的話﹐數值越低的就越先被查詢。但有時候該主機沒有回應呢﹖那麼就由下一個數值的主機負責了。

Tips﹕我們通常用‘10’、‘20’、‘30’.... 這樣的偏好值( preference ) 來分配 MX 記錄﹐但只要您喜歡﹐用‘1’、‘2’、‘3’... 這樣的順序一樣可以。不過﹐建議您還是使用慣例。

您還發現這裡為所有主機指定了 MX 記錄﹐有些直接指向自己(如 rh71、mdk 等)﹐而有些則指向別的機器(如 lp64、acer 等)。在 Linux 機器上面﹐各主機本身就具備郵件交換功能﹐而 Windows 則除非額外加裝﹐否則本身是沒有郵件交換功能的。這裡的設定是﹐從外面通過 DNS 查詢而寄往那些主機的郵件﹐都會轉到 MX 上面指定的郵件伺服器。

 

TXT和HINFO記錄

另外﹐在這個檔裡面﹐您或許還發現‘ TXT ’這樣的記錄類別﹐它是‘Text Information’的意思﹐它實際上不牽涉任何設定﹐只記錄一些環境說明而已﹔這和‘ HINFO(Host Information) ’差不多﹐但 HINFO 一定要有兩項記錄(分別用引號分開)﹐其中第一項是關於 CPU 的訊息﹐第二項則是作業系統。

       CNAME記錄

CNAME 是一個別名記錄( Canonical Name )。當 DNS 系統在查詢 CNAME 左面的名稱的時候﹐都會轉向 CNAME 右面的名稱再進行查詢﹐一直追蹤到最後的 PTR 或 A 名稱﹐成功查詢後才會做出回應﹐否則失敗。例如﹐在正解查詢中﹐一個 IP 通常(當然也有例外)﹐只會對應一個 A 記錄﹐但我們可以使用 CNAME 在 A 名稱之上賦予該 IP 更多的名稱。也就是說﹕所有關於‘www.siyongc.domain’、‘ftp.siyongc.domain’、‘mail.siyongc.domain’這些名稱的查詢﹐實際上都會再查詢一次‘rh71.siyongc.domain.’這個記錄﹐直到找到它的 IP 位址為止。有些朋友或許會設定多層的 CNAME 查詢﹐例如﹕

C    CNAME    B
B    CNAME    A

這樣的話﹐會一層一層的逐級 CNAME 下去... 但是﹐這很浪費 DNS 資源﹗因為每一個 CNAME 都一定會產生另外一個查詢動作﹐如果層級越多﹐那就產生越多的重複查詢。所以﹐DNS 管理員都會儘量的減少查詢次數的發生﹐他會將 CNAME 變成這樣子﹕

C    CNAME    A
B    CNAME    A

還有另外一個 /var/named/dmz.domain 檔案也不要忘記了﹕

$TTL    86400
$ORIGIN dmz.domain.
@ IN  SOA  rh71.siyongc.domain. root.rh71.siyongc.domain. (
	2001111601 28800 14400 3600000 86400 )
        IN  NS  rh71.siyongc.domain.
        IN  NS  lp64.dmz.domain.
        IN  MX  10 rh71.dmz.domain.

;; -- linux servers --
rh71    IN  A   10.0.1.131
        IN  MX  0 rh71.dmz.domain.
        IN  HINFO "Petium II 266""Redhat 7.1"
        IN  TXT   "The internet gateway."

lp64   IN  A   10.0.1.130
        IN  MX   0 rh71.dmz.domain.
        IN  HINFO "Pentium 90""Linpus 6.4"

;; -- cnames --
gw      IN  CNAME   lp64
www     IN  CNAME   lp64
ftp     IN  CNAME   lp64
mail    IN  CNAME   lp64

我們的 DNS 就已經設定好了﹐包括反解和正解

 

三. 重新啟動 named

當您以為所有設定檔都設定好之後﹐我們還要重新啟動 named ﹐否則﹐您查詢出來的還是舊資料。使用如下命令來重新啟動DNS 服務﹕

service named restart

 

在重新啟動 named 服務之後﹐請檢查一個檔案﹐就是 /var/log/messages 。因為當您執行 service named restart 之後您看到的都是綠色的 OK ﹐但事實上是否真的 OK 呢﹖除非您在 log 檔中沒發現錯誤信息。所以﹐我也強烈建議您每次重新啟動 named 之後﹐一定要做如下動作﹕

vi /var/log/messages

 

然後按“G”鍵(大寫)跳到檔案末尾部份(事實上﹐您也可以用 tail 命令)。您或許會看到如下這樣的記錄﹕

Nov 16 14:54:10 rh71 named[2211]: starting BIND 9.1.0 -u named
Nov 16 14:54:10 rh71 named[2211]: using 1 CPU
Nov 16 14:54:10 rh71 named: named startup succeeded
Nov 16 14:54:10 rh71 named[2215]: loading configuration from '/etc/named.conf'
Nov 16 14:54:10 rh71 named[2215]: the default for the 'auth-nxdomain' option is now 'no'
Nov 16 14:54:10 rh71 named[2215]: no IPv6 interfaces found
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface lo, 127.0.0.1#53
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface eth0, 192.168.100.23#53
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface eth1, 10.0.1.1#53
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface eth2, 10.0.1.131#53
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface vmnet1, 172.16.233.1#53
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface vmnet8, 192.168.183.1#53
Nov 16 14:54:10 rh71 named[2215]: listening on IPv4 interface ppp0, 211.74.244.213#53
Nov 16 14:54:10 rh71 named[2215]: running

上面雖然有 'auth-nxdomain' 和 IPV6 的提示﹐但那是正常的(除非您有設定相關的功能)。如果沒有其它錯誤信息的話﹐那真要恭喜您了﹗

 

但有時候您或許會看到有其他錯誤信息的﹐例如﹕

Nov 16 15:01:49 rh71 named[2287]: loading configuration from '/etc/named.conf'
Nov 16 15:01:49 rh71 named[2287]: /etc/named.conf:41: parse error near zone
Nov 16 15:01:49 rh71 named[2287]: loading configuration: failure
Nov 16 15:01:49 rh71 named[2287]: exiting (due to fatal error)

這個錯誤信息明顯指出了是 /etc/named.conf 的問題﹐而且很可能在 41 行附近。根據經驗﹐這通常是您漏了 “ ﹔”符號的原因而已。

 

如果碰到如下信息﹐那是沒有為所有 RR 記錄項設定 TTL 而已﹐您可以為每一個記錄項補上 TTL (在 IN 前面)﹐也可以在記錄檔的前面用 $TTL 來設定﹕

Nov 16 15:04:47 rh71 named[2395]: master.c:1172: unexpected error:
Nov 16 15:04:47 rh71 named[2395]: dns_master_load: siyongc:3: no TTL specified. 
THIS ZONE WILL NO LONGER WORK IN FUTURE VERSIONS. Add a TTL.
Nov 16 15:04:47 rh71 named[2395]: dns_master_load: siyongc:5: using 
RFC 1035 TTL semantics

 

如果碰到下面這樣的信息﹐那多是因為您打字錯誤的關係﹐輸入了 named 不認識的記錄類別名稱(例如漏了記錄名稱或打錯了)﹕

Nov 16 15:07:44 rh71 named[2422]: dns_master_load: siyongc:2: unknown RR 
type 'siyongc.domain.'
Nov 16 15:07:44 rh71 named[2422]: dns_zone_load: zone siyongc.domain/IN: loading 
master file siyongc: unknown class/type

 

如下的問題﹐那可能是您沒有定義 SOA 記錄﹐或設定有錯誤﹕

Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: could 
not find NS and/or SOA records
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: has 
0 SOA records
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: no 
NS records

 

下面的問題可能是 SOA 記錄多輸入了一組數字﹐或少輸入了一組數字﹐或數字格式有錯誤﹕

Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: could not 
find NS and/or SOA records
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: has 
0 SOA records
Nov 16 15:14:33 rh71 named[2506]: dns_zone_load: zone siyongc.domain/IN: no 
NS records

Nov 16 15:18:24 rh71 named[2562]: dns_rdata_fromtext: siyongc:4: near eol: unexpected 
end of input
Nov 16 15:18:24 rh71 named[2562]: dns_zone_load: zone siyongc.domain/IN: loading 
master file siyongc: unexpected end of input

Nov 16 15:19:34 rh71 named[2640]: dns_rdata_fromtext: 
siyongc:4: near '14B400': 
syntax error
Nov 16 15:19:34 rh71 named[2640]: dns_zone_load: zone 
siyongc.domain/IN: loading 
master file siyongc: syntax error

 

以下問題可能是 SOA 的 “ ( ) ”符號有問題﹐要麼是“ ( ” 給斷到下一行了﹐要麼是“ ) ”給註解掉了﹕

Nov 16 15:22:08 rh71 named[2669]: dns_rdata_fromtext: siyongc:3: near eol: unexpected 
end of input
Nov 16 15:22:08 rh71 named[2669]: dns_zone_load: zone siyongc.domain/IN: loading 
master file siyongc: unexpected end of input

Nov 16 15:22:52 rh71 named[2696]: dns_rdata_fromtext: siyongc:4: 
near 'IN': extra input text
Nov 16 15:22:52 rh71 named[2696]: dns_zone_load: zone siyongc.domain/IN: 
loading master file siyongc: extra input text

 

以下是您沒有設定 NS 記錄或 NS 記錄設定有錯誤﹕

Nov 16 15:25:30 rh71 named[2801]: dns_zone_load: zone siyongc.domain/IN: no NS records

 

下面的錯誤可能是您設定了一個記錄項超出了當前 ORIGIN 的範圍﹐例如 localhost. 或 siyongc. (也就是錯誤使用 FQDN )﹔或是錯誤的使用了 $ORIGIN 設定﹔或是在 named.conf 中有多個 zone 在分享同一份記錄檔﹕

Nov 16 15:31:20 rh71 named[2920]: dns_master_load: siyongc:16: 
ignoring out-of-zone data

 

下面的錯誤﹐有可能您在設定多個 $ORIGIN 並同時嘗試設定多個 SOA 時出現的錯誤﹕

Nov 16 15:28:31 rh71 named[2855]: dns_master_load: siyongc:26: 
not at top of zone

 

許多問題都可以在 /var/log/messages 中找到﹐當您發現這些錯誤信息之後﹐看看是關於什麼記錄的﹐留心一下檔案內容﹐就比較容易找到錯誤的原因了。

 

四. 設定 DNS Client

不知道您記不記得設定 linux 的 dns client 呢﹖在之前就設定過了﹐也就是修改 /etc/resolv.conf 這個檔案﹐將您剛設定好的 DNS 主機 IP 放在檔案的前排位置﹐如﹕

nameserver	192.168.100.23
nameserver	168.95.1.1
nameserver	139.175.10.20
domain	siyongc.domain
search	siyongc.domain dmz.domain test.com

假如您的 client 和 server 在同一台機器上﹐那可以將第一個 name server 設定為 0.0.0.0 或 127.0.0.1 。

要是您使用 Windows ﹐但不是透過 DHCP 來指定 DNS 的話﹐那您或許需要手工設定了﹕控制台 --> 網路 --> TCP/IP (-> 網路卡) --> 內容 --> DNS 組態 ﹕

 

請注意﹕如果您修改了這裡的設定﹐就算您的 Windows 是透過 DHCP 取得 IP 設定的話﹐也會以這裡的設定為準。如果您想使用 DHCP 的設定﹐那就選擇“關閉 DNS”吧。

五. 測試 DNS

要測試設定是否生效﹐直接 ping 一下您所預期的 dns 名稱就知道結果了。

不過﹐ping 畢竟很有限﹐例如﹕您不能查詢 MX 和 NS 等記錄。實作上﹐我們最最常使用的 DNS 查詢工具是 nslookup 命令。然而﹐nslookup 似乎在以後的版本中不再維護了﹐取而代之的﹐就是 dig 命令﹐學習一下如何用 dig 來查詢和測試 DNS 服務。

基本上﹐dig 命令的語法如下﹕

dig [@server] domain [<query-type>] [<query-class>] [+<query-option>]
         [-<dig-option>] [%comment]

要 man dig 才知道怎麼使用。例如﹕

# dig siyongc.domain mx

; <<>> DiG 9.1.0 <<>> siyongc.domain mx
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 8198
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 2, ADDITIONAL: 2

;; QUESTION SECTION:
;siyongc.domain.                        IN      MX

;; ANSWER SECTION:
siyongc.domain.         86400   IN      MX      20 lp64.dmz.domain.
siyongc.domain.         86400   IN      MX      10 rh71.siyongc.domain.

;; AUTHORITY SECTION:
siyongc.domain.         86400   IN      NS      lp64.dmz.domain.
siyongc.domain.         86400   IN      NS      rh71.siyongc.domain.

;; ADDITIONAL SECTION:
rh71.siyongc.domain.    86400   IN      A       192.168.100.23
lp64.dmz.domain.        86400   IN      A       10.0.1.130

;; Query time: 8 msec
;; SERVER: 192.168.100.23#53(192.168.100.23)
;; WHEN: Fri Nov 16 21:13:18 2001
;; MSG SIZE  rcvd: 138

上面是的命令是使用預設的 name server 來查詢 siyongc.domain 的 mx 記錄。當然﹐您也可以用 @ 來指定用某一台 name server 來查詢其它的資訊。例如﹐我要用 hinet 的 dns 來查詢負責 com.tw 的 NS 有哪些﹕

# dig @168.95.1.1 com.tw ns

; <<>> DiG 9.1.0 <<>> @168.95.1.1 com.tw ns
;; global options:  printcmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 33339
;; flags: qr aa rd ra; QUERY: 1, ANSWER: 3, AUTHORITY: 0, ADDITIONAL: 4

;; QUESTION SECTION:
;com.tw.                                IN      NS

;; ANSWER SECTION:
com.tw.                 518400  IN      NS      b.twnic.net.tw.
com.tw.                 518400  IN      NS      c.twnic.net.tw.
com.tw.                 518400  IN      NS      a.twnic.net.tw.

;; ADDITIONAL SECTION:
b.twnic.net.tw.         159497  IN      A       192.72.81.200
c.twnic.net.tw.         159497  IN      A       168.95.192.10
a.twnic.net.tw.         159497  IN      A       163.28.1.2
a.twnic.net.tw.         159497  IN      A       140.111.1.2

;; Query time: 167 msec
;; SERVER: 168.95.1.1#53(168.95.1.1)
;; WHEN: Fri Nov 16 21:17:46 2001
;; MSG SIZE  rcvd: 146

 

除了用 nslookup 和 dig 之外﹐如果您只想簡單的查詢 dns 資訊的話﹐可以用 host 命令。例如﹕

 

# host -t any siyongc.domain 0.0.0.0
Using domain server:
Name: 0.0.0.0
Address: 0.0.0.0#53
Aliases:

siyongc.domain. SOA rh71.siyongc.domain. root.rh71.siyongc.domain. 2001111601 28
800 14400 3600000 86400
siyongc.domain. name server lp64.dmz.domain.
siyongc.domain. name server rh71.siyongc.domain.
siyongc.domain. mail is handled by 10 rh71.siyongc.domain.
siyongc.domain. mail is handled by 20 lp64.dmz.domain.
siyongc.domain. has address 192.168.100.23

上面的命令就是用本機 name server 來查詢 siyongc.domain 的 any 資訊。至於 host 命令的格式如下﹕

host [-aCdlnrTwv] [-c class] [-N ndots] [-R number] [-t type] [-W wait]
          name [server]

您可以發現﹕透過 nslookup 、 dig 、與 host 命令﹐事實上可以查詢到許多 dns 上面的設定資訊。所以﹐如果您的 DNS 是對外提供服務的話﹐請儘量控制 DNS 資訊量﹐如果覺得沒必要對外提供的﹐那就拿掉它。

六. 註冊 domain

到此為止﹐您已經能夠在單一的 dns 上面設定一個或多個 domain 的正解和反解服務了。這時候﹐您或許早已迫不及待想註冊一個屬於自己的 domain 來玩玩看﹖

現在的 domain 註冊那麼方便和便宜﹐現在註冊一個 .com 或 .org 的網站﹐一年都不用 $10 塊美金﹗實在是便宜﹐可以請任何一家網路公司代您申請 domain ﹔要不然呢﹐也可以直接到網路上完成自己的 domain 註冊。

要註冊自己的 domain 之前﹐有些條件您還是要準備好的﹕

 

當您這些條件都符號之後﹐可以連線到網路上的著名 domain 服務網站﹐例如﹕

http://www.networksolutions.com
http://www.dotster.com
http://www.godaddy.com
http://www.twnic.net

最後一個網站是負責台灣的 domain 註冊的機構﹐您可以到那裡註冊所有以 tw 結尾的 domain﹐除了 twnic 之外﹐很多 ISP (例如 seednet )也有提供 tw domain 的註冊服務。

填寫的資料主要就是domain名稱和 ns 主機(name server)要指向哪裡。

另外﹐還有一個概念或許是許多 DNS 新手容易搞混亂的﹕我們這裡所說的 domain 註冊﹐在整個 DNS 系統中﹐僅屬於“正解”方面的註冊和授權而已﹔這和“反解”的授權毫不相關。而反解的授權﹐因為是跟據 IP 授權的﹐所以必須透過您的 IP 發放機構進行另外的申請。請您一定要區分這兩種授權模式。

 

七. 設定 master / slave

在前面您已經知道如何在單一的主機上面進行 DNS 設定了﹐那麼﹐當有兩台主機需要為同一個 domain 提供 DNS 服務的時候又如何設定呢﹖

這就是 master 和 slave DNS 的設定了。透過 master 和 slave 的架構﹐您日後要進行資料變更的時候﹐只需在 master 上面維護就好﹐然後 slave 會定期的自動過來將更新資料同步回去。

slave 會在 refresh 時間到達的時候﹐就嘗試和 master 進行資料同步的動作﹐這在 DNS 系統裡面有一個專門術語﹐叫做“zone transfer”(區域轉移)﹐相關的專有名詞則是 AXFR 查詢﹕

  1. 當 slave 需要進行 zone transfer 之前﹐它首先查詢 master 的 SOA 記錄之 serial 數值﹔
  2. 如果發現數值比 slave 上的 serial 要大﹐就送出 AXFR 查詢﹔
  3. 如果 master 允許 slave 的 zone transfer ﹐那就回應 AXFR 的查詢結果﹔
  4. 然後 slave 根據查詢結果更新自己的記錄檔。

從上面的流程來看﹐您每次修改了 master﹐一定要將增加 serial 數值。雖然﹐您可以依序的增加數值﹐但如果您的 Serial 號碼是依照“日期 + 修改次數”格式的話﹐那麼您只要修改日期部份﹐就肯定可以獲得一個更大的數值﹔假如您的修改是在同一天發生的﹐那您可以修改最右邊的兩位數字。

要設定 slave DNS 非常簡單﹐您只需在 slave 主機上面的 /etc/named.conf 增加這幾行就可以了﹕

zone "siyongc.domain" IN { 
	type slave;
	masters { 192.168.100.23; };	// 請不要漏了 masters 後面的 s ﹗
	file "slave.siyongc.domain";
};

 

 我們假設上面的設定在 10.0.1.130 ( lp64 ) 上面進行﹐而 master 則是 192.168.10.23 ( rh71 )。您無需擔心如何建立 slave 的記錄檔﹐named 會自動幫您搞定﹗您只需確定 /var/named 這個目錄能夠被 named 寫入就行了。如果您不確定﹐那只需將目錄的 owner 改一改就行了﹕

chown -R named.named /var/named

 

每次當您修改了 master 上面的設定並重新啟動 named 服務的時候﹐master 就會主動向資源記錄當中的所有 NS 主機送出 NOTIFY 信號。當 slave(s) 收到來自 master 的 NOTIFY 之後﹐會回復一個確認給 master ﹔然後根據 /etc/named.conf 檔案中的設定﹐嘗試向所定義的 masters 位址進行 zone transfer (是否更新資料﹐還必須以 Serial 為依據)﹐就好像 refresh 到達了一樣。

 

除了上述的備援需求外﹐在其它情形也有可能需要 master / slave 的架構。比方說﹐您有一個很大型的網路﹐如果所有主機都集中向 master 進行 DNS 查詢﹐那勢必會增加 master 的工作負荷、而降低其效能。這時﹐您最好設定多台 slave 放置在不同的地點來分擔 master 的工作﹐同時也能提供備援服務。

 

八. 設定 forwarder

我們除了能夠用 slave 來分擔 master 工作、減少網路流量之外﹐還可以透過另外一種 DNS 機制來減低網路流量的﹐那就是 forwarder 設定了。

所謂的 forwarder ﹐就是當某一台 NS 主機遇到非本機負責的 zone  之查詢請求的時候﹐將不直接向 root zone 查詢而把請求轉交給指定的 forwarder (一台或多台) 主機代為查詢。

如果 NS 上面指定了 forwarder﹐那這個 NS 發現 cache 沒有記錄的話﹐將不向 root 查詢﹐而是將自己扮成一個 client﹐向 forwarder 送出同樣的請求﹐然後等待查詢結果﹔而逐級往下查詢的動作﹐則交由 forwarder 負責﹐NS 自己就輕鬆多了。但無論這個結果是自己直接查詢得來的﹐還是 forwarder 送回來的﹐NS 都會保存一份資料在 cache 中。這樣﹐其後的相同查詢就快多了﹐這對於 NS 所服務的 client 而言更是有效率得多。

forwarder 在我們的實際應用中也很常見﹐例如﹐我們只要將 forwarder 設定為 ISP 的 DNS ﹐那麼﹐我們的 NS 就無需直接向 root 查詢了﹔又因為 ISP 上的 DNS 也有 cache 的關係﹐所以我們的 NS 所獲得的查詢結果﹐也比直接向 root 查詢來得要快。

如果您打算使用 forwarder 的話﹐您可以在 /etc/named 的 options { } 裡面加入這樣的句子

	forward first;
	forwarders {	// 別漏了最後的 s ﹗
		139.175.10.20;
		168.95.1.1;
	};

然而﹐上面的設定由於是在 options 裡面設定的緣故﹐這樣會讓所有非本機的查詢都轉向 forwarder 。假如您不想這樣做﹐而只是針對個別的 zone 設定 forwarder 的話﹐那您也可以這樣設定﹕

zone "siyongc.domain" IN {
	type forward;
	forwarders { 192.168.100.23; 10.0.1.130; };
};

在這台 NS 主機上面﹐所有關於 siyongc.domain 的查詢﹐都將轉交到 192.168.100.23 或 10.0.1.130 那邊去。

 

九. 設定子網域授權

但如果您的網路非常龐大﹐那您需要了解一下 DNS 的子網域 (sub zone) 授權設定。

用實際的例子來說明。正如您從本章所看到的範例﹐目前我在 rh71 上面已經設定有兩個 domain 的 zone ﹕siyongc.domain 和 dmz.domain 。假設我現在要在 siyongc.domain 分出一個 sub-zone﹐稱為 home.siyongc.domain ﹐同時將這個 sub-zone 授權給一台叫 diamond 的主機來管理﹔目前 diamond 上面有兩張網路卡﹕192.168.100.26 和 192.168.2.1 ﹐而 home 這個 sub-zone 需要管理的 DNS 除了 diamond 本身外﹐還有 pc100 到 pc200 ( IP 範圍從 192.168.2.100 到 192.168.2.200 之間) 等主機﹐他們都是由 DHCP 發放的。

首先﹐我需要修改 rh71 上的 /var/named/siyongc.domain 擋案﹐將 home 授權給 diamond.home.siyongc.domain 這台 NS 來管理﹐您只需在記錄檔後面增加這些句子就可以了﹕

;; -- sub zones --
$ORIGIN home
@       IN  NS     diamond.home.siyongc.domain.
diamond IN  A 192.168.2.1

上面我用一個 $ORIGIN 來宣告一個屬於 siyongc.domain 範圍內的 sub-zone 叫 home (如果改用帶小數點的 FQDN 的話﹐則寫成 home.siyongc.domain. )﹐以及負責這個 sub-zone 的 NS 主機﹐還有 NS 主機的 IP 位址所在。這裡的 NS 記錄就是用來授權用的了﹗目前我只授權給單一台 NS 而已﹐如果您喜歡﹐那您可以授權多台 NS 主機。當您在網路上註冊 domain 的時候﹐他們也是在上層(如 com. 或 com.tw. )幫您設定 NS 記錄和 NS 主機的 A 記錄 。

Tips﹕假如您不使用 $ORIGIN 的話﹐那可以取消這行﹐然後將 @ 改為 home ﹐以及將 diamond 改為 diamond.home 就可以了(註﹕兩個記錄名稱都沒有小數點﹗)。

 

接下來的設定﹐需要轉到 diamond 上面進行。首先﹐修改 /etc/named.conf 檔案﹐增加如下數行﹕

zone "siyongc.domain" IN {		// 上一級區域設定
        type forward;
        forwarders { 192.168.100.23; };
};

zone "home.siyongc.domain" IN {	// 本機管轄區域設定
        type master;
        file "home.siyongc.domain";
};

 

父網的 NS 主機可以從 root zone 查詢下來﹐否則的話﹐它就查詢不到其它 sub-zone 的記錄了﹗如果您不能查詢到上游 NS 的話﹐您就沒辦法查詢其他 sub-zones 了。

除此之外﹐我們還必須建立 /var/named/home.siyongc.domain 這個檔案﹐內容如下﹕

$TTL 86400
$ORIGIN home.siyongc.domain.
@ IN  SOA  diamond.home.siyongc.domain. root.diamond.home.siyongc.domain. (
    2001111701 28800 14400 3600000 86400 )
        IN  NS     diamond.home.siyongc.domain.
   600  IN  MX 10  diamond.home.siyongc.domain.

;; -- servers --
diamond IN A 192.168.2.1
        IN  MX 0  diamond.home.siyongc.domain.

;; -- workstations --
$GENERATE 100-200 pc$ A 192.168.2.$

在這裡﹐我首先將 MX 的 TTL 降為 10 分鐘﹐因為我目前還不很確定這個 sub-zone 的郵件是否由 diamond 來管。如果不增加 600 這個欄位的話﹐那麼 TTL 會以前面的 $TTL 值為準﹐也就是一天。然則﹐一旦有別的 DNS 查詢過這個 MX 記錄﹐那麼這個記錄會在對方的 cache 中存在一天時間。假如我日後修改 MX 記錄的話﹐那我很可能要等一天之後﹐才能讓別的 DNS 查詢到新的設定值。

 

在這個檔案中﹐您首次接觸到 $GENERATE 這個選項。如果您有寫過 shell script﹐或是具有“變數 (variable) ”概念的話﹐這行一點都不難理解﹕

  1. 首先﹐我用 $GENERATE 產生一段數值範圍﹐您可以將之當成一個變數陣列( array )。注意﹕這段數值並不能直接用來作記錄項﹔
  2. 然後﹐在這個句子後面的“ $ ”符號就是變數陣列裡面的值(還記得 for 迴圈嗎﹖如果忘記了﹐請回去 補習 shell 的知識)﹔
  3. 其後﹐我所定義的 pc$ 才是記錄項名稱的開始﹕它的意思就是定義一個 pcXXX 的名稱﹐而 XXX 的值就是 $ 。
  4. 那後面的 A 呢﹖您應該知道什麼是 A 記錄類別了吧﹖(不過﹐我覺得奇怪﹐這個版本竟不接受“ IN  A ”這樣的設定﹗不知道新版有沒有解決了﹖)
  5. 同樣道理﹐192.168.2.$ 的那個 $ ﹐和 PC$ 那個 $ 是同一樣的值。

如果您不使用 $GENERATE 的話﹐那就為 pc100 到 pc200 這 100 台主機設定 100 行 A 記錄就是了。

 

註﹕假如您已經在 Internet 上註冊了一個合法的 domain ﹐那麼您在這個 domain 下面切分出去的 sub-zone 就無須再註冊了。因為您的 domain 所使用的 zone 已經獲得授權﹐並且也有自己的 SOA ﹐那麼其下要再授權出多少個 sub-zone﹐或往下授權多少層﹐完全由您自己作主。

 

十. 設定子網反解授權

如果您獲得的 IP 是一整段 class (或 A 或 B 或 C ) 的話﹐在反解設定上也不會太難。

如果您真真正正了解 IP 和 Net mask 的關係﹐那我這裡要出一道難題了﹕我在我的網路設定中﹐10.0.1.0 這個網路實際上借用了 3 個 bit 來切割成 8 個子網路。而我將這台 rh71 上其中一個界面分配到 sub-net ID 為‘100’的這個子網中﹐也就是說﹐實際的 Net ID 應該是‘10.0.1.128’﹔而另外一個界面則分配在 10.0.1.0/27 這個子網路中。

在前面﹐我們已經設定過 0.1.10.in-addr.arpa 的反解了﹐但那次只是單純的為整個 C Class 做反解﹐事實上並沒考慮到 sub-net 的問題。現在我打算將這個網路的反解再進行子網路的授權設定。我暫時保留 10.1.0 這個‘父網’的反解﹐然後將 128 這個子網的反解授權給 10.0.1.130 ( lp64 ) 上面進行, 至於其他網暫時不設定了。

 

先得在 rh7.1 上面確定 /etc/named.conf 這個檔案有關於‘父網’的設定﹕

zone "1.0.10.in-addr.arpa" IN {
        type master;	
        file "10.0.1.rev";
};

 

事實上﹐上面的內容和我們以前的設定沒什麼不一樣﹐您只需確定它有這個設定就行了。原本的 /var/named/10.0.1.rev 卻必須修改一下﹐使之變成如下內容﹕

$TTL    86400
$ORIGIN 1.0.10.in-addr.arpa.	; 宣告當前網路(父網)反解
@  IN  SOA  rh71.siyongc.domain. root.rh71.siyongc.domain. (
            2001111701 28800 14400 3600000 86400 )
   IN  NS   rh71.siyongc.domain.

; 將 128 這個子網授權出去﹕
sub-128 IN  NS  lp64.dmz.domain.

; 以 $GENERATE 的方式﹐建立 CNAME ﹐將查詢轉往子網﹕
$GENERATE 128-159 $ CNAME $.sub-128

在這個特殊的“切割子網”例子中﹐其中最關鍵的設定是 CNAME 的設定﹐如果您沒忘記我前面是如何解釋 CNAME 的話﹐您會知道凡是查詢 CNAME 左邊的記錄﹐就轉到 CNAME 右邊再查一次。這裡﹐我們用 $GENERATE 的方式將 128-159 這段記錄用 CNAME 轉向 sub-128 這個子網查詢。

因為 128 至 159 這段 IP 實際上是在子網 10.0.1.128 裡面的範圍(這段現已授權出去﹐但您不能在 ineternet 上面查詢 203.30.35.128.134 這樣的五組數字的 IP 格式)﹐當人們要查詢所有以 10.0.1 開頭的 IP 的時候﹐都會先向 1.0.10.in-addr.arpa. 的 NS 查詢﹐也就是目前這台機器﹔然後再透過 CNAME 將查詢轉向其子網路 sub-128.1.0.10.in-addr.arpa. 進行查詢﹐直至找到 128 至 159 之間的 PTR 記錄為止。

在上例中的最後一行﹐我將 sub-128 這個自己定義的子網記錄項﹐以 NS 授權給 “lp64.dmz.domain.”來負責。而至於 lp64.dmz.domain 的 IP 在哪裡呢﹖那就透過正解查詢來獲得了﹐我們無需擔心這個﹐除非解那邊沒設定起來。

接下來﹐讓我們轉到 sub-128.1.0.10.in-addr.arpa. 的 NS ﹐也就是 lp64 這台機器上面。首先﹐需要修改 /etc/named.conf 檔案﹐讓 named 知道 sub-128 目前由它來負責﹕

zone "1.0.10.in-addr.arpa" {
	type forward;
	forwarders { 192.168.100.23; };
};

zone "sub-128.1.0.10.in-addr.arpa" {
        type master;
        file "10.0.1.128.rev";
};

當我們完成 named.conf 的設定之後﹐還必須在 /var/named 目錄下面建立相應的檔案﹐也就是 10.0.1.128.rev 這個檔﹕

$TTL 86400
$ORIGIN sub-128.1.0.10.in-addr.arpa.		; 關於當前子網的設定
@  IN  SOA  lp64.dmz.domain. root.lp64.dmz.domain. (
            2001111701 28800 14400 3600000 86400 )

@  IN  NS   lp64.dmz.domain.		; 這應該和父網指定的一致

; 固定 IP 的反解﹕
129  IN PTR dialser.dmz.domain. 
130  IN PTR lp64.dmz.domain. 
131  IN PTR rh71.dmz.domain. 

; 撥接主機的反解﹕
$GENERATE 132-155 $ PTR dialup-pc$.dmz.domain.

 

在當前的 Internet 環境﹐能順利申請到完整的一組 class IP 的情況實在非常少見。這時候您很可能要需要上游 ISP 幫您做反解。如果他們肯授權下來﹐那麼您自己的設計彈性就比較高﹐日後要修改也容易得多。

但是﹐如果在上游沒有授權的情況之下﹐您日後的每次修改﹐都必須要通知上游﹐才能保持資料的準確性﹐卻是十分的不方便。下面的這個方法是是一個折衷的辦法﹐您只需到上游註冊一次﹐日後的變動則完全看您自己的意思了﹕

假設您是一個 ADSL 的用戶﹐獲得 5 個可用 IP﹐分別從 211.2.3.113 到 211.2.3.118﹔同時﹐您為您目前的 domain 註冊為 my.domain。這樣﹐您首先要到上游完成反解的註冊﹐這樣設就可以了﹕

$ORIGIN 3.2.211.in-addr.arpa.
......
114	IN	CNAME		114.my.domain.
115	IN	CNAME		115.my.domain.
116	IN	CNAME		116.my.domain.
117	IN	CNAME		117.my.domain.
118	IN	CNAME		118.my.domain.
......

 

然後您也無需另外設定反解﹐全部都在 my.domain 的記錄檔上面設就可以了﹕

......
$ORIGIN my.domain.
114	IN	PTR	dns.my.domain.
dns	IN	A	211.2.3.114
115	IN	PTR	www.my.domain.
www	IN	A	211.2.3.115
116	IN	PTR	ftp.my.domain.
ftp	IN	A	211.2.3.116
117	IN	PTR	pop.my.domain.
pop	IN	A	211.2.3.117
118	IN	PTR	smtp.my.domain.
smtp	IN	A	211.2.3.118
......

 

十一. 參考資訊

 1. 如果您想看一看設定範例:  http://dnsrd.nctu.edu.tw/Named-Conf/conf.html

 2. DNS 的技術原理則可以參考﹕ http://turtle.ee.ncku.edu.tw/~tung/dns/

 3. http://www.tp.edu.tw/service/dns0.htm 這篇相當容易上手。

 4. http://www.acmebw.com/cats.htm 網站﹐有許多 DNS 的問題與解答。

 5. http://www.isc.org/products/BIND/ 網站﹐最新最全面的關於 BIND 這個軟體的資訊。