DDNS 更新用スクリプト (DynDNS 用)

DynDNS が有償化したため、無料時代に設定したホスト名を維持するために組んだスクリプト。自分用のメモなのでたぶん正しく動作すると思うけど、動作その他一切保証はしない。

・本スクリプトを公開して何が嬉しいのか?

必要以上に DynDNS 側の URL へアクセスしなくて済む。

・その他の注意点

  • スクリプトは nobody で実行する。
  • data ディレクトリは nobody ユーザで読み書き出来きること。
  • ip-check.sh.conf は nobody ユーザ権限でパーミッションは 600 とする。
  • ip-check.sh は nobody ユーザで実行できるようにしておき、適当な間隔で nobody ユーザで cron で実行する。

・以下のような配置を想定

/usr/local/ip-check/
├── [drwxr-xr-x]  data
├── [-rwxr-xr-x]  ip-check.sh
└── [-rw-------]  ip-check.sh.conf

・ip-check.sh.conf (DynDNS のアカウントとパスワードを設定。パーミッションに注意。)

http_user=DynDNSのアカウント
http_passwd=上記のパスワード

・ip-check.sh (オプション force で強制的に通知)

#!/bin/bash
#-----------------------------
# Usage: ip-check.sh [force]
#
# IPv4 アドレスに前回と変化があれば、DynDNS に通知する。
#
# Option
# force : IPv4 アドレスに変更がなくとも、強制的に DynDNS に通知する。
#-----------------------------

export LANG=C

#-----------------------------
# 要変更: DynDNS で設定したドメインを FQDN で指定
DYNDNSHOSTNAME="www.example.com"
#-----------------------------

#-----------------------------
# 要変更: DynDNS のログインアカウントとパスワードを記載したファイルを指定 (他のユーザから読み書きできないようにすること)
CONFFILE="/usr/local/ip-check/ip-check.sh.conf"
#-----------------------------

#-----------------------------
# 要変更: スクリプトが使用するデータディレクトリを指定 (スクリプトから読み書きできること)
DATADIR="/usr/local/ip-check/data"
#-----------------------------

#-----------------------------
# 要変更: DynDNS に対して更新を行った場合の結果報告用メールアドレス
REPORTMAIL="root"
#-----------------------------

#-----------------------------
# IPv4 のチェック用 URL を指定 (単に aaa.bbb.ccc.ddd 形式で返してくるものであれば良い)
# 以下は機能しているが、出来れば自分で借りているレンタルサーバなり VPS なりでそういうスクリプトを準備してそちらを参照して欲しい。
CHECKURL="http://www.manabii.info/php/addr.php"
# 例として、php スクリプトなら以下のような内容のファイルをサーバにアップロードしておいて、そこへアクセスするなどする。
# <?php echo $_SERVER["REMOTE_ADDR"]; ?>
#-----------------------------

IPDATAFILE="${DATADIR}/ip-check.data"
LOCKFILE="${DATADIR}/ip-check.lock"
TMPFILE="${DATADIR}/ip-check.tmp"
LASTMSG="${DATADIR}/ip-check.msg"

DYNDNSURL="https://members.dyndns.org/nic/update"
PROGNAME="IP-Check"

#-----------------------------
# ロックファイル作成
function create_lockfile {
	if [ ! -e ${LOCKFILE} ]
	then
		touch ${LOCKFILE}
	fi
}
#-----------------------------

#-----------------------------
# ロックファイル削除
function remove_lockfile {
	if [ -e ${LOCKFILE} ]
	then
		rm ${LOCKFILE}
	fi
}
#-----------------------------

if [ -e ${LOCKFILE} ]
then
	echo "${PROGNAME}: Another process is running."
	exit 1
fi

if [ ! -d ${DATADIR} ]
then
	echo "${PROGNAME}: Data directory is not found."
	exit 1
fi

if [ ! -e ${CONFFILE} ]
then
	echo "${PROGNAME}: Config file is not found."
	exit 1
fi

if [ ! -e ${IPDATAFILE} ]
then
	wget -q ${CHECKURL} -O ${IPDATAFILE} > /dev/null
	if [ 0 -ne ${?} ]
	then
		exit 1
	fi
	exit 2
fi

create_lockfile

wget -q ${CHECKURL} -O ${TMPFILE} > /dev/null

if [ 0 -ne ${?} ]
then
	remove_lockfile
	exit 1
fi

diff ${IPDATAFILE} ${TMPFILE} > /dev/null

if [ 0 -ne ${?} -o "force" = "${1}" ]
then
	export WGETRC=${CONFFILE}
	wget -q -O ${LASTMSG} "${DYNDNSURL}?hostname=${DYNDNSHOSTNAME}&myip=`cat ${TMPFILE}`&wildcard=NOCHG&mx=NOCHG&backmx=NOCHG" > /dev/null
	if [ 0 -ne ${?} ]
	then
		WGETRC=""
		echo "0.0.0.0" > ${IPDATAFILE}
		logger -t ${PROGNAME} "DynDNS: Update Error"
		remove_lockfile
		exit 4
	fi

	WGETRC=""
	cp -a ${TMPFILE} ${IPDATAFILE}
	logger -t ${PROGNAME} "DynDNS: Update ${DYNDNSHOSTNAME} -> `cat ${IPDATAFILE}`"

cat <<EOM | mail -s "IP Address Update" $REPORTMAIL
DynDNS: Update
${DYNDNSHOSTNAME} -> `cat ${IPDATAFILE}`

DynDNS Message:
`cat ${LASTMSG}`
EOM

	remove_lockfile
	exit 3
fi

remove_lockfile

exit 0

しつこいようだが、上記のスクリプトを使用した結果その他について一切保証しない。