自宅Serverを公開 - IP変更時の対応

Last Modified: 2004.02.18

11. IP変更時の対応
固定IPではないので、IPアドレスが変更された場合はDNS2Goの情報をUpdateする必要がある。
DNS2GoのDownloadサイトからLinux用ツールを入手し、 インストール後実行する。
このツールは、常駐してIPアドレスの変更を監視し続ける。

自動起動するように、/etc/rc.d/rc.localファイルの最後に、以下を追加した。

 /usr/local/bin/dns2go &

12. Megabit GearからIPアドレスを読み出す方法
Megabit Gear TE4100からGlobal IP Addressを読み込むPerlスクリプトを作成した (TE4121Cでも動作するようです)。
cron(root)で10分毎に動作させ、IPアドレスの監視を行っている(過去のIPアドレスに変更履歴はここをクリック)。

DNS2Goのツールがたまに変な動きをするので、pingの結果とADSL RouterのIPアドレスが異なっている場合は、DNS2Goのツールを再起動している。
  • Megabit Gear TE4100専用(Megabit Gear TE4100が書き出すHtmlを読んでいるため)。
  • ひとまず動いていますが、私はPerlに余り詳しくないので参考程度にして下さい。
  • /var/log/adslip.logにログファイルを書き出しているので、rootでないと動作しません。

 #!/usr/bin/perl


 use Socket;
 use FileHandle;


 # ユーザ名等の設定(この部分を自分の設定に合わせて下さい)
 $adsl_user   = "ADSL Routerにブラウザでアクセスするときのユーザ名";
 $adsl_passwd = "ADSL Routerのパスワード";
 $adsl_host   = "ADSL RouterのIPアドレス";
 $mydomain    = "自分のドメイン";

 # ADSLのIPを取得するための情報(ROMのバージョンが違う場合等はここをチェックして下さい)
 $adsl_url    = "/cgi-bin/main.cgi?cc_webname=STATUS";
 $adsl_key_s  = "<TR><TD NOWARP>ADSL IP</TD><TD NOWARP>:";
 $adsl_key_e  = "</TD>";

 # その他の変数
 $logfile     = "/var/log/adslip.log";
 $adsl_port   = getservbyname('http','tcp');
 $adsl_auth   = &base64en("$adsl_user:$adsl_passwd");


 # ソケットの生成
 $ip = inet_aton($adsl_host) || die "Host($adsl_host) not found.\n";
 $sockaddr = pack_sockaddr_in($adsl_port, $ip);
 socket(SOCKET, PF_INET, SOCK_STREAM, 0) || die "Socket error.\n";


 # ソケットの接続
 connect(SOCKET, $sockaddr) || die "Connect $adsl_host $adsl_port error.\n";
 SOCKET->autoflush(1);

 # リクエスト送信
 print SOCKET "GET http://$adsl_host$adsl_url HTTP/1.0\n";
 print SOCKET "Authorization: Basic $adsl_auth\n\n";

 # HTTP応答を受信
 while( chomp($buf=<SOCKET>) )
 {
 	$pos = index($buf,$adsl_key_s);
	if( $pos >= 0 )
	{
		$new_adslip = substr($buf,length($adsl_key_s),index($buf,$adsl_key_e,length($adsl_key_s))
			- length($adsl_key_s));
	}
 }

 # Socketを閉じる
 close(SOCKET);

 # 以前のADSL IPをlogileから読み込む
 open(FH, "$logfile");
 while( $buf = <FH> )
 {
 	$old_adslip = substr($buf, 20, length($buf) - 21);
 }
 close(FH);

 # ADSL IPが変わっていた時の処理 
 if( $new_adslip ne $old_adslip )
 {
 #	ここに実行したいコマンドを記述

	($sec, $min, $hour, $mday, $mon, $year) = localtime(time());
	$year += 1900;
	$mon  += 1;
	$buf = sprintf("%04d/%02d/%02d %02d:%02d:%02d %s\n",$year,$mon,$mday,$hour,$min,$sec,$new_adslip);
	open(FH, ">> $logfile");
	print FH $buf;
	close(FH);
 }

 # pingの結果を調査し、万一ADSLのIPと異なる場合はdns2goを再起動
 open(FH, "/bin/ping -c1 -q $mydomain |");
 while( $buf=<FH>)
 {
	@pings = split(/ /,$buf);
	$pingip = substr($pings[2],1,length($pings[2])-2);
	last;
 }
 close(FH);
 if( $new_adslip ne $pingip )
 {
 	system("/usr/local/bin/dns2go -k");
 	system("/usr/local/bin/dns2go");
 }


 # Subroutines
 sub e_base64_table
 {
	%e_base64 = ( '000000','A','000001','B','000010','C','000011','D'
	,'000100','E','000101','F','000110','G','000111','H','001000','I'
	,'001001','J','001010','K','001011','L','001100','M','001101','N'
	,'001110','O','001111','P','010000','Q','010001','R','010010','S'
	,'010011','T','010100','U','010101','V','010110','W','010111','X'
	,'011000','Y','011001','Z','011010','a','011011','b','011100','c'
	,'011101','d','011110','e','011111','f','100000','g','100001','h'
	,'100010','i','100011','j','100100','k','100101','l','100110','m'
	,'100111','n','101000','o','101001','p','101010','q','101011','r'
	,'101100','s','101101','t','101110','u','101111','v','110000','w'
	,'110001','x','110010','y','110011','z','110100','0','110101','1'
	,'110110','2','110111','3','111000','4','111001','5','111010','6'
	,'111011','7','111100','8','111101','9','111110','+','111111','/');
 }

 sub base64en
 {
	&e_base64_table unless %e_base64;
	my $str = $_[0];
	my $tmp = "";
	$str  = unpack("B*",$str);
	$tmp  = length($str) % 6;
	$str .= '0' x (6 - $tmp) if ($tmp);
	$str  =~ s/(......)/$e_base64{$1}/g;
	$tmp  = length($str) % 4;
	$str .= '=' x (4 - $tmp) if ($tmp);
	return $str;
 }


<Prev Top Next>
Copyright(C) 2001-2003 Katsuyuki Kobayashi.
このサイトへのリンクや引用時はメール頂戴
webmaster@kkoba.com