DiCEに代わるIP更新プログラム

投稿日: 2008年4月7日 | カテゴリ:『自宅サーバー』>自作プログラム

ダイナミックIPアドレスの変更通知を自動で行うプログラムにDiCEが使用されていますが、これをバックグラウンドで稼動させておくとCPUの負荷率が50%を上下する状態が持続します。そこで、これに代わるプログラムがないか検索し、見つけたプログラムを改良してみました。

次の図は、DiCEが稼動しているときに、システム・モニターを使用してサーバーの負荷率を表示させたものです。明らかにCPUの負荷率が高いことがわかります。

そこで、これに代わるプログラムをインターネットで探したところ、次のようなプログラムを見つけました。あにょの自宅サーバー構築メモ 「IPアドレス自動更新スクリプト」

それ以降、このプログラムを使用させて頂いていたのですが、今年2月ごろからwgetコマンドでIPアドレスを取得し、IPアドレスを保存した時に、以下のように1行目に空白が入るようになり、IPアドレスが取得できないような状態になってしまいました。

 (改行)
REMOTE_ADDR:xxx.xxx.xx.xxx

そこで保存されたIPアドレスがどこに位置しても取得できるようにCシェルでプログラムを書き換えました。また、プログラムをバッググラウンドで稼動させて反応をより速くするようにしました。
このプログラムを使用した結果、CPUの負荷率は最大で10%に低下しました。また、バックグラウンドで5分ごとにチェックしているのでIPが変更されたときの反応が以前よりも速くなっています。

(注) 以下のプログラムは、DDNSのプロバイダーであるDDOの無料アカウントを前提にしています。他のDDNSプロバイダーを使用している場合には、プロバイダーのURLを確認した上でプログラムを適当に書き直してください。

プログラムの構造

  1. DDNSサービス業者に自サーバーのグローバルIPアドレスを問い合わせる。
  2. このIPと既存のIPアドレスを比較して異なっていればDDNSに変更を通知する。
  3. 通知に対する応答をshift-jisに変換して一時ファイルに保存する。
  4. 保存した内容には、HTMLタグ(注1)が付いているのでこれを削除した上でログファイルに保存する。
  5. IPアドレスの変更通知が長時間(1ヶ月)行われないと登録を抹消されてしまうので、これを防ぐために週1回定期確認をする。これは、既存のIPアドレスを保存しているCRT_IP.dat ファイルを削除(つまりNEW_IPとの相異を意図的に作る)することによって実行する。
  6. Awstatsのアクセス解析のカウントから自サイトのIPアドレスを除く設定は、awstats.confファイル内のSkipHostsの項に次のように指定します。
    SkipHosts=”127.0.0.1 REGEX[^192\.168\.X\.] WWW.XXX.YYY.ZZZ”
    127.0.0.1はサーバーのIPアドレス、REGEX[^192\.168\.X\.] はルーターを使用している場合のローカルIPアドレス、最後がダイナミックIPアドレスです。ダイナミックIPアドレスは変化することが前提ですので、変化した場合の対応をしておかなければなりません。今回はこの処理を新たに付け加えました。

(注1) DDNSからの応答は以下のようになります。

<html><body>
<a href="http://ddo.jp/">Dynamic DO!.jp</a><br>
SUCCESS: hsuzuki.ddo.jp <= [ XXX.XXX.XXX.XXX ]<br>
IPアドレス更新完了.<br>※IPアドレスに変更がありませんため、パスワードはチェックしておりません。<br>
2008/05/11 02:04:42<br>
<input type="button" value="閉じる" onclick="window.close();">
</body></html>

整形プログラムで不必要なタグを取り除きます。ログに保存される内容は以下のようになります。

SUCCESS: hsuzuki.ddo.jp <= [ XXX.XX.XX.XXX ]
IPアドレス更新完了.※IPアドレスに変更がありませんため、パスワードはチェックしておりません。
2008/05/11 02:04:42

プログラムの実行方法

  1. まず、phpプログラムとnkfプログラムがインストールされているか確かめます。which php、及びwhich nkf。インストールされていない場合には、yum -y install php、及びyum -y install nkf としてインストールを行います。
  2. /usr/ddns ディレクトリを作成しここに本体プログラム(ip_check.csh)をおきます。DDNSに登録したときに設定したユーザー名とパスワードを所定の部分 に書き込みます。プログラムを実行可能にします。(注2)
  3. /root/program ディレクトリを作成しここに整形プログラム(rm_htmltag.php)をおきます。プログラムを実行可能にします。
  4. /root/temp ディレクトリを作成しておきます。
  5. crontabに起動時にip_check.cshをバックグラウンドで実行するように次の記述を追加します。@reboot /usr/ddns/ip_check.csh &
  6. crontabにCRT_IP を削除する設定を行います。例えば、日曜日の午前1時に削除する場合には、次のように記述します。00 01 * * 0 rm -f /usr/ddns/CRT_IP.dat
  7. コマンド・ラインで、ip_check.csh & と打ってプログラムをバックグラウンドで走らせます(JOB番号を覚えておいて下さい)。/usr/ddns にIP_CRT.datとNEW_IP.datのファイル、/root/temp にddns.tmpファイル、/var/logにddns.logファイルが作成され、上記のようなログデータが残っているはずです。バッググラウンドジョブを停止するには、セッションを終わらせるか、kill ジョブ番号 で停止させます。(注3)

(注2):このプログラムはCシェルでかかれていますが、FedoraなどのUNIX系オスにはcshは標準でインストールされています。ちなみに、which csh で確かめてください。

(注3):端末でのbgジョブはそのセッションが終わる(端末を終了させる)と同時に停止します。実行試験が終わったら、サーバーを再起動してcron からバックグラウンド・ジョブを開始させてください。

プログラムの詳細説明
以下、プログラム ip_check.cshの内容についての詳しい説明です。

#!/bin/csh
set CRT_IPF = /usr/ddns/CRT_IP.dat
set NEW_IPF = /usr/ddns/NEW_IP.dat
set temp = /root/temp/ddns.tmp
set awstats = /etc/awstats/awstats.hsuzuki.ddo.jp.conf
set dummy = /root/temp/dummy.txt

1行目:プログラムの宣言
2行目:現行IPアドレスの保存ファイルの指定
3行目:IPが変更された場合のIPアドレスを保存するファイルの指定
4行目:DDNSプロバイダーからの応答を保存しておく一時ファイルの指定
5行目:アクセス解析Awstatsのconfファイルのパスを指定。サイトの特殊性に応じて変更してください。
6行目:Awstatsのconfファイルを一時格納しておくファイルの指定

while(1)
 wget -q -O $NEW_IPF http://info.ddo.jp/remote_addr.php
 set NEW_IP=`gawk -F : '/REMOTE_ADDR/{print $2}' $NEW_IPF`

1行目:ループの開始
2行目:自サーバーのIPアドレスをDDNSのサーバーに問い合わせ、ファイル$NEW_IPFに取得
3行目:新しいIPアドレスを変数NEW_IPに取得(ファイル$NEW_IPF内の文字列「REMOTE_ADDR」を含む行を検索して、その文字列を「:」で区切り、2番目の文字列=IPアドレスを取得する)

if ( -e $CRT_IPF ) then
 set CRT_IP=`grep '.' $CRT_IPF`
 if ( $NEW_IP != "" && $CRT_IP != $NEW_IP ) then
  echo $NEW_IP > $CRT_IPF
  echo "*****IPアドレスの更新*****" >> $temp
  wget -q -O - 'http://free.ddo.jp/dnsupdate.php?dn=XXXX&pw=XXXX' | nkf -s > $temp
  /bin/bash /etc/cron.hourly/awstats
  cp $awstats $awstats.old
  sed -e "s/$CRT_IP/$NEW_IP/g" $awstats > $dummy
  cp $dummy $awstats
  php /root/program/rm_htmltag.php
 endif

1行目:CRT_IPFのファイルが存在したら以下を実行
2行目:ファイルCRT_IPF内を検索して旧IPアドレスを取得
3行目:CRT_IPF内の旧IPアドレスと新IPアドレスを比較し、それが異なっていれば次を実行
4行目:新IPアドレスをCRT_IPFに保存
6行目:IPアドレスの変更をDDNSに報告し、その結果をshift-jisに変換して一時ファイルに保存-プロバイダーによってこの部分は違ってくると思いますので適宜変更してください。この設定は、ddo.jpの無料設定です。dnにはユーザー名、pwの後にはパスワードを記入のこと。
7行目:ここからAwstatsのconfファイルの処理。まず、IPアドレスを変更する前に、前IPアドレスで解析を行っておく。さもないと、次の自動更新の際に旧IPアドレスがカウントされてしまう。
8行目:Awstatsの既存confファイルを退避させる
9行目:confファイル内の旧IPアドレスを検索して見付かったら、新IPアドレスに変換し、Dummyファイルに保存する
10行目:ダミーファイルの内容をconfファイルにコピーする
11行目:ログ整形プログラムを起動
(注):sedコマンドで保存先を直接$awstatsにすると制御ファイルが空になってしまうので、一旦ダミーファイルに保存して後にコピーするようにしてください。

else
 echo $NEW_IP > $CRT_IPF
 echo "*****定期確認*****" >> $temp
 wget -q -O - 'http://free.ddo.jp/dnsupdate.php?dn=XXXX&pw=XXXX' | nkf -s > $temp
 php /root/program/rm_htmltag.php
endif

1行目:CRT_IPFのファイルが存在しなかったら以下を実行
2行目:新IPアドレスをCRT_IPFに保存
4行目:既存のIPアドレスをDDNSに報告し、その結果をshift-jisに変換して一時ファイルに保存(dnにはユーザー名、pwの後にはパスワードを記入)
5行目:ログ整形プログラムを起動
6行目:条件ネストを終了

sleep 300
end

1行目:300秒休止
2行目:ループの終了=先頭に戻る

以下は、整形プログラム(rm_htmltag.php)の説明です(簡単なプログラムなので、コメントを読めば解かると思います)。

<?php
//ログファイルと一時ファイルのパス
$temp="/root/temp/ddns.tmp";
$log="/var/log/ddns.log";
//tempファイルを開いてデータを読み込みながら、タグを削除する
$save=array();
if (! $fp = @fopen("$temp", "r")){
 print "Could not open file<BR>";
 exit();
 }
while(! feof($fp)){
  $data=fgets($fp);
 if (!ereg("^<",$data) && $data != "\n"){
  $data=str_replace("<br>","",$data);
  array_push($save,$data);
  }
}
fclose($fp);
//logファイルを開いてデータを書き込む
if (! $fp = @fopen("$log", "a")){
  print "Could not open file<BR>";
  exit();
}
foreach ($save as $data){
  fwrite($fp,$data);
}
fclose($fp);
?>

関連記事



コメントを残す




空欄に計算式を満たす数値を記入してください(必須)