all-in-one 3 (dynamic ip script)
ทำเรื่อง dynamic dns client
สมมุติว่าได้สมัครเป็นสมาชิก ddns client ไว้ที่ www.zoneedit.com และ www.everydns.net ไว้เรียบร้อยแล้ว
การนี้เราจะใช้ทั้งคู่ในการเป็น name server ให้เรา กันเหนียวไว้ เวลาอันไหนตาย อีกอันจะได้ทำหน้าที่แทน
จากประวัติพบว่า zoneedit เสถียรและอัปเดตเร็วกว่า เราจึงให้ขึ้นเป็น primary
งานที่ต้องทำคือ
- สคริปต์ดูเลขไอพีจากเราเตอร์ หรืออาจให้เริ่มการทำงานเราเตอร์ใหม่
- สคริปต์ cron ที่จะตรวจไอพีมาเก็บไว้เป็นระยะ ทุก 5 นาที ถ้าไม่เท่าเก่าจึงสั่งอัปเดต แบบอัปเดตทุกโซน
- สคริปต์ cron ที่จะตรวจไอพีซ้ำ จาก dns ภายนอก ทุกครึ่งชั่วโมง ถ้าไอพีไม่ตรงค่อยสั่งอัปเดต เฉพาะโซนที่ไม่ตรง
- สคริปต์อัปเดต แบบมีอาร์กิวเมนต์ต่อท้ายว่าจะให้อัปเดตทั้งหมด หรือเฉพาะราย
เตรียมไดเรคทอรี่ก่อน
# 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
สคริปต์ cron ที่จะตรวจไอพีมาเก็บไว้เป็นระยะ ทุก 5 นาที
ตั้งชื่อว่า 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
สคริปต์ cron ที่จะตรวจไอพีซ้ำ จาก dns ภายนอก ทุกครึ่งชั่วโมง
สร้างไฟล์ข้อมูลโดเมนเอาไว้ที่ /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:------------------
เสร็จแล้ว
- Printer-friendly version
- Log in or register to post comments
- 3890 reads
Recent comments