2013年1月7日 星期一

在 ubuntu 架設 BIND9 與啟用 DDNS

網路上其實已經有很多 BIND9 的相關安裝資訊了,這裡只是記錄我自己的安裝步驟和遇到的問題與解法。

因為我的目的是要架 DDNS Server,忘了在哪裡查到說 BIND8 要某個版本以上才有支援動態更新
因此這裡就直接安裝 BIND9 了~。

1、安裝 BIND9

在 ubuntu 上安裝 BIND9 一樣很簡單,只要用 apt-get install 安裝即可。
sudo apt-get install bind9

在我的 ubuntu 上會顯示以下的訊息:
正在讀取套件清單... 完成
正在重建相依關係
正在讀取狀態資料... 完成
下列的額外套件將被安裝:
  bind9-host bind9utils dnsutils libbind9-80 libcap2 libdns81 libisc83 libisccc80 libisccfg82 liblwres80
建議套件:
  bind9-doc rblcheck
下列【新】套件將會被安裝:
  bind9 bind9utils libcap2
下列套件將會被升級:
  bind9-host dnsutils libbind9-80 libdns81 libisc83 libisccc80 libisccfg82 liblwres80
升級 8 個,新安裝 3 個,移除 0 個,有 57 個未被升級。
需要下載 1,651 kB 的套件檔。
此操作完成之後,會多佔用 1,332 kB 的磁碟空間。
是否繼續進行 [Y/n]?
這裡特別記錄只是記一下 ubuntu 建議安裝 bind9-doc 和 rblcheck 這兩個套件而已 XD
按 Y 以後基本上就會自動把所有 BIND9 相關的東西都建立好了。

2、設定 BIND9
設定 BIND9 蠻建議參考鳥哥的說明 [1],對很多細節都有一些描述。(或者 [2])
首先要設定 BIND9 的網域基本設定~設定檔位置是 /etc/bind/named.conf
在裡面加入一個新的自訂網域,這裡假設是 ddns.local 這個網域,加入的資料如下:
zone "ddns.local" IN {
  type master;
  file "/var/lib/bind/named.ddns.local";
};
第一行指定的就是要用的網域名稱是 ddns.local;
第二行指定這台 DNS 伺服器是這個域名的 Master 主機;
第三行指定 ddns.local 這個域名的正解資料庫設定檔放在 /var/lib/bind/named.ddns.local 這個檔案。
這裡需要注意的是,named.ddns.local 是自由命名的檔案,我在這邊設定的名字是仿照鳥哥的命名方法
不過資料庫設定檔放的位置,在 ubuntu 上建議是放在 /var/lib/bind/ 資料夾內比較好
因為放在別的地方有可能會造成 bind 服務做動態更新時權限不足,會需要額外的設定去讓 bind 擁有寫入權限 [3-4]。

/var/lib/bind/named.ddns.local 的內容如下:
$TTL 600
@  IN  SOA  root.ddns.local. admin.ddns.local. (
                    2013010700
                    3H
                    15M
                    1W
                    1D )
@  IN  NS  ddns.local.
@  IN  A  127.0.0.1
依照鳥哥在 19.4.6 小節中的描述,正解資料庫檔必須包含的資訊有 $TTL, SOA, NS (與這部 NS 主機名稱的 A)。

以上設定完成後,BIND9 基本的 DNS 服務就已經設定完成了,接著只要重新啟動 BIND9 即可。
sudo /etc/init.d/bind restart
不過要注意的是,使用 /etc/init.d/bind start/restart 時,從回應的訊息常常是看不出有沒有錯誤的
想要知道 BIND9 有沒有發生任何錯誤,在 ubuntu 上可以去看 /var/log/syslog 這個系統日誌。
例如可以先開一個 terminal,執行以下的指令:
tail -f /var/log/syslog | grep named
然後再執行 /etc/init.d/bind start/restart,就可以比較清楚地看到 BIND9 啟動時的日誌內容了。

3、測試 DNS
測試 DNS 的方法有很多種,我這邊直接從 Windows 上把 DNS 指給剛剛架起來的 DNS 伺服器
然後執行 nslookup 指令,要求查詢 www.google.com 的位址,回應如下:(xxx.xxx.xxx.xxx 是 DNS 伺服器的 IP 位址)
C:\Users\user> nslookup www.google.com
伺服器: UnKnown
Address: xxx.xxx.xxx.xxx

未經授權的回答:
名稱: www.google.com
Addresses: 2404:6800:4008:c00::63
    74.125.31.147
    74.125.31.99
    74.125.31.103
    74.125.31.104
    74.125.31.105
    74.125.31.106
而在 BIND9 的日誌則會顯示以下的訊息:
named[3100]: success resolving 'www.google.com.org.tw/A' (in 'org.tw'?) after reducing the advertised EDNS UDP packet size to 512 octets

4、設定動態 DNS
設定動態 DNS 的詳細教學也可以參考鳥哥的 19.6.4 小節

首先因為通常不會想要讓任何人都能修改 DNS 的記錄,因此可以用加密的方式來授權
只要把加密的資料傳遞給要授權的程式,就可以只允許特定的程式或伺服器進行 DNS 記錄更新。
產生加密金鑰的方式是執行以下的指令:
dnssec-keygen -a HMAC-MD5 -b 512 -n HOST ddnskey
相關參數的意義一樣請參考鳥哥的說明囉~。
這段指令中,我指定我要產生的加密金鑰的名稱是 ddnskey。
另外要注意的是,這段指令真的會執行很久 XD,想要讓他變快,推薦可以參考 [5] 安裝 haveged
apt-get install haveged
根據 [5] 的說明,會執行很久是因為 dnssec-keygen 要收集 entropy 才能產生夠安全的 key
但是如果系統的 entropy 很少,有可能永遠收集不到足夠的 entropy。

以我這邊的狀況,執行完 dnssec-keygen 後產生的檔案是 Kddnskey.+157+14569.key 和 Kddnskey.+157+14569.private
而產生的金鑰內容如下:
root@ubuntu64:/var/lib/bind$cat Kddnskey.+157+14569.key
ddnskey. IN KEY 512 3 157 5NSa4MFJSXzbXAQAd...R9BzI+9y5oYe7xw==

其中 ddnskey 是金鑰的名稱,"5NSa4MFJSXzbXAQAd...R9BzI+9y5oYe7xw==" 就是金鑰了。

金鑰產生完以後,要去 named.conf 裡面設定,修改後的 named.conf 內容如下:
key "ddnskey" {
  algorithm hmac-md5;
  secret "5NSa4MFJSXzbXAQAd...R9BzI+9y5oYe7xw==";
};

zone "ddns.local" IN {
  type master;
  file "/var/lib/bind/named.ddns.local";
  update-policy {
    grant ddnskey subdomain ddns.local A;
  };
};
首先是增加了一個 key,key 的名字是 ddnskey
使用的加密演算法是 HMAC-MD5,而金鑰是 "5NSa4MFJSXzbXAQAd...R9BzI+9y5oYe7xw=="。
接著原本的 zone 當中增加了一段 update-policy(9~11 行),這是指定這個 zone 的更新規則
第 10 行就是規則的內容,亦即授權使用 ddnskey 的程式可以更新 ddns.local 這個域名的子網域的 A 記錄。

5、測試動態 DNS
要測試動態 DNS,可以直接在 DNS 伺服器上透過 nsupdate 指令進行,例如我輸入以下的指令:
root@ubuntu64:/var/lib/bind$ sudo nsupdate -k ./Kddnskey.+157+32282.key
> server 127.0.0.1
> update add www.ddns.local 600 A 192.168.1.1
> send
指令中,第一行先指定 nsupdate 要使用 /var/lib/bind/Kddnskey.+157+32282.key 這個金鑰檔
第二行指定要使用的 DNS 伺服器是 127.0.0.1(即本機)
第三行設定更新,要更新 www.ddns.local 這個域名,指定 A 記錄為 192.168.1.1
第四行送出指令~。
第四行送出後,在日誌上就會出現類似以下的記錄:
named[4344]: client 127.0.0.1#23142: updating zone 'ddns.local/IN': adding an RR at 'www.ddns.local' A
named[4344]: zone ddns.local/IN: sending notifies (serial 1)

這時如果要看更新的結果,暫時沒辦法從資料庫設定檔上看到。
但是只要把 BIND9 關掉之後,去看 ddns.local 的資料庫設定檔
就會發現透過 nsupdate 指令寫進去的子網域,已經自動被寫進資料庫設定檔囉!

參考資料:
1、鳥哥的 Linux 私房菜:第十九章、主機名稱控制者: DNS 伺服器
2、Configure the DHCP server dynamically update the DNS records on Ubuntu 12.04LTS
3、nsupdate on a new ubuntu box failed to write the jnlp file
4、Ubuntu rndc.key dynamic DNS updates failing
5、dnssec-keygen takes forever to generate a keyfile

沒有留言: