本網站一直都有使用ipv6,也一直嚐試利用ipv6提供網頁服務,但是也不知道是HINET小氣還是技術瓶頸,說好的一顆沙子都有IPV6位置的固定IPV6服務一直沒有普及。
雖然之前嘗試使用HINET所提供的IPv6 reverse proxy服務,但是因為https的認證無法通過而取消。
這次利用QNAP架設BIND伺服器,並使用nsupdate功能建立可以自動更新ipv6位置的DNS服務。
需要的軟體可以利用QNAP的Container Station建立。這次使用LXC的Ubuntu 18.04 LTS。
Container Station建立與環境設定請參考相關的QNAP Q&A。
安裝軟體
軟體使用BIND,目前都是BIND9了,至於細項版本的話,因為只服務一台機器就不用挑剔了。
sudo apt-get update sudo apt-get upgrade sudo apt-get install bind9 -y
安裝好之後先確認一下BIND有沒有順利啟動並且監聽PORT 53
netstat -anl |grep 53
tcp 0 0 127.0.0.1:53 0.0.0.0:* LISTEN tcp 0 0 127.0.0.53:53 0.0.0.0:* LISTEN tcp 0 0 127.0.0.1:953 0.0.0.0:* LISTEN tcp6 0 0 :::53 :::* LISTEN tcp6 0 0 ::1:953 :::* LISTEN udp 0 0 127.0.0.1:53 0.0.0.0:* udp 0 0 127.0.0.53:53 0.0.0.0:* udp6 0 0 :::53 :::*
重新啟動服務的方式
sudo service bind9 restart
很重要,因為熟悉度與重啟次數會有相關(笑
如果出現錯誤或是BIND沒有反應的查詢方式
sudo tail -50 /var/log/syslog
syslog是最好用的,有沒有錯誤一看就知道,至於其他的方式像是 sudo service bind9 status 或是 named-checkzone 則是看看就好。
建立nsupdate需要的密鑰
HOST後面的名稱是為了辨別,取名不是很重要。加密的方式有很多種可以選擇,像DH (Diffie Hellman)、HMAC-MD5、HMAC-SHA1、HMAC-SHA224、HMAC-SHA256、HMAC-SHA384或HMAC-SHA512。
我這邊是使用HMAC-SHA512,長度為512bits。
cd /etc/bind sudo dnssec-keygen -a HMAC-SHA512 -b 512 -n HOST est.idv.tw.
完成後在路徑下建立2個檔案,其中的private檔是我們需要的。
Kest.idv.tw.+165+54877.key Kest.idv.tw.+165+54877.private
sudo cat Kest.idv.tw.+165+54877.private
Private-key-format: v1.3 Algorithm: 165 (HMAC_SHA512) Key: b3twery534546hgwe4g43wg54y46u7jhghtrshdf54dyw2a3rtes-05oylperw34534ertertertewrtyb2r057A== Bits: AAA= Created: 20201221022842 Publish: 20201221022842 Activate: 20201221022842
其中的 Algorithm 跟 Key 先記錄下來,並貼在 named.conf.default-zones 裡面。
sudo vi /etc/bind/named.conf.default-zones
// prime the server with knowledge of the root servers ...中略... key "est.idv.tw." { algorithm hmac-sha512; <--- Algorithm填這邊 secret "b3twery534546hgwe4g43wg54y46u7jhghtrshdf54dyw2a3rtes-05oylperw34534ertertertewrtyb2r057A=="; <--- Key填這邊 }; ...中略... //這邊是你的正解檔位置 zone "est.idv.tw" { type master; file "/etc/bind/est.idv.tw.fwd"; allow-query { ANY; }; <--- 允許誰更新 update-policy { grant est.idv.tw. name est.idv.tw. AAAA; <--- 只允許AAAA更新 }; }; ...後略... //這邊就是你的反解檔,但是不需要去動他。
建立好之後可以先restart一次看看有沒有錯誤,通常的錯誤是 “;” 或是 “.” 忘記打。另外就是 update-policy 跟 allow-update 是不能一起使用的。
nsupdate 使用
nsupdate依附在dnsutils 內,所以必須安裝dnsutils在web server(如果是跟BIND安裝在同一SERVER就不用執行這步驟)。
sudo apt-get -y install dnsutils
用法:
nsupdate [-dv] [-y keyname:secret | -k keyfile] [-t timeout] [-u udptimeout] [-r udpretries] [filename]
參數 -d 是debug模式。
參數 -v 是使用TCP方式更新,這樣在更新失敗時會一直重複嚐試直到成功。如果使用UDP則會有下列參數 -t 逾時 、-u 重試間格、-r 重試次數 可使用。
參數 -y 是key值,以 : 來做為分隔,使用法必須依照 加密方式 : key名稱: 密鑰 的方式填入。不建議使用 –y 選項,因為共享密鑰作為命令行參數以明文形式提供,可以在 ps(1)的輸出中或用戶 shell 維護的歷史文件中看到。
參數 -k 則是從文件 keyfile 讀取密鑰,其名稱格式為 K{name}.+165.+{random}.private。由於歷史原因,還必須存在文件 K{name}.+165.+{ random}.key。
先手動更新試試看:
nsupdate -v -k Kest.idv.tw.+165+54877.private update del est.idv.tw. AAAA update add est.idv.tw. 60 AAAA 2001:b011:7c05:14ee::1002 send
正常執行不會出現訊息,若是出現
; TSIG error with server: tsig indicates error update failed: NOTAUTH(BADKEY)
named[58]: client @0x7fe2d412c640 122.116.254.160#29079: request has invalid signature: TSIG hmac-sha512: tsig verify failure (BADKEY)
是密鑰錯誤,可能是打到空白或是加密方式搞錯,可以從syslog看到詳細錯誤訊息。
如果是出現
update failed: REFUSED
named[1363]: client @0x7f8fe4101460 122.116.254.160#38651/key est.idv.tw: updating zone 'est.idv.tw/IN': update failed: rejected by secure update (REFUSED)
查一下是不是 “.” 忘記了。
如果是出現
update failed: SERVFAIL
則必須先看一下syslog,有可能是權限問題造成。只須把目錄更新為775就可以了。等jnl檔建立後即可改回原來的權限。
named[1395]: client @0x7f4b2810fa80 122.116.254.160#2783/key est.idv.tw: updating zone 'est.idv.tw/IN': deleting rrset at 'est.idv.tw' AAAA named[1395]: /etc/bind/est.idv.tw.fwd.jnl: create: permission denied named[1395]: client @0x7f4b2810fa80 122.116.254.160#2783/key est.idv.tw: updating zone 'est.idv.tw/IN': error: journal open failed: unexpected error
確定手動方式可以正常更新之後就可以使用自動執行了
Shell Script
sudo vi ipv6ddns.sh
#!/usr/bin/env bash #安裝路徑 INSTALLPATH="檔案路徑" # NS名稱 HOST="xx.yy.zz." #nsupdate用參數 KEYPATH="Kxyz+165+random.private檔名" # DNS SERVER IP 有裝BIND那台 DNSSERVER="1.2.3.4" #取得現在IPv6位置 IP=`dig -6 TXT +short o-o.myaddr.l.google.com @ns1.google.com | awk -F'"' '{ print $2}'` #記錄在DNS伺服器上的位置 PRIIP=`dig +short @168.95.192.1 $HOST AAAA` if [ "$IP" != "$PRIIP" ]; then echo "server $DNSSERVER" > $INSTALLPATH/nsupdate_update echo "update delete $HOST AAAA" >> $INSTALLPATH/nsupdate_update echo "update add $HOST 60 AAAA $IP" >> $INSTALLPATH/nsupdate_update echo "send" >> $INSTALLPATH/nsupdate_update echo "answer" >> $INSTALLPATH/nsupdate_update echo "IP已變更,更新AAAA紀錄..." nsupdate -v -k ${KEYPATH} $INSTALLPATH/nsupdate_update > /var/log/nsupdate.log 2>&1 else echo "無需更新..." fi
然後將ipv6ddns.sh、private檔、key檔放在同一目錄,並確定權限。
sudo chmod 744 ipv6ddns.sh sudo chmod 600 *.key sudo chmod 600 *.private
執行訊息會存在/var/log/nsupdate.log
確定沒問題後就可以使用cron定期執行。
*/5 * * * * root PATH/ipv6ddns.sh >/dev/null 2>&1
可以用http://ipv6-test.com/validate.php檢查是不是設定正確。
別忘了要到你的Domain服務商那邊將託管與DNS主機設定好。