MENU
カテゴリー
アーカイブ

Python3でアドレス自動通知(旧)

最新版はこちらの記事

MyDNS.JPのサイトには、crontabで定期的に通知する方法が丁寧に書いてある。

説明では5分間隔で通知するようになっているけど、頻繁にアドレスが変更されるような環境ならともかく、アドレスに変更があったときに通知すればいいので見直すことにした。

ただし、MyDNSのDNS情報生成期間は約1週間ということなので、最低でも週一で通知しないといけない。
ちなみに、1ヶ月以上ログインや通知が無いと登録データそのものが無くなる。

ということで、

  • 10分ごとにアドレスをチェックして、変更があれば通知する。
  • アドレスに変更が無くても1日に1回は通知する。

に変更する。5分毎にIPアドレスを確認しても良いけど、そんなに頻繁にアドレスが変更されることは無いから気分的に10分としてみた。

・・・DiCE for Linuxで良いじゃん!

そのとおりです、ハイ。
でも、そこは趣味で自鯖を運用しているのと動機は同じなので気にしない。

とはいうものの、自身はプログラマーでも何でもないからゼロから作るのも大変。なので既にWebで公開されているものを利用させてもらうことにした。

目次

準備

こちらの自鯖サイトにieServer用のIPアドレス更新スクリプト(Python版)が公開されている。

当たり前だけどieServer用で正常に更新できるので利用させてもらい、MyDNS用に、かつPython3化してみる。
感謝!

修正

Python2からテキストの扱いが大きく変わったらしい。この辺りに注意して少しずつ確認しながら修正する。

自鯖環境によるが、自分の場合(ubuntu18.04)はPython3が入っているものの、'~$python --version'で確認すると2.7.17になっていた。
/usr/bin/pythonのシンボリックを変更してシステム全体をPython3に変更するのはリスクが大きいから、このスクリプトだけ明示的にPython3で動作させることにした。
要はスクリプトの1行目を #!/usr/bin/python3 にするだけ。

あと、オリジナルのスクリプトは毎日定時に強制通知する設定になっている。これでもいいけど、例えば「2時」に強制通知するとして、「10分毎にアドレス変更を確認、変更があれば通知する」に設定していると、2時10分、2時20分、2時30分・・・というように2時の間は毎回通知することになる。
なので今回は、毎日定時の強制通知は別のcronで実行することにして、単純に(例えば)10分毎の確認(アドレスに変更があれば通知)だけ、cronで以下のスクリプトを実行することに修正した。
Python3のスクリプトを保存するときの文字コードはutf-8で!

#!/usr/bin/python3

import subprocess
import os
import codecs
from datetime import datetime


MYPATH = "/usr/local/sbin/mydns/"         #このpythonスクリプトの配置場所
MASTER_ID = "mydns999999"                 #マスターID
PWD = "aaaaaaaaaaa"                       #パスワード


REMOTE_ADDR_CHK = "http://ieserver.net/ipcheck.shtml"
DDNS_UPDATE = "www.mydns.jp/login.html"

CURRENT_IP = subprocess.run("wget -q -O - " + REMOTE_ADDR_CHK , stdout = subprocess.PIPE , shell=True)
currIp=CURRENT_IP.stdout.decode("utf8")

line = "none"

if os.path.exists(MYPATH + "saveip.txt") == True:
        f = open(MYPATH + "saveip.txt","r")

        for line in f:
                dummy = line
        f.close

if (currIp != line):
        cmd = "wget -q -O - '"
        cmd += "https://"
        cmd += MASTER_ID
        cmd += ":" + PWD
        cmd += "@" + DDNS_UPDATE + "'"

        ret = subprocess.run(cmd , stdout = subprocess.PIPE , shell=True)

        if ("Login and IP address notify OK.") in ret.stdout.decode("utf8"):
                f2 = open(MYPATH + "saveip.txt","w")
                f2.write(currIp)
                f2.close

                f2 = open(MYPATH + "update.log","a")
                line =  datetime.now().strftime('%Y/%m/%d %H:%M:%S')
                line += "\tIP Address を更新しました。[" + currIp + "]\n"
                f2.write(line)
                f2.close

        else:
                f2 = open(MYPATH + "update.log","a")
                line =  datetime.now().strftime('%Y/%m/%d %H:%M:%S')
                line += "\tIP Address の更新に失敗しました。\n"
                f2.write(line)
                f2.close

ちなみに、アドレスが偶然1時58分に変更されているとして、強制通知を毎日2時00分に実行している場合、10分毎の確認(通知)と同時に実行(MyDNSに通知)する可能性を避けるため、cronの実行は5分ずらすことにした。

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

#毎時10分、20分・・・にIPアドレス変更の有無を確認、有れば通知。
0,10,20,30,40,50 * * * * root /usr/local/sbin/mydns/sample.py3

#毎日2時05分にIPアドレス変更の有無にかかわらず通知。
5 2 * * * root /usr/bin/wget -O - 'https://mydns999999:aaaaaaaaaaa@www.mydns.jp/login.html'

予定(のようなもの)

強制通知をcronで実行するのも良いけど、せっかくアドレス更新logを残しているのだから、「最終更新日から○時間経過していたら強制通知する」を追加してみようかな。

それから、放置しているとlogファイルが大きくなるから、一定期間を経過したら古いlogは削除するとか。

あと、IPアドレスの取得に失敗したときの処理が必要だな。回線断は諦めるとして、割り当てられているIPアドレス確認を2ヵ所で取得して比較、合致したら更新するとか。

その他

現在割り当てられているIPアドレスの取得は、上のスクリプトではieServerのhttp://ieserver.net/ipcheck.shtmlをそのまま使っている。
でもMyDNS.JPを使いながらだとバツが悪いから、別に運用しているレンタルサーバーに次のようなファイルを設置して現在アドレスを確認することにした。

<?php
echo getenv('REMOTE_ADDR');
?>

ファイル名をipcheck.phpとかにして、自鯖からアクセスすればOK。(例えば)123.123.123.123というアドレスだけが返ってくる。

無料で広告なしのレンタルサーバーでphpが使用できれば、そこに設置してもいいけれど、レンタルサーバー更新手続きを忘れては元も子もないからご注意を。

SterServerFreeのPHP・MySQL対応プランなら、広告はモバイルだけだし良いかもしれない。

XFREEのPHP・MySQL対応プランとWordPress機能プランも広告はモバイルだけだから試してみようかな。

コメント

コメントする

目次