簡易DDNS
20161218

◆個人的な仕様が理由で実装を計画
 サーバー専用に1回線、その他PC用(複数)に1回線を用意し、合わせて2回線構成である。
 サーバー回線は固定IP
 その他PC回線は非固定IP
 その他PC回線の非固定IPを自ドメインのDNSで運用したい。
◆実装するにあたって
 1.意識する事なく使用出来るよう、全ての処理をDNSサーバー(固定IP所持サーバー)にて行う。
 2.DNSサーバー側はNICを2つ実装(仮想割り当てでも可)し、どちらの回線も使用出来る事。
 →また、ルーター1機で回線の割り振りをしている場合についてもNIC1つで可。
 3.IPアドレス確認ページは当サーバー(61.197.190.58)に設置しているものを使用(変更可)
 4.一時的にルーティングテーブルを変更する事によって、普段使用しない回線側のグローバルIPアドレスを確認します。
 →ルーター1機で構成する場合は経路設定を実施する必要有り。
◆確認環境
 CentOS7.x

 BIND
 Cron
※CentOS6.xの場合は、簡易DDNSページをご参照ください。
tmpファイルを作成する事から、「tmpfs(RAMディスク)」の設定も検討して下さい。
◆処理の流れ
 1.IPアドレス確認ページにアクセスする時のみ、ルーティングテーブルを変更
 2.IPアドレス確認
 3.DNSのファイルとの差異を計測。差異があれば更新
 4.情報更新をした場合はDNSサーバーの再起動
 5.ルーティングテーブルを元に戻す
 6.情報更新をした場合はメールにて変更があったことを送信
 7.1〜6をCronにて定期的に実行

非固定IP側を経由(proxy等)してwgetを行える場合はルーティングテーブルの変更処理は不要
◆まずはシェルスクリプトの作成
 [root@Server ~]#  vi /root/dns.sh

#!/bin/sh
export LANG=ja_JP.UTF-8

# Ver 20160112

# サブドメインの指定
SUB="winows"

# 取得したいグローバルIPアドレスのゲートウェイを指定。
# この場合、IPアドレス取得ページへアクセスする時に限り192.168.10.1ルーターを使用する。
# ルータ1機にてルーティングで対応する場合はデフォルトゲートウェイを指定して下さい。
GW="192.168.10.1"

# DNSファイルの指定
FILE="/var/named/chroot/var/named/ry.tl.db.wan"

# DNSレコードを変更した場合にメールを送信するか否か。「no」で無効。(デフォルト有効)
MAILMESSAGES="yes"
# メール送信先アドレス。(デフォルトroot宛)
MAILADDRESS="root"
# TMPディレクトリ
TMP_DIR="/tmp"

# ルーティングテーブルを一時的に書き換えるか否か。「no」で無効(デフォルト有効)
# ルーター1機構成で適切に設定している場合や、
# サブドメイン側IPのプロキシサーバーを経由している等でwgetを制御出来ている場合は無効でも可
ROUTE="yes"

# 以降設定不要

# 日付取得
DATE=`date '+%Y%m%d'`
DATE2=`date '+%Y/%m/%d %k:%M:%S'`

# TMPファイル定義
TMP="$TMP_DIR/DNS.tmp"
TMP_FAILE="$TMP_DIR/DNS_FAILE.tmp"

# ルーティングテーブルを一時的に変更
if [ $ROUTE = "yes" ] ; then
ip route add 61.197.190.58/32 via $GW
GW_FLAG="1"
else
GW_FLAG="0"
fi

# 現在のIPアドレス取得
IP=`wget -t 1 -T 1 -q -O - 61.197.190.58/ip.shtml | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+"`
# →高負荷時に失敗する等、場合によってはタイムアウト時間(-T)及びリトライ回数(-t)を変更して下さい。

# IPアドレス取得失敗時、処理の中止
if [ "$IP" = "" ] ; then
# メール送信用
if [ $MAILMESSAGES = "yes" -a ! -e $TMP_FAILE ] ; then
echo -e "IPアドレスの取得に失敗しました。"| mail -s "$0" $MAILADDRESS
echo [$DATE2] IPアドレスの取得に失敗 >> $TMP_FAILE
fi
exit 0
else
rm -rf $TMP_FAILE
fi

# 現在設定している情報取得
DNSR=`cat $FILE | grep -w $SUB`
# IPアドレス取得
DNSIP=`cat $FILE | grep -w $SUB | grep -o "[0-9]\+\.[0-9]\+\.[0-9]\+\.[0-9]\+"`
# Serial取得
SERIAL_DATE=`cat $FILE | grep -o "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"`
SERIAL=`cat $FILE | grep -o "[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]"`

FLAG="0"

# 登録が無い場合
if [ "$DNSR" = "" ] ; then
FLAG="1"
echo $SUB IN A $IP >> $FILE
# 登録されているIPアドレスと現在のIPアドレスに相違がある場合
elif [ "$DNSIP" != "$IP" ] ; then
FLAG="1"
sed -i "s/$DNSIP/$IP/g" $FILE
fi
# シリアル変更
if [ $FLAG -eq 1 ] ; then
if [ "$SERIAL_DATE" = "$DATE" ] ; then
NEWSERIAL=`expr $SERIAL + 1`
sed -i "s/$SERIAL/$NEWSERIAL/g" $FILE
else
NEWSERIAL="${DATE}01"
sed -i "s/$SERIAL/$NEWSERIAL/g" $FILE
fi
fi

# ゾーン書き換えた場合
if [ $FLAG -eq 1 ] ; then
# DNSサーバーを再起動
systemctl restart named.service
# メール送信用
if [ $MAILMESSAGES = "yes" ] ; then
echo "IPアドレスの変更を検知。DNS設定を変更しました。" > $TMP
echo "[$DNSIP]→[$IP]" >> $TMP
echo "" >> $TMP
cat $FILE >> $TMP
cat $TMP | mail -s "$0" $MAILADDRESS
rm -f $TMP
fi
fi

# ルーティングテーブルを書き換えている場合は、元に戻す
if [ $GW_FLAG -eq 1 ] ; then
ip route del 61.197.190.58/32 via $GW
GW_FLAG="0"
fi

※GWとDNSファイルの指定等、必ず環境に合わせて変更してください。
◆一応実行権限を付与
 [root@Server ~]# chmod +x /root/dns.sh
◆cronにて自動実行するよう設定しましょう。
 [root@Server ~]# echo "*/5 * * * * root bash /root/DNS.sh >/dev/null 2>&1" >> /etc/crontab

この場合、5分毎に監視して対処します。
変更する場合はcrontabにて設定を確認して下さい。
〜ルーター1機で経路設定が必要な場合〜
◆Cisco機器の場合の経路設定例

 Cisco851(config)#ip route 61.197.190.58 255.255.255.0 Dialer 1

この場合、宛先61.197.190.58」であれば「Dialer 1」インターフェースを使用して接続します。

終わり。