INDEX
Dynamic DNS IP更新スクリプト
今は亡き ieServer.Net のダイナミックDNSのIPアドレスの自動更新スクリプトです。
ルータの設定画面から、グローバルIPアドレスを取得して、変わっていた場合に、DDNSの更新要求を行う。動作ログを syslog に記録する。また、変更を行った際に、Twitter のダイレクトメッセージを送る。
対応するルータは、OMRON MR504DV と NTT RV-S340SE、SoftBank E-WMTA2.3 。まぁ、ieServer.Net の回線IP確認ページからも取得できるのですが。
1 |
#!/usr/bin/perl
##### Character-code is UTF-8. Tab-size is 4 space character. #####
###############################################################################
## ieServer.Net update Script - Ver.0.00 (2020/01/28) ##
###############################################################################
use strict; # restrict unsafe constructs
use warnings; # control optional warnings ( as /usr/bin/perl -w )
use utf8;
use Sys::Syslog qw(openlog syslog closelog LOG_DEBUG LOG_INFO LOG_NOTICE LOG_WARNING LOG_ERR LOG_CRIT LOG_ALERT LOG_EMERG);
use LWP::UserAgent;
use LWP::Protocol::https; # https
use Storable qw(nstore retrieve);
# ieServer.Net アカウント(サブドメイン)情報
my $ACCOUNT = "account"; # アカウント(サブドメイン)名
my $DOMAIN = "example.com"; # ドメイン名
my $PASSWORD = "password"; # パスワード
# 設定されてるIPアドレスのローカル保存
my $CURRENT_FILE = __FILE__ . '.dat';
# WEBアクセス時の USER_AGENT
my $USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0';
# DDNS更新ページURL
my $UPDATE_DDNS_URL = "https://ieserver.net/cgi-bin/dip.cgi";
# 回線IP確認ページURL
my $CHECK_IPADD_URL = "https://ieserver.net/ipcheck.shtml";
# OMRON MR504DV の PPPoE 接続状況 / WAN状況 から取得
my $MR504DV_ROUTERIP = undef; #"192.168.65.1";
my $MR504DV_USERNAME = "admin"; # ユーザ名
my $MR504DV_PASSWORD = "pass"; # パスワード
my $MR504DV_PPPOE_URL = $MR504DV_ROUTERIP ? 'http://' . $MR504DV_ROUTERIP . '/disconnect_pppoe.htm' : undef;
my $MR504DV_WAN_URL = $MR504DV_ROUTERIP ? 'http://' . $MR504DV_ROUTERIP . '/show_wan.htm' : undef;
# NTT RV-S340SE の 現在の状態 から取得
my $RVS340SE_ROUTERIP = undef; #"192.168.65.1";
my $RVS340SE_USERNAME = "user"; # ユーザ名
my $RVS340SE_PASSWORD = "pass"; # パスワード
my $RVS340SE_STATUS_URL = $RVS340SE_ROUTERIP ? 'http://' . $RVS340SE_ROUTERIP . '/cgi-bin/main.cgi?mbg_webname=status' : undef;
# SoftBank E-WMTA2.3 の 設定情報一覧 から取得
my $SoftBank_ROUTERIP = undef; #"192.168.3.1";
my $SoftBank_USERNAME = "user"; # ユーザ名
my $SoftBank_PASSWORD = "pass"; # パスワード
my $SoftBank_STATUS_URL = $SoftBank_ROUTERIP ? 'http://' . $SoftBank_ROUTERIP . '/settei.html' : undef;
# Twitter OAuth keys [ test client ]
my $CONSUMER_KEY = 'consumer';
my $CONSUMER_SECRET = 'consumer_secret';
# Twitter OAuth keys [ test client - imatake_secret ]
my $ACCESS_TOKEN = 'access_token';
my $ACCESS_SECRET = 'access_secret';
# Twitter ダイレクトメッセージで通知するか
my $SCREEN_NAME = undef; #'your?screen_name';
########################################
openlog(__FILE__, 'pid,perror', Sys::Syslog::LOG_USER); # pid,perror
##
my $current_ip = &load_current_ip() || '0.0.0.0';
syslog(LOG_DEBUG, 'Current IP addr. ' . $current_ip);
my $remote_ip = &get_remote_ip() || '0.0.0.0';
syslog(LOG_DEBUG, 'Now remote IP addr. ' . $remote_ip);
##
if( $remote_ip eq '0.0.0.0' ){
syslog(LOG_WARNING, 'Cannot get remote IP addr.');
}elsif( $current_ip eq $remote_ip ){
syslog(LOG_DEBUG, 'No dynamic DNS update.');
}else{
my ($host, $ip) = &update_ddns();
if( $ip ){
syslog(LOG_NOTICE, 'Dynamic DNS updated. Remote IP Address=' . $ip . ' HostNama=' . $host);
&save_current_ip($remote_ip);
&update_notification($host, $ip) if($SCREEN_NAME);
}else{
syslog(LOG_WARNING, 'Cannot dynamic DNS update.');
}
}
closelog();
exit;
########################################
sub load_current_ip {
return '0.0.0.0' unless(-f $CURRENT_FILE);
my $ip = ${retrieve($CURRENT_FILE)};
return $ip;
}
sub save_current_ip {
my $ip = shift || return undef;
nstore(\$ip, $CURRENT_FILE);
return $ip;
}
########################################
sub update_ddns {
return undef unless($UPDATE_DDNS_URL);
my $ua = LWP::UserAgent->new;
$ua->agent($USER_AGENT);
$ua->ssl_opts( verify_hostname => 0 ); # ホスト名の検証を無視
#
syslog(LOG_DEBUG , 'Request DDNS update.');
my $res = $ua->post(
$UPDATE_DDNS_URL,
[
'username' => $ACCOUNT,
'password' => $PASSWORD,
'domain' => $DOMAIN,
'updatehost' => '1',
]);
# submit button name. Update 'updatehost' / Offline 'offline'
return undef unless($res->is_success);
syslog(LOG_DEBUG , 'Request DDNS updated.');
my $html = $res->decoded_content();
my ($host, $ip) = (undef, undef);
if( $html =~ /ドメイン名: *([0-9a-zA-Z.]+) *のIPアドレスは現在 *([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+) *に設定されています。/im ){
$host = $1;
$ip = $2;
syslog(LOG_DEBUG , 'DDNS update. host=' . $host . ' ip=' . $ip);
}
return wantarray ? ($host, $ip) : $ip;
}
sub get_remote_ip {
if($MR504DV_ROUTERIP){
my $ip = undef;
$ip = &get_remote_ip_from_mr504dv_wan();
return $ip if($ip);
$ip = &get_remote_ip_from_mr504dv_pppoe();
return $ip if($ip);
}
if($RVS340SE_ROUTERIP){
my $ip = undef;
$ip = &get_remote_ip_from_rvs340se_status();
return $ip if($ip);
}
if($SoftBank_ROUTERIP){
my $ip = undef;
$ip = &get_remote_ip_from_SoftBank_status();
return $ip if($ip);
}
##
return undef unless($CHECK_IPADD_URL);
syslog(LOG_DEBUG , 'Check remote IP address.');
#
my $ua = LWP::UserAgent->new;
$ua->agent($USER_AGENT);
$ua->ssl_opts( verify_hostname => 0 ); # ホスト名の検証を無視
my $res = $ua->get($CHECK_IPADD_URL);
return undef unless($res->is_success);
return $res->content();
}
########################################
sub get_remote_ip_from_SoftBank_status {
return undef unless($SoftBank_STATUS_URL);
my $ua = LWP::UserAgent->new;
$ua->agent($USER_AGENT);
my $req = HTTP::Request->new(GET => $SoftBank_STATUS_URL );
$req->authorization_basic($SoftBank_USERNAME, $SoftBank_PASSWORD);
my $res = $ua->request($req);
return undef unless($res->is_success);
my $html = $res->decoded_content();
my $ip = undef;
if( $html =~ /var WANIP="([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)";/i ){
$ip = $1;
syslog(LOG_DEBUG , 'Remote IP from SoftBank(status). ip=' . $ip);
}
return $ip;
}
sub get_remote_ip_from_rvs340se_status {
return undef unless($RVS340SE_STATUS_URL);
my $ua = LWP::UserAgent->new;
$ua->agent($USER_AGENT);
my $req = HTTP::Request->new(GET => $RVS340SE_STATUS_URL );
$req->authorization_basic($RVS340SE_USERNAME, $RVS340SE_PASSWORD);
my $res = $ua->request($req);
return undef unless($res->is_success);
my $html = $res->decoded_content();
my $ip = undef;
if( $html =~ /<tr[\s\S]*?<td[\s\S]*?WAN側IPアドレス<\/td[\s\S]*?<td.*?>:([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)<\/td[\s\S]*?<\/tr>/i ){
$ip = $1;
syslog(LOG_DEBUG , 'Remote IP from RVS340SE(status). ip=' . $ip);
}
return $ip;
}
sub get_remote_ip_from_mr504dv_pppoe {
return undef unless($MR504DV_PPPOE_URL);
my $ua = LWP::UserAgent->new;
$ua->agent($USER_AGENT);
my $req = HTTP::Request->new(GET => $MR504DV_PPPOE_URL );
$req->authorization_basic($MR504DV_USERNAME, $MR504DV_PASSWORD);
my $res = $ua->request($req);
return undef unless($res->is_success);
my $html = $res->decoded_content();
my $ip = undef;
if( $html =~ /<TR.*><TD.*>割り当てIPアドレス.*<\/TD><TD.*>([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)<\/TD><\/TR>/i ){
$ip = $1;
syslog(LOG_DEBUG , 'Remote IP from MR504DV(PPPoE). ip=' . $ip);
}
return $ip;
}
sub get_remote_ip_from_mr504dv_wan {
return undef unless($MR504DV_WAN_URL);
my $ua = LWP::UserAgent->new;
$ua->agent($USER_AGENT);
my $req = HTTP::Request->new(GET => $MR504DV_WAN_URL );
$req->authorization_basic($MR504DV_USERNAME, $MR504DV_PASSWORD);
my $res = $ua->request($req);
return undef unless($res->is_success);
my $html = $res->decoded_content();
my $ip = undef;
if( $html =~ /<TR.*><TD.*>IPアドレス.*<\/TD><TD.*>([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)<\/TD><\/TR>/i ){
$ip = $1;
syslog(LOG_DEBUG , 'Remote IP from MR504DV(WAN). ip=' . $ip);
}
return $ip ne '0.0.0.0' ? $ip : undef;
}
sub update_notification {
my $host = shift;
my $ip = shift;
eval { use Net::Twitter; };
#
my $twit = Net::Twitter->new(traits => ['API::RESTv1_1', 'OAuth'], ssl => 1,
consumer_key => $CONSUMER_KEY, consumer_secret => $CONSUMER_SECRET, );
$twit->access_token($ACCESS_TOKEN);
$twit->access_token_secret($ACCESS_SECRET);
#
$host =~ s/\./ . /g;
my $status = 'Update Dynamic DNS (ieServer . Net). Remote IP Address=' . $ip . ' HostNama=' . $host;
$twit->new_direct_message({ screen_name => $SCREEN_NAME, text => $status });
}
###############################################################################
## End Of File (ddns-update.pl) ##
############################################################################### |
最終更新時間:2022年01月25日 23時40分22秒 指摘や意見などあればSandBoxのBBSへ。
ddns-update.pl