ルーターにDD-WRTを入れました。WZR-HP-AG300Hに米Buffalo謹製のProfessional Firmwareです。ルーター自身でMyDNS.jpを更新させるただそれだけのために。
ちなみに無線LANは社外ファームでは法令に触れるので使ってはダメだとか。送信出力を10dBmにすると同等らしいですが、法律がそうなっているとかで。
さてMyDNS更新ですが、先人の知恵により、サービス名を手動設定にした上でURLに"/login.html?"と記述すれば通りました。
ところがRC_IP_CONNECT_FAILEDが発生してダメになる場合がありました。色々調べていくと、どうもWAN IPアドレスの確認に失敗した場合のエラーメッセージのようでした。
DDNSクライアントinadynはデフォルトでcheckip.dyndns.org使っていました。これはリモートホストのIPアドレスを表示するだけのサービスで、DDNS更新のために用意されている物のようです。DynDNS以外で使われるのは迷惑だろうになあ、と思わなくもありません。
一つのホスト名に複数のIPアドレスが割り当てられている(DNSラウンドロビンとか呼ぶらしい)のですが、inadynは立ち上がるとDNSを一度しか引かないため、落ちていても余所に回りません。こうして接続できない場合にRC_IP_CONNECT_FAILEDが記録されます。
inadynを更新すれば回避できるらしいですが、せっかく米Buffaloが動作確認してくれたバージョンからずらすのも嫌ですし、inadynだけ更新も怖いので、外から何とかすることにしました。
そもそもルーター自身がWAN IPアドレスを把握しているのに、わざわざ外のCGIに調べてもらうなんておかしいだルルォ!?
というわけで、設定画面のInfo.htmからPerlでWANのIPアドレスを取り出して表示するcgiを設置しました。Perlなんて自分で書くのは初めてですが、こんな感じ(後述)で良いのでしょうか。
後は、これをDDNS設定画面の追加オプションで
--ip_server_name サーバーのLAN IPアドレス cgiへの絶対パス
とすればWAN IPアドレスの確認に使ってくれます。詳細はDD-WRT公式のこちらを。
DD-WRTにPerlを入れてしまえば1台で完結できますが、今のところはこのWebサーバーに設置しています。ルーターで完結していませんが、WAN IP確認はローカルで行なわなければならないものでもないので、おまけです。
クラスCプライベートIPアドレスを判別して上記仕組みを動作させ、それ以外なら相手のリモートIPアドレスを表示します(つまりcheckip.dyndns.org等と同じ動作)。
#!/usr/bin/perl
use utf8;
use LWP::UserAgent;
use HTML::TreeBuilder;
print "Content-type: text/plain\n\n";
my $ip = $ENV{'REMOTE_ADDR'};
if ($ip =~ /^(192\.168)/) {
my $ua = LWP::UserAgent->new;
my $req = HTTP::Request->new(GET => 'http://ルーターのLAN IPアドレス/Info.htm');
$req->authorization_basic('ユーザー', 'パスワード');
my $res = $ua->request($req);
if ($res->is_success) {
$tree = HTML::TreeBuilder->new;
$tree->parse($res->content);
$tree->eof();
my $ipaddr = $tree->look_down(_tag => "span", id => "wan_ipaddr")->as_text;
print $ipaddr, "\n";
} else {
print "ERROR.\n";
print $res->status_line, "\n";
}
} else {
print $ip, "\n";
}
RC_IP_CONNECT_FAILED
トラックバック(0)
トラックバックURL: https://mychro.mydns.jp/cgi-bin/mt/mt-tb.cgi/392
コメントする