|
[分享] 用 BIND 架設 DDNS Server 提供 DDNS 服務
版權宣告
歡迎轉載 ,但有任何修改請來信告知,不得作為商業用途
作者: abelyang <abelyang{at}twnic{dot}net{dot}tw>
version: 1.0
最後修正時間: 2007/07/28 00:10
轉載時請保持此一宣告
1.前言
目前動態 DNS 兩大主流,一個是 BIND (ISC),另一個就是套接 DB 的 DNS 如 PowerDNS (或 mydns)
等,兩種方式各有好壞,主要是因為 BIND 會有一些複雜性,但效果非常好,而 PowerDNS 則是很簡單,
但相對的它不能承受大量查詢,主要原因在於資料庫上先天的限制. 本文主要為介紹 BIND 之動態
DNS 做法,而這個做法之最重要重點則在於nsupdate 這個指令及 IXFR (incremental zone transfer
request),是不同於傳統的 AXFR (full zone transfer),IXFR 在做 Zone Transfer (DNS 的同步機制)
時,會以差異化的部份進行同步, 而 AXFR 則是以整個 Zone 進行同步.DDNS 主要由 RFC 2136 構成,
建議若您要對 DDNS 有一定深入的了解,可以閱讀這篇 RFC 以了解更多重要的資訊
(1034 1035 1995 是 2136 的基礎)
本文適用於對 DNS 巳有一定了解的朋友,若是不甚清楚建議您可先參考 TWNIC 所做的講義:
http://dns-learning.twnic.net.tw/DNS94/
如果你想對 nsupdate + key 的方法有更深入的了解可以參考
http://www.study-area.org/tips/tipsfr1.htm
或參考 isc bind 的文件有最詳細的解說
http://www.isc.org/sw/bind/arm93/Bv9ARM.pdf
本文不討論 view 的情形,若是 view 情形您必需從 view 的 match-client 去更新或是使用不同
的 key,所以建議您多參考 isb bind 的文件,雖然辛苦些,但資料絕對是最官方最正確的
2. 必要的資訊及知識
本文的範例以 Shell Script 做成,重點在於原理,採用什麼工具或做法完全視您個人的能力.以下
就一些重點進行說明.
2.1 BIND 動態更新
基本上在 BIND8,BIND9 都是支援 nsupdate 的,但這裏面要注意的是 BIND8 在8.3.X 後才支援
IXFR,而 BIND9 則都支援,所以若您的 Server 在 8.3.0 前的版本,那就不建議了,更何況這個以
前的版本多多少少都有許多安全性的問題.
2.1.1 nsupdate:
bind 要開 allow-update 選項,讓你的程式可以來執行更新指令,allow-update 選項可以是 IP 或
key,而本文僅就 IP進行介紹,若用 Key 對有些朋友來說可能會變得稍複雜些了
CODE:[Copy to clipboard]# named.conf
# 其他略
zone "dyndns.twnic.tw" {
type master;
file "dyndns.twnic.tw";
allow-update {127.0.0.1;}; # 開放 127.0.0.1 進行動態更新
allow-transfer { slave_ip;127.0.0.1;}; # slave 主機,可能一部或多部,若無請寫 none
};
以上是開放讓 127.0.0.1 進行動態更新,動態更新有其指令,詳細您可看看 nsupdate man page
(man nsupdate),以下僅以最常用的進行說明:
CODE:[Copy to clipboard]#nsupdate
[root@eai1 dyndns]# nsupdate
> server 127.0.0.1
> zone dyndns.twnic.tw
> update delete user1.dyndns.twnic.tw A 211.72.210.249
> update add user1.dyndns.twnic.tw A 211.72.210.251
ttl 'A': not a valid number # 這個例子是錯誤示範,加一筆記錄要有 TTL 值
> update add user1.dyndns.twnic.tw 60 A 211.72.210.251
> show
Outgoing update query:
;; ->>HEADER<<- opcode: UPDATE, status: NOERROR, id: 0
;; flags: ; ZONE: 0, PREREQ: 0, UPDATE: 0, ADDITIONAL: 0
;; UPDATE SECTION:
user1.dyndns.twnic.tw. 0 NONE A 211.72.210.249
user1.dyndns.twnic.tw. 60 IN A 211.72.210.251
> send
> quit
CODE:[Copy to clipboard]server 指向某一台 NameServer 進行 update 操作
zone 修改某個 zone file
update delete 進行 update 的 delete 動作,這個指令格式是
update delete FQDN TYPE RDATA,如果有多筆相同的 A
記錄或不同的 MX 記錄要刪除某一筆需將 RDATA 補上,
若沒有 RDATA 則表示這個 FQDN 的這個 TYPE 都要刪除
(TYPE 即是 A,MX,PTR,SOA,NS..等,RDATA 就是 TYPE 後
接的東西,如 A 的 RDATA 是 IP 而 MX 的 RDATA 是 優
先權 FQDN)
update add 進行記錄的增加,操作如同 delete, 但是一定要有
TTL 值,且必需明確寫出 RDATA
show 這只是操作後要顯示進行了那些 update 指令
send 這個代表要把整個 update 指令送給 server,操作 update
時資料不是馬上送出的,所以 update 可以很多行,最後
nsupdate 看到 send 時,才會將整個所有 update 送出,
而 update 使用 port 53/udp 若送出的資料量 (DNS packet)
大於 512 bytes,則會 truncate 而改使用 53/tcp,這是您
需要注意的地方,而只要您有 send, 則 SOA 記錄的 serial
會自動加1,以期讓 slave 來進行同步,所以過多的 send 可
能造成過多的 traffic
2.1.2 zone file 及日誌檔
如果您進行了 nsupdate 的操作,則原來 directory 所指的目錄將會產生一些日誌檔,這個日誌檔即為
zone_name.jnl (directory 習慣上都設在 /var/named , 您自己必要注意 named 程式要有寫入的權限,
chroot 狀況等)
CODE:[Copy to clipboard]# 顯示 dyndns.twnic.tw zone file 內容
[root@eai1 named]# cat /var/named/dyndns.twnic.tw
$TTL 86400 ; 1 day
@ IN SOA twnic.net.tw. snw.twnic.net.tw. (
2006073267 ; serial
7200 ; refresh (2 hours)
1800 ; retry (30 minutes)
2419000 ; expire (3 weeks 6 days 23 hours 56 minutes 40 seconds)
300 ; minimum (5 minutes)
)
NS ns2.dyndns.twnic.tw.
NS eai1.twnic.tw.
ns2 A 203.73.24.204
; 如果別人在查詢時,我們有這個記錄則回應這個記錄的 IP,若沒有這個記錄代表
; 這個網站沒有上線,所以此時我們可以建立一筆 wildcard 記錄,指向自己的說
; 明網站,以供 user 識別這個網站沒有上線,而這筆 wildcard 的記錄 TTL 時間
; 不能太長,以免別的 DNS Cache 了這資料
* 0 A 211.72.210.251
# 目錄裏的東西
[root@eai1 named]# ls -la /var/named/
總計 128
drwxr-xr-x 2 named named 4096 7月 27 09:25 .
drwxr-xr-x 20 root root 4096 3月 13 16:50 ..
-rw-r--r-- 1 named named 451 7月 27 09:25 dyndns.twnic.tw
-rw-r--r-- 1 named named 104177 7月 27 10:01 dyndns.twnic.tw.jnl
-rw-r--r-- 1 named named 195 7月 4 2001 localhost.zone
-rw-r--r-- 1 named named 2851 10月 17 2003 named.ca
我們可以看到這個 .jnl 的產生,這個 .jnl 檔是不能隨便刪除,因為它等於是 dyndns.twnic.tw 的補
充資料,而這些補充資料在 DNS reload/restart 時, named 還會在把它讀進來,所以動態更新後的資料,
並不會隨著 dns 重啟後而消失,如果你想讓現在整個 zone 檔出現所有的記錄,那可以 rndc stop 來停止
dns, 此時 named 會把 .jnl資料寫入原來的 zone file,不過這種方式一般來說較不建議,因為我們的 zone
file 只要存一個樣版 (template),其他的東西都是臨時性的. 而若你想知道現在整個 zone 的內容,在可
以做 zone transfer 的主機上(如上例為 slave_ip及 127.0.0.1), 以 dig 指令來執行 axfr:
CODE:[Copy to clipboard][root@eai1 dyndns]# dig @127.0.0.1 dyndns.twnic.tw axfr
; <<>> DiG 9.3.0 <<>> @127.0.0.1 dyndns.twnic.tw axfr
;; global options: printcmd
dyndns.twnic.tw. 86400 IN SOA twnic.net.tw. snw.twnic.net.tw. 2006073528 7200 1800 2419000 300
dyndns.twnic.tw. 86400 IN NS ns2.dyndns.twnic.tw.
dyndns.twnic.tw. 86400 IN NS eai1.twnic.tw.
*.dyndns.twnic.tw. 0 IN A 211.72.210.251
ns2.dyndns.twnic.tw. 86400 IN A 203.73.24.204
user1.dyndns.twnic.tw. 60 IN A 211.72.210.248
user1.dyndns.twnic.tw. 60 IN MX 10 user1.dyndns.twnic.tw.
# 以下略
...
2.設定 NameServer 僅進行差異化的同步
Master/Slave 要進行 zone file 的同步,而 ddns server 若只有一部是可以不用考慮這些問題的,但是若有兩
部以上的 DNS Server, 就需要考慮到同步的進行方式,若 zone file 的總資料量小,採用什麼同步方式是無所
謂的,但若資料量多,或是經常處在變動狀況,那差異化的同步就會顯得很重要,因為它可以讓所有的 DNS 在短時
間內全部同步完成,BIND 支援 IXFR 後,其預設即是採用 IXFR, 若沒有 IXFR (update) 時,則採用 AXFR,所以不
需要對 IXFR 進行額外設定,但為使大家了解其參數,本處還是舉例來進行說明,好讓大家能夠更了解
CODE:[Copy to clipboard]# master DNS's named.conf
key "rndc-key" {
algorithm hmac-md5;
secret "HpXtFRFdLaRPFjpZokIwusyezyyRNjxhcafCfmktWNyGkDFzHAXlpTZQtVLc";
};
controls {
inet 127.0.0.1 port 953
allow { 127.0.0.1; } keys { "rndc-key"; };
};
options {
directory "/var/named";
pid-file "/var/run/named/named.pid";
allow-transfer { none; };
provide-ixfr yes; # 提供 slave 主機以 IXFR 同步,default yes
request-ixfr yes; # slave 以 IXFR 向 master 進行同步,default yes
recursion no; # 不允許遞迴查詢
};
zone "0.0.127.in-addr.arpa" {
type master;
file "named.local";
};
zone "." {
type hint;
file "named.ca";
};
zone "dyndns.twnic.tw" {
type master;
file "dyndns.twnic.tw";
max-journal-size 500k; # 設定日誌檔大小
allow-transfer { 203.73.24.204;127.0.0.1;}; # 可做 ixfr/axfr 的來源 IP,必需寫上 slave,
# 127.0.0.1 是方使我們自己查看 zone file 現況
also-notify {203.73.24.205;211.72.210.251}; # 額外的同步主機,這可能是 hot site 備份主機
allow-update { 127.0.0.1;}; # 允許動態更新的來源
}; |
|