Ipcheck

提供: Wikinote
移動: 案内検索

hagio.org の IP アドレスを自動的に更新するツール。

概要

うちのネットワーク環境は、フレッツ光による PPPoE 接続+VALUE-DOMAIN によるドメインである。 たまに接続が切断されて IP アドレスが変わってしまうので、これを自動で更新できるようにする。 VALUE-DOMAIN は HTTP アクセスによる IP アドレスの更新が可能なので、これを利用する。

シェルスクリプトで実装し、cron で動かすことにする。

ipaddr コマンド

まずは、後々のために現在の IP アドレスを出力するコマンド ipaddr を作る。 ifconfig ppp0 から IP アドレスを切り出すことにしよう。

[hagio@lab ~]$ ifconfig ppp0
ppp0      Link encap:Point-to-Point Protocol  
          inet addr:203.212.48.216★ P-t-P:202.224.37.130  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1454  Metric:1
          RX packets:419348 errors:0 dropped:0 overruns:0 frame:0
          TX packets:226329 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3 
          RX bytes:533010019 (508.3 MiB)  TX bytes:25575899 (24.3 MiB)

これ(★)を切り出せばよい。

[hagio@lab ~]$ cat ipaddr 
#!/bin/bash
#
# ipaddr : print the current IP address
#

addrs=$(/sbin/ifconfig ppp0 | egrep -o '([[:digit:]]{1,3}\.){3}[[:digit:]]{1,3}')
# I can't head above because I use egrep's exit status.

if [ $? -eq 0 ]; then
    echo "$addrs" | head -n 1
    exit 0
else
    exit 1
fi
[hagio@lab ~]$ ./ipaddr
203.212.48.216

update-domain コマンド

次に、IP アドレスを更新するコマンド update-domain を作る。 先ほど作成した ipaddr コマンドの出力を利用する。

[hagio@lab ~]$ cat update-domain
#!/bin/bash
#
# update-domain : update dynamic DNS information
#

IPADDR=$(/path/to/ipaddr)
if [ $? -ne 0 ]; then
    exit 1
fi

/usr/bin/curl "http://dynamic.name-services.com/interface.asp?Command=SetDNSHost&HostName=@&Zone=ドメイン名&DomainPassword=パスワード&Address=$IPADDR"
if [ $? -ne 0 ]; then
    exit 1
fi
exit 0

実行してみる。curl の出力は /dev/null に捨てるべきか?

[hagio@lab ~]$ update-domain
;URL Interface<br>
;Machine is Reseller7-SJL<br>
IP=203.212.48.216
Command=SETDNSHOST
Language=eng
ErrCount=0
ResponseCount=0
MinPeriod=1
MaxPeriod=10
Server=Reseller7-SJL
Site=eNom
IsLockable=True
IsRealTimeTLD=True
TimeDifference=+07.00
ExecTime=0.047
Done=true

ipcheck コマンド

前回実行時と現在の IP アドレスが異なっていれば、DNS サーバの HTTP インタフェースに変更を伝えるようにする。

ipcheck コマンドと同じディレクトリに、前回実行時の IP アドレスを prev_ip というファイル名で書き込むことにしよう。

[hagio@lab ~]$ cat ipcheck
#!/bin/bash
#
# ipcheck : check IP address and update dynamic DNS information
#

LOGGER='/usr/bin/logger -t ipcheck'
BASEDIR=${0%/*}
cd $BASEDIR

IPADDR=$(/path/to/ipaddr)
if [ $? -ne 0 ]; then
    $LOGGER "Error: No IP address" 
    > prev_ip # clear previous IP address
    exit 1
fi

PREV_IP=''
if [ -f prev_ip ]; then
    PREV_IP=$(< prev_ip)
fi

if [ $IPADDR != $PREV_IP ]; then
    echo $IPADDR > prev_ip # save current IP address
    $LOGGER "Send current IP address: $IPADDR"
    $LOGGER "$(/path/to/update-domain 2> /dev/null | tr '\r' '\n')"

    date # for logging
    # restart ntpd service
    /etc/init.d/ntpd status
    if [ $? -eq 0 ]; then
       /etc/init.d/ntpd restart
    fi  
fi

これを crontab に登録する。

[hagio@lab ~]$ crontab -e
0 * * * * /path/to/ipcheck >> /path/to/logfile 2>&1

エラー処理をほとんど行っていないので、考える必要がある。

待ちわびていたエラーが発生したので、エラー処理を施した。

動作時のログ

施した改良がうまく動いていたので記録しておく。

★何らかの原因で eth1 (= ppp0) がリンクダウン
May 25 23:31:45 lab kernel: r8169: eth1: link down
May 25 23:31:47 lab kernel: r8169: eth1: link up
★リンクダウンの影響か、echo が返らなくなり、切断される。
May 25 23:32:39 lab pppd[9098]: No response to 3 echo-requests
May 25 23:32:39 lab pppd[9098]: Serial link appears to be disconnected.
May 25 23:32:39 lab pppd[9098]: Connect time 7226.3 minutes.
May 25 23:32:39 lab pppd[9098]: Sent 104003535 bytes, received 591067683 bytes.
May 25 23:32:39 lab pppd[9098]: Connection terminated.
May 25 23:32:39 lab NET[22935]: /etc/sysconfig/network-scripts/ifdown-post : updated /etc/resolv.conf
May 25 23:32:39 lab pppd[9098]: Exit.
★再接続が行われる。
May 25 23:32:39 lab adsl-connect: ADSL connection lost; attempting re-connection.
May 25 23:32:44 lab pppd[22948]: Plugin /usr/lib/pppd/2.4.4/rp-pppoe.so loaded.
May 25 23:32:44 lab pppd[22948]: RP-PPPoE plugin version 3.3 compiled against pppd 2.4.4
May 25 23:32:44 lab pppd[22948]: pppd 2.4.4 started by root, uid 0
May 25 23:32:44 lab pppd[22948]: PPP session is 30787
May 25 23:32:44 lab pppd[22948]: Using interface ppp0
May 25 23:32:44 lab pppd[22948]: Connect: ppp0 <--> eth1
May 25 23:32:44 lab pppd[22948]: PAP authentication succeeded
May 25 23:32:44 lab pppd[22948]: peer from calling number 00:12:44:5A:1C:1D authorized
May 25 23:32:44 lab pppd[22948]: local  IP address 122.249.77.250
May 25 23:32:44 lab pppd[22948]: remote IP address 202.224.37.114
May 25 23:32:44 lab pppd[22948]: primary   DNS address 202.224.32.1
May 25 23:32:44 lab pppd[22948]: secondary DNS address 202.224.32.2
May 25 23:32:44 lab NET[22996]: /etc/sysconfig/network-scripts/ifup-post : updated /etc/resolv.conf
★接続に成功するも、ntpd がおかしくなってしまうようだ。
May 25 23:35:53 lab ntpd[9399]: sendto(192.218.230.58) (fd=21): Invalid argument
May 25 23:39:03 lab ddclient[5640]: SUCCESS:  updating hagio.dyndns.org: good: IP address set to 122.249.77.250
May 25 23:40:34 lab ntpd[9399]: sendto(202.224.32.4) (fd=21): Invalid argument
May 25 23:52:56 lab ntpd[9399]: sendto(192.218.230.58) (fd=21): Invalid argument
★以降、ntpd のエラーは出力され続けてしまう。

再接続が行われた場合は、ntpd がおかしくなるようなので、ntpd も再起動するように修正しよう。 以下は、ipcheck のログである。messages に出力するようにしてもいいかもなあ。

Mon May 25 22:00:01 JST 2009 ipcheck: No change: 118.243.237.150
Mon May 25 23:00:01 JST 2009 ipcheck: No change: 118.243.237.150
Tue May 26 00:00:01 JST 2009 ipcheck: Send current IP address: 122.249.77.250
;URL Interface<br>^M
;Machine is Reseller12-SJL<br>^M
IP=122.249.77.250^M
Command=SETDNSHOST^M
Language=eng^M
ErrCount=0^M
ResponseCount=0^M
MinPeriod=1^M
MaxPeriod=10^M
Server=Reseller12-SJL^M
Site=eNom^M
IsLockable=True^M
IsRealTimeTLD=True^M
TimeDifference=+07.00^M
ExecTime=11.125^M
Done=true^M
Tue May 26 01:00:01 JST 2009 ipcheck: No change: 122.249.77.250
Tue May 26 02:00:01 JST 2009 ipcheck: No change: 122.249.77.250