สมมุติว่าได้สมัครเป็นสมาชิก ddns client ไว้ที่ www.zoneedit.com และ www.everydns.net ไว้เรียบร้อยแล้ว
การนี้เราจะใช้ทั้งคู่ในการเป็น name server ให้เรา กันเหนียวไว้ เวลาอันไหนตาย อีกอันจะได้ทำหน้าที่แทน
จากประวัติพบว่า zoneedit เสถียรและอัปเดตเร็วกว่า เราจึงให้ขึ้นเป็น primary
งานที่ต้องทำคือ
# mkdir -p /sys1/sysb/etc/ddns
# ln -sf /sys1/sysb/etc/ddns /etc
ตั้งชื่อว่า d.router-getip เอาไว้ใน /usr/local/sbin
โดยถ้ามีอาร์กิวเมนต์ต่อท้ายว่า "RESET" จะสั่งให้เราเตอร์เริ่มการทำงานใหม่ สำหรับใช้ในกรณีที่เราเตอร์ฝั่งเราหรือฝั่งไอเอสพีเกิดอาการแฮงก์
(ต้องปรับสคริปต์ตามเราเตอร์ที่ใช้นะครับ)
# vi /usr/local/sbin/d.router-getip
#!/bin/bash
USER="ROUTER_ADMIN"
PASSWORD="ROUTER_PASSWORD"
IPAB="58.9" #OUR FIRST 2 DIGIT OF IP NUMBER
ROUTERNAME="192.168.5.1"
if [ "$1" == "RESET" ]; then
ADDRESS="http://$ROUTERNAME/rebootinfo.cgi"
wget -o /dev/null -O - \
--http-user="$USER" \
--http-passwd="$PASSWORD" \
"$ADDRESS"
echo "RESET ROUTER"
else
ADDRESS="http://$ROUTERNAME/wancfg.cmd?action=view"
IP_ADDR=`wget -o /dev/null -O - \
--http-user="$USER" \
--http-passwd="$PASSWORD" \
"$ADDRESS" \
| grep $IPAB \
| cut -d ">" -f 2 \
| cut -d "<" -f 1`
echo $IP_ADDR
fi
เปลี่ยนสถานะให้ root ดูได้เท่านั้น เพราะมีรหัสผ่านอยู่ในสคริปต์
# chmod 700 /usr/local/sbin/d.router-getip
ตั้งชื่อว่า d.router-cron-checkip เอาไว้ใน /usr/local/sbin
การทำงานคือ ถ้าอ่านค่าไอพีจากเราเตอร์ไม่ได้ (อาจเกิดจากเราเตอร์ของเราหรือของไอเอสพีแฮงก์) จะสั่งรีเซ็ตเราเตอร์ใหม่
# vi /usr/local/bin/d.router-cron-checkip
#!/bin/bash
DATA="/etc/ddns/router-ip"
OLD_IP=`cat $DATA`
CUR_IP=`/usr/local/sbin/d.router-getip`
#SOLVE ROUTER (OR ISP?) IS HUNG
if [ ! $CUR_IP ]; then
/usr/local/sbin/d.router-checkip RESET
fi
#TEST BETWEEN SAVED-IP AND NEW-READ-IP
if [ "$OLD_IP" != "$CUR_IP" ]; then
echo $CUR_IP > $DATA #SAVE NEW IP
/usr/local/sbin/d.router-reconnect
fi
เปลี่ยนสถานะให้รันได้
# chmod 700 /usr/local/bin/d.router-cron-checkip
ตั้ง cron ทุก 5 นาที (ถ้าคุณภาพสายไม่ดี อาจตั้งค่าให้บ่อยขึ้นก็ได้ครับ)
# crontab -e
... #CHECK ROUTER IP ADDRESS EVERY 5 MIN */5 * * * * /usr/local/bin/d.router-cron-checkip ...
ในครั้งแรก ที่ยังไม่มีไฟล์ router-ip ต้องสร้างก่อน เพียงครั้งเดียว
# d.router-getip > /etc/ddns/router-ip
สร้างไฟล์ข้อมูลโดเมนเอาไว้ที่ /etc/ddns (เลียนแบบการวางไฟล์จาก apache2)
โดยเราจะเขียนไฟล์คอนฟิกเอาไว้ใน /etc/ddns/ddns-available และเมื่อเสร็จแล้วก็โยงลิงก์เข้าไปที่ /etc/ddns/ddns-enabled
(วิธีนี้ทำให้ปรับแต่งไฟล์ง่าย อันไหนที่ทดสอบแล้วว่ายังไม่เรียบร้อย ก็แค่ลบลิงก์ไป)
สคริปต์จะเข้าไปอ่านไฟล์คอนฟิกจากในไดเรกทอรี่ /etc/ddns/ddns-enabled
# mkdir -p /etc/ddns/{ddns-available,ddns-enabled}
สมมุติว่าเราจดทะเบียนไว้ที่ zoneedit.com และ everydns.net ไว้ 2 โดเมน
คือ example.com และ example.org
ตัวอย่างไฟล์คอนฟิก จะเป็นดังนี้
# vi /etc/ddns/ddns-available/zoneedit
#ZONEEDIT DATA USER="ZONEEDIT-USER" PASSWORD="ZONEEDIT-PASSWORD" #UPDATE_DOMAIN="DOMAIN:NAME-SERVER, ... " #NO SPACE IN FIELD UPDATE_DOMAIN=" example.com:ns13.zoneedit.com example.org:ns2.zoneedit.com"
# vi /etc/ddns/ddns-available/everydns
#EVERYDNS DATA USER="EVERYDNS-USER" PASSWORD="EVERYDNS-PASSWORD" #UPDATE_DOMAIN="DOMAIN:NAME-SERVER, ... " #NO SPACE IN FIELD UPDATE_DOMAIN=" example.com:ns2.everydns.net example.org:ns2.everydns.net"
ต้องระวัง พยายามอย่าพิมพ์ผิด เพราะข้อมูลในนี้คือตัวแปรในสคริปต์โดยตรง ไม่มีการตรวจสอบความถูกต้องจากสคริปต์อีกแล้ว
โยงลิงก์ เพื่อเปิดใช้งาน
# ln -sf /etc/ddns/ddns-available/* /etc/ddns/ddns-enabled
ต่อไปสร้างสคริปต์ชื่อ d.router-cron-checkddns เอาไว้ที่ /usr/local/sbin เพื่อตรวจสอบไอพีของเราจากผู้ให้บริการ
# vi /usr/local/sbin/d.router-cron-checkddns
#!/bin/bash
# CRON SCRIPT FOR TEST IP FROM PROVIDER.
# KNOWN PROVIDER:
# zoneedit.com
# everydns.net
#
# PUT PROVIDERS DATA FILE IN /etc/ddns/ddns-available .
# MAKE LINK TO /etc/ddns/ddns-enabled TO ENABLE.
#DEFAULT DIRECTORY CONTAIN DDNS PROVIDERS DATA
DIR="/etc/ddns/ddns-enabled"
# GLOBAL VAR
CUR_IP=`/usr/local/sbin/d.router-getip`
UPDATE_SCRIPT="/usr/local/sbin/d.router-updatezone"
for PROVIDER in `ls -1 $DIR`; do
#GET VARIABLE: $USER,$PASSWORD,$UPDATE_DOMAIN
. $DIR/$PROVIDER
for i in $UPDATE_DOMAIN; do
DOMAIN=`echo $i | cut -d: -f1`
NAME_SERVER=`echo $i | cut -d: -f2`
TEST_IP=`nslookup $DOMAIN $NAME_SERVER | grep -v "#" | grep Address | cut -d\ -f2`
if [ "$TEST_IP" != "$CUR_IP" ]; then
$UPDATE_SCRIPT $PROVIDER
fi
done
done
ทำให้รันได้
# chmod 700 /usr/local/sbin/d.router-cron-checkddns
ตั้ง cron ทุก 30 นาที
# crontab -e
... #CHECK DOMAIN IP ADDRESS EVERY 30 MIN */30 * * * * /usr/local/sbin/d.router-cron-checkddns ...
เป็นการสั่งอัปเดต โดยนำค่าจากข้อมูลในไฟล์คอนฟิกข้างบน คือใน /etc/ddns/ddns-enabled มาอัปเดต ชื่อไฟล์คือค่าอาร์กิวเมนต์ของสคริปต์ ยกเว้นถ้าใส่ -a จะหมายถึง all คืออัปเดตทุก ๆ ผู้ให้บริการ
การทำงานของสคริปต์จะแบ่งเป็น 2 จังหวะ คือในครั้งแรกจะอัปเดตรวดเดียวกับทุกโดเมน เมื่อเสร็จเรียบร้อยแล้วจะย้อนกลับมาตรวจสอบอีกครั้งนึงว่า ในแต่ละโดเมนรายงานค่าไอพีถูกต้องหรือไม่ ถ้าไม่ถูกก็จะเว้นไป 5 วินาที แล้วเชื่อมต่อใหม่เป็นจำนวน 10 รอบการทำงาน
สร้างสคริปต์ชื่อ d.router-updatezone เอาไว้ที่ /usr/local/sbin ในการอัปเดตเมื่อไอพีเปลี่ยน
# vi /usr/local/sbin/d.router-updatezone
#!/bin/bash
# SCRIPT FOR UPDATE DNS RECORD.
# KNOWN PROVIDER:
# zoneedit.com
# everydns.net
#
# PUT PROVIDERS DATA FILE IN /etc/ddns/ddns-available .
# MAKE LINK TO /etc/ddns/ddns-enabled TO ENABLE.
# DATA FILE FORMAT:
# USER="user"
# PASSWORD="password"
# UPDATE_DOMAIN="
# example.com:ns1.zoneedit.com
# example.com:ns2.zoneedit.com"
if [ ! $1 ]; then
PROG=`basename $0`
echo "Usage: $PROG [-a=all | ddns_provider_file]"
exit
fi
#DEFAULT DIRECTORY CONTAIN DDNS PROVIDERS DATA
DIR="/etc/ddns/ddns-enabled"
if [ "$1" == "-a" ]; then
DDNS_ENABLED=`ls -1 $DIR`
else
DDNS_ENABLED=$1
fi
# GLOBAL VAR
IP_ADDR=`/usr/local/sbin/d.router-getip`
# FIRST FAST UPDATE
fastupdate() {
ADDRESS=$1
DOMAIN=$2
USER=$3
PASSWORD=$4
echo "$DOMAIN fast update ..."
wget -O - --http-user=$USER --http-passwd=$PASSWORD "$ADDRESS"
}
# SECOND RECHECK & UPDATE
recheck() {
ADDRESS=$1
DOMAIN=$2
NAME_SERVER=$3
USER=$4
PASSWORD=$5
echo "$DOMAIN recheck with $NAME_SERVER ..."
TEST_IP=`nslookup $DOMAIN $NAME_SERVER | grep -v "#" | grep Address | cut -d \ -f 2`
echo "REAL_IP=$IP_ADDR , TEST_IP=$TEST_IP"
I=0
LOOP=10
while [ $I -lt $LOOP ] && [ "$IP_ADDR" != "$TEST_IP" ] ; do
wget -O - --http-user=$USER --http-passwd=$PASSWORD $ADDRESS
sleep 5
echo "ROUND=$I , NAME_SERVER=$NAME_SERVER , REAL_IP=$IP_ADDR , TEST_IP=$TEST_IP"
TEST_IP=`nslookup $DOMAIN $NAME_SERVER | grep -v "#" | grep Address | cut -d \ -f 2`
I=$[$I+1]
done
}
# BEGIN MAIN
#1.FAST UPDATE
for PROVIDER in $DDNS_ENABLED; do
#GET VARIRABLE $USER,$PASSWORD,$UPDATE_DOMAIN
. $DIR/$PROVIDER
for i in $UPDATE_DOMAIN; do
DOMAIN=`echo $i | cut -d: -f1`
case $PROVIDER in
zoneedit)
ADDRESS="http://dynamic.zoneedit.com/auth/dynamic.html?host=$DOMAIN"
;;
everydns)
ADDRESS="http://dyn.everydns.net/index.php?ver=0.1&domain=$DOMAIN"
;;
esac
fastupdate $ADDRESS $DOMAIN $USER $PASSWORD
done
done
#WAIT 30 SECONDS BEFORE RECHECK
sleep 30
#2.RECHECK
for PROVIDER in $DDNS_ENABLED; do
#GET VARIABLE $USER,$PASSWORD,$UPDATE_DOMAIN
. $DIR/$PROVIDER
for i in $UPDATE_DOMAIN; do
DOMAIN=`echo $i | cut -d: -f1`
NAME_SERVER=`echo $i | cut -d: -f2`
case $PROVIDER in
zoneedit)
# NEW wget , USED WHEN dynamic.zoneedit.com IS DOWN OR THIS MACHINE STAY BEHIND FIREWALL
ADDRESS="http://www.zoneedit.com/auth/dynamic.html?host=$DOMAIN&type=A&dnsto=$IP_ADDR"
;;
everydns)
# WITH IP, SUITABLE FOR MACHINE BEHIND FIREWALL
ADDRESS="http://dyn.everydns.net/index.php?ver=0.1&ip=$IP_ADDR&domain=$DOMAIN"
;;
esac
recheck $ADDRESS $DOMAIN $NAME_SERVER $USER $PASSWORD
done
done
เปลี่ยนสถานะให้รันได้
# chmod 700 /usr/local/sbin/d.router-updatezone
สคริปต์นี้แทบไม่มีอะไร เพียงแต่ไปเรียกใช้สคริปต์อัปเดตข้างบน เพียงแต่ใส่พารามิเตอร์เป็น -a (อัปเดตทุกผู้ให้บริการ) เท่านั้น
แต่ว่าต้องสร้างสคริปต์นี้ไว้ เพราะเราจะต้องเชื่อมโยงกับการอัปเดต bind9 ที่จะติดตั้งต่อไป
ตั้งชื่อว่า d.router-reconnect เอาไว้ใน /usr/local/sbin
# vi /usr/local/sbin/d.router-reconnect
#!/bin/bash # UPDATE ALL ENABLED ZONE #KILL OLD PROCESS killall d.router-updatezone #UPDATE ALL ZONE /usr/local/sbin/d.router-updatezone -a #-------ADDITIONAL BIND9 SCRIPT:------------------
เสร็จแล้ว