my Top page| ドジ話の目次| 前のドジ話次のドジ話

Dynamic DNS の自動接続・自動更新

  2001年3月20日(火)

 フレッツISDN(変動 IP address) 環境で Dynamic DNS を利用して 自宅 
Server を立ち上げたのは良かったのですが、運用過程で、困ることに気づ
きました。
 それは、ISP や NTT 側又はルーター側に問題があって、接続が中断する
ことです。また、中断後再接続しても IP address が変わらないという保証
はどこにも無いということです。それに気づいて更新するまで、誰も Server
にアクセス出来ません。取りあえず毎朝更新はしていますが、その直後に現象
が起きたら、帰宅するまでどうしようもありません。(外部からのリモートは
禁止しています。) 
 まあ、それでも "最悪半日間で済むから良いか" と思っていました。
 ところが、旅行することになり、この前提が崩れてしまいました。何とか 
"自動接続更新" の方法を考えないといけない状態に追い込まれました。
 それで、今日1日潰して自動接続自動更新を設定しました。

【参考】
http://www3.plala.or.jp/YMMT/      (作者の希望によりアドレス変更:2001/03/21)
http://www8.freeweb.ne.jp/computer/kkon/



【自動変更script dynto.pl】

--------- /root/dynto.pl ---------------------------------
#!/usr/bin/perl
#---------------------------------------------------------------
# http://www3.plala.or.jp/YMMT/
# Rta52i IPAddress Update Script Ver1.00 
# Rta52i用 IPアドレス 自動更新用 Script Ver1.00  UpDate2001.01.09
#-------------------------------------------------------------

print "________ Script Start _______\n";

# 下の4行は、私が独自に変更した部分です。
# この script を /etc/crontabに
# */15 * * * * root /root/perl dynto.pl >/dev/null
# と記述して実行させる。
system("nslookup akiyama.dyn.to >/dev/null");

# ルーター RTA-52i にログインする
use Net::Telnet ();

my($lines,$t,$pass,$rthost);

$rthost = 'rta52i';
# rta52i は BIND 又は hosts に登録する。
$pass = 'xxxxxxxx';
# xxxxxxxx は 実際のものを記述。

$t = new Net::Telnet (-host => "$rthost");

## Wait for first prompt 
$t->waitfor('/Password:.*$/');
$t->print("$pass");
$t->waitfor('/>.*$/');
$t->print("show status pp 3");
# pp 3 の 3 は、自分のルーターと交信して確認する。
# 確認方法は、この script を参考にしてください。
($lines) = $t->waitfor('/>.*$/');

open (INPUT,"ip.txt");
# ip.txt は touch ip.txt として事前に作っておく必要あり。
$OldIP = <INPUT>;
print ">> OLD_IP = $OldIP <<\n";

foreach($lines){
if(/ PP IP Address Local:/)
        {
#         $NewIP = substr($',1,length($') - 40);
# この数字40の部分は試行で設定しないといけない。また、IP の文字数に
# 変化があった場合、問題有り。確実に IP を取得する方法は今のところ??。
# その後、上記の行をコメントし、次の2行を追加することで、確実に IP を取得できた。
         $position = index($',",");
 	 $NewIP = substr($',1,$position - 1);
         print ">> NEW_IP = $NewIP <<\n";
         if($OldIP eq $NewIP)
              {
               print " ** IP Address Not Change **\n";
               $t->close;
               print " => Connection Close\n";
               print "________ Script End _______\n\n";
               exit;
              }
         else{
               open(OUTPUT,">ip.txt");
               print OUTPUT $NewIP;
               close OUTPUT;
               print " => IP Change DNS Check !!\n";
               $t->close;
               print " => Connection Close\n";
             }
        }
}


#-------------------------------------------------------------------
# dyn.to Jjido Settei Script v0.1
# (C) KK.Kon
# http://www8.freeweb.ne.jp/computer/kkon/
#-------------------------------------------------------------------

# Create a user agent object 

#$AgentName = "";
#$AgentName = "Mozilla/4.0 (compatible; MSIE 5.01; Windows 98)";
#$AgentName = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
$AgentName = "Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)";
#$AgentName = "Mozilla/4.04 [ja] (Win95; I ;Nav)";
#$AgentName = "Mozilla/4.6 [ja] (Win95; I)";
#$AgentName = "Mozilla/4.7 [en] (Win98; I)"; 

# dyn.to UserName And Passwd

#$UserName = "xxxxxxxx";
# xxxxxxxx は 実際のものを記述。
#$Password = "xxxxxxxx"; 
# xxxxxxxx は 実際のものを記述。
$CGIparm = "command=Update&IP=$NewIP&MX=1";

use LWP::UserAgent;
use LWP::Debug;
# 次の行をコメントアウトすると、LWP の実行結果が
表示される。設定作業時以外は不要。
#LWP::Debug::level('+');

$ua = new LWP::UserAgent;
$ua->agent($AgentName);

# Create a request

my $req = new HTTP::Request
(GET => "http://${UserName}:${Password}\@" .
"cgi.dyn.to/cgi-bin/members/dyndns?" .
"${CGIparm}");

# Pass request to the user agent and get a response back
my $res = $ua->request($req);

# Check the outcome of the response
if ($res->is_success)
     {
       print "=== IP Address Change Normal End ===\n";
       print "________ Script End _______\n\n";
       exit 0;
     }
else {
       print $res->content;
       print "=== IP Address Change AbNormal END ===\n";
       print "________ Script End _______\n\n";
       exit 1;
     }
----------- /root/dynto.pl (END) ------------------------------- 


【手動実行結果】

(初回の実行結果)

# perl dynto.pl
________ Script Start _______

host/domain
Server:  ******.**.****.ad.jp
Address:  ***.***.***.***

Non-authoritative answer:
Name:    akiyama.dyn.to
Address:  ***.***.***.***

>> OLD_IP =  <<
>> NEW_IP = ***.***.***.*** <<
 => IP Change DNS Check !!
 => Connection Close

            ・
            ・
            ・
<html>
<head><title>dyn.to -- Dynamic DNS Service --</title>
<!-- 顰蹙とかいてIE3の文字化けを抑制する -->
</head>
<body>
<pre></pre>
DNSの更新に成功しました。<br>
MXの更新に成功しました。<br>
<HR>
<A HREF="/members/">Return</A>
<!-- dyndns status: Ok -->
<!-- dyndns MX: Ok -->
</BODY></HTML>
LWP::Protocol::http::request: HTTP/1.1 200 OK
LWP::Protocol::collect: read 297 bytes
LWP::UserAgent::request: Simple response: OK
=== IP Address Change Normal End ===
________ Script End _______

# 

(2回目の実行結果)

# perl dynto.pl
________ Script Start _______

Server:  meshsv62.os.mesh.ad.jp
Address:  ***.***.***.***

Non-authoritative answer:
Name:    akiyama.dyn.to
Address:  ***.***.***.***

>> OLD_IP = ***.***.***.*** <<
>> NEW_IP = ***.***.***.*** <<
 ** IP Address Not Change **
 => Connection Close
________ Script End _______

# 
-------------- 追加 --------------------------------
【追加変更後の結果】

#         $NewIP = substr($',1,length($') - 40);
# この数字40の部分は試行で設定しないといけない。また、IP の文字数に
# 変化があった場合、問題有り。確実に IP を取得する方法は今のところ??。
# その後、上記の行をコメントし、次の2行を追加することで、確実に IP を取得できた。
         $position = index($',",");
 	 $NewIP = substr($',1,$position - 1);

# perl dynto.pl
________ Script Start _______
>> OLD_IP = 211.13.47.155 <<
>> NEW_IP = 211.13.47.155 <<
 ** IP Address Not Change **
 => Connection Close
________ Script End _______

# 

と、確実に取得できた。

-------------- END 追加 --------------------------------


IP address の取得結果は、

# cat ip.txt 
***.***.***.***
#

と、手動では無事 Dynamic DNS の更新が出来ることが確認できた。
あとは、自動実行させるだけ。

【自動実行の設定】
それには次のように、/etc/crontab に次の行を追加。

-------  /etc/crontab ------------------ 

# Flet's ISDN keep connect and change IP for Dynamic DNS
*/10 * * * * root /root/perl dynto.pl >/dev/null 

----------------- /etc/crontab (END) --------------

# /etc/rc.d/init.d/crond status
crond (pid 345) is running...
# kill -HUP 345

と、crond を再スタートさせれば、後は自動実行される。

(実行結果 /var/log/cron )
root (03/21-00:00:00-28279) CMD (/root/perl dynto.pl >/dev/null )
root (03/21-00:10:00-28290) CMD (/root/perl dynto.pl >/dev/null )
root (03/21-00:20:00-28301) CMD (/root/perl dynto.pl >/dev/null )
root (03/21-00:30:00-28314) CMD (/root/perl dynto.pl >/dev/null )

と確かに実行されている。


【dynto.pl についてのの補足】


dynto.pl を実行させるためには、次のような perl module が必要に
なります。(LWP が必要)
取得も、インストールも次の様に簡単です。

        ftp://ftp.funet.fi/pub/languages/perl/CPAN/

などから、

       MIME-Base64-2.12.tar.gz
       URI-1.11.tar.gz
       HTML-Tagset-3.03.tar.gz
       HTML-Parser-3.19.tar.gz
       libnet-1.0703.tar.gz
       Digest-MD5-2.13.tar.gz
       Net-Telnet-3.02.tar.gz
       libwww-perl-5.51.tar.gz

を取ってきて、上述の順番でインストールします。(依存関係による)

インストール要領は、

# tar xvzf HTML-Tagset-3.03.tar.gz 
HTML-Tagset-3.03/
HTML-Tagset-3.03/Makefile.PL
HTML-Tagset-3.03/ChangeLog
HTML-Tagset-3.03/test.pl
HTML-Tagset-3.03/Tagset.pm
HTML-Tagset-3.03/README
HTML-Tagset-3.03/MANIFEST
# cd HTML-Tagset-3.03
# ls
ChangeLog  MANIFEST  Makefile.PL  README  Tagset.pm  test.pl
# less README 

You install HTML::Tagset, as you would install any perl module
library, by running these commands:

   perl Makefile.PL
   make
   make test
   make install


# perl Makefile.PL 
Checking if your kit is complete...
Looks good
Writing Makefile for HTML::Tagset

# make
mkdir blib
mkdir blib/lib
mkdir blib/lib/HTML
mkdir blib/arch
mkdir blib/arch/auto
mkdir blib/arch/auto/HTML
mkdir blib/arch/auto/HTML/Tagset
mkdir blib/lib/auto
mkdir blib/lib/auto/HTML
mkdir blib/lib/auto/HTML/Tagset
mkdir blib/man3
cp Tagset.pm blib/lib/HTML/Tagset.pm
Manifying blib/man3/HTML::Tagset.3

# make test
PERL_DL_NONLAZY=1 /usr/bin/perl -Iblib/arch -Iblib/lib -I/usr/lib/perl5/5.00503/i386-linux -I/usr/lib/perl5/5.00503 test.pl
1..1
ok 1

# make install
Installing /usr/lib/perl5/site_perl/5.005/HTML/Tagset.pm
Installing /usr/lib/perl5/man/man3/HTML::Tagset.3
Writing /usr/lib/perl5/site_perl/5.005/i386-linux/auto/HTML/Tagset/.packlist
Appending installation info to /usr/lib/perl5/5.00503/i386-linux/perllocal.pod
# 

とこんな感じで簡単です。



my Top page| ドジ話の目次| 前のドジ話次のドジ話