https://naba-san.hatenablog.com/


freedns.afraid.org でドメインを自動更新させる

概要

以前まで ZoneEdit を利用していたが,知らん間にサービスが有料化したのか,なんか色々と面倒な事になってるので退散する事にした.EveryDNSもDynDNSも有料化してる中で見つけたのは,freedns.afraid.org

いわゆるサブドメインを使った Dynamic DNS の他,持込ドメインによるダイナミックDNSサービスが利用可能.但し,持ち込んだドメインに対して private と public なる設定項目が存在し,これをうっかり public に設定してしまうと,持ち込んだドメインサブドメインが誰でも利用できるようになってしまう(面白いドメイン取って人に見せびらかしたい人とか,publicに設定してみたらいいと思う).

その辺を気にしなければ,UIはシンプルだし,更新対象のホストごとにトークン付きでURL発行してくれる(認証方法にIDとかPassの代わりにTokenが使えるのは使う側として非常に楽).

RaspPiを使っていて,DiCEが使えないのがちょっと面倒だなと思っていた所だったので,この際だからと updater をこしらえる事にした.ベースにさせて頂いたのは、ieServerさんが公開されているIPアドレス更新サンプルスクリプト

作る過程でcheckyourip.phpとかも作ったけど(というか公式にもそれっぽいものがあったんだけど),よく考えたらクライアント側でIPアドレスの変更を管理する必要がない事に気付いたので,その辺りは原型留めてない.

updater

以下は update-freedns_afraid_org.txt にもコピーがあります(リンク先と版が一致していない可能性あり).

#!/usr/bin/perl
use POSIX;

###############################################################################
# 説明                                                                        #
###############################################################################
#                                                                             #
# freedns.afraid.org が提供する Dynamic DNS のアドレス更新に利用するもの.    #
#                                                                             #
# 使い方は次のURLを参照して下さい:                                            #
#   http://d.hatena.ne.jp/naba_san/20140119/1390092645                        #
#                                                                             #
# 履歴:                                                                       #
#  [2014-01-19.01] 初版.                                                     #
#  [2014-01-19.02] エラー判定を追加.                                         #
#  [2014-01-19.03] 不要な記述を除去.                                         #
#                                                                             #
###############################################################################


###############################################################################
# 設定                                                                        #
###############################################################################

# DDNS更新ページURL
# 説明: freedns.afraid.org から対象ホストの Direct URL を取得する.
#       取得できるURLは http でアクセスするものだが,https でもアクセス可能.
$DDNS_UPDATE  = "https://freedns.afraid.org/dynamic/update.php?YOUR-TOKEN";

# 現在のIPアドレスの記録先
$CURRENT_FILE = "/dev/null";

# ログファイル
$LOG_FILE    = "/var/log/ip_update.log";

################################################################################


# 以下は処理部分.

# 現在時刻を取得して返す
sub get_time{
    # my ($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst)
    #= localtime(time);
    #$year += 1900;
    #$mon += 1;
    #return "$year-$mon-$mday $hour\:$min\:$sec";
    return POSIX::strftime "%Y/%m/%d %H:%M:%S",localtime(time);
}

# URLにアクセス,結果を$STATUSへ
$STATUS = `wget -q -O - $DDNS_UPDATE`;

# 更新成功
if ($STATUS =~ /Updated [0-9] host\(s\) .* to ([0-9]{1,3}\.){3}[0-9]{1,3} in [0-9]{1,2}\.[0-9]{3} seconds/) {
    $TIME = &get_time;
    $STATUS =~ /([0-9]{1,3}\.){3}[0-9]{1,3}/;
    open (FILE ,">>$LOG_FILE");
    print FILE "[$TIME] SUCCESS: Address has been changed to $&.\n";
    close FILE;
    open (FILE ,">$CURRENT_FILE");
    print FILE "$&";
    close FILE;
}

# アドレスが変更されていない
elsif($STATUS =~ /ERROR: Address ([0-9]{1,3}\.){3}[0-9]{1,3} has not changed\./){
    $TIME = &get_time;
    open (FILE ,">>$LOG_FILE");
    print FILE "[$TIME] SUCCESS: Address has not changed.\n";
    close FILE;
    $STATUS =~ /([0-9]{1,3}\.){3}[0-9]{1,3}/;
    open (FILE, ">$CURRENT_FILE");
    print FILE "$&";
    close FILE;
}

# URL(トークン)がおかしい
elsif($STATUS =~ /ERROR: Invalid update URL \(2\)/) {
    $TIME = &get_time;
    open (FILE ,">>$LOG_FILE");
    print FILE "[$TIME] ERROR: Update URL is invalid!\n";
    close FILE;
}

# 認証トークンがおかしい(登録が存在しない)
elsif($STATUS =~ /ERROR: Unable to locate this record/) {
    $TIME = &get_time;
    open (FILE ,">>$LOG_FILE");
    print FILE "[$TIME] ERROR: Authentication Token is invalid!\n";
    close FILE;
}

# レスポンスから結果を判定できなかった場合
else
{
    $TIME = &get_time;
    open (FILE ,">>$LOG_FILE");
    print FILE "[$TIME] ERROR: Server response was not recognizable!\n";
    print FILE " --------------------\n";
    print FILE "  $STATUS";
    print FILE " --------------------\n\n";
}

exit;

ログはこんな感じで出力される.

[2014/01/19 09:13:20] SUCCESS: Address has changed to XX.XX.XX.XX.
[2014/01/19 09:13:46] SUCCESS: Address has not changed.
[2014/01/19 09:16:33] SUCCESS: Address has not changed.
[2014/01/19 10:10:04] ERROR: Server response is not recognizable!
 --------------------
  ERROR: Unable to locate this record
 --------------------

フォーマットが変わった時に,「Server response is not recognizable!」が多発する可能性あり(上記は認証トークンエラーの判定を追加する前に出ていたもの).

初期設定

freedns.afraid.org から,左メニューの Dynamic DNS を開き,ページ下部に表示されるドメインから,Direct URL を開く.

アクセスすると「ERROR: Address XXX.XXX.XXX.XXX has not changed.」的なメッセージが出てくることを確認して,そのURLをコピーし,上のスクリプトに設定.

$LOG_FILE にログの出力先を設定して,要らないログがあったら該当処理行の中身の頭に#付けて全部コメントアウト

例えば,アドレスが維持された時の通知が要らない人はこんな感じ.ifとかelse ifを一緒にコメントアウトすると,その部分のレ寸ポスが返された時に判定不能エラーになるので注意.

# アドレスが変更されていない
elsif($STATUS =~ /ERROR: Address ([0-9]{1,3}\.){3}[0-9]{1,3} has not changed\./){
#    $TIME = &get_time;
#    open (FILE ,">>$LOG_FILE");
#    print FILE "[$TIME] SUCCESS: Address has not changed.\n";
#    close FILE;
#    if($STATUS =~ /([0-9]{1,3}\.){3}[0-9]{1,3}/)
#    {
#        open (FILE, ">$CURRENT_FILE");
#	print FILE "$&";
#	close FILE;
#    }
}
導入

お好きな方で
・/etc/cron.hourly とかへ実行可能な状態で突っ込む.
・/usr/local/freedns/upate-freedns.pl とかへ実行可能な状態で突っ込んで,crontab から定期的に呼び出されるようにする.

後者の設定例(/etc/crontab)

 */5 * * * * root /usr/local/freedns/update-freedns.pl