yi.orgを(ez-ipupdateの代わりに)wgetで更新する

yi.orgって?

DDNSサービスの有名なところに、yi.orgというサービスがあります。DDNSとはDynamic DNSの略で、IPアドレスが固定でないホストでも、DNSが返すIPアドレスを動的に変化させることで、ドメインネームを使えるようにしましょうというものです。

yi.orgのウェブサイトではUNIX系のサーバからIPアドレスを更新するには、ez-ipupdateというクライアントを使いましょうと書いてあります。このクライアントは、yi.orgがサポートしているプロトコルのうち、「GnuDIP2」というプロトコルを用いて更新します。

ところが最近、公式ページの「Help」に書かれている設定どおりでも、ez-ipupdateが「Invalid login」とエラーを吐いて、IPアドレスを更新できなくなっていました。

yi.orgのIPアドレス更新用プロトコル

私はWindowsではDiCEというDDNSクライアントのユーザなので、こちらの更新スクリプトを見てみると、どうやらGnuDIP2プロトコルを使わずに更新しているように見受けられます。

実はyi.orgがサポートするプロトコルは1つではなく、それについては以下のページで述べられています。
http://www.yi.org/help/tech/protocols.shtml

そのうちの「MonoLith (ml.org)」と書かれているプロトコルは、Basic認証を使って指定されたURLにアクセスするだけという簡単な方法で更新できます。ただし、このプロトコルでは、パスワードを安全な方法では送信しない(ほぼ平文で送信され、盗聴されると読めてしまう)ので、注意が必要です。

wgetで実現

先に述べた「MonoLith」プロトコルを、Unix系の環境でほぼ標準で使える?はずの、簡易HTTPクライアント「wget」でやってみました。具体的には、以下を実行します。

$ wget -q --http-user=[更新したいドメイン名] --http-password=[アカウントのパスワード] --spider http://www.yi.org/bin/dyndns.fcgi

すっげぇ簡単ですね。

説明しよう。wgetコマンドとはhttpプロトコルでファイルをダウンロードして保存するためのCUIプログラムである。--http-userと--http-passwordはBasic認証のユーザとパスワードを指定するオプションである。--spiderはファイルを保存しないようにするオプションである。-qはもちろん--quiet。--spiderがミソで、GETリクエストを発行するだけのプログラムに大変身させることができる。

これをファイルに保存して、起動時に実行されるように設置すれば良いでしょう。ただし、パスワードを直で書かないといけないので、独立したファイルに書き出しておき、所有ユーザ・グループを両方rootにし、パーミッションを所有ユーザのみの読み書き実行(700)にしておくべきでしょう。その場合は、shebangを忘れずに、以下のようなファイルを作成してください(今回は便宜的にファイル名をupdate_yi_org.shとしておきます)。

#!/bin/sh
wget -q --http-user=(更新したいドメイン名) --http-password=(アカウントのパスワード) --spider http://www.yi.org/bin/dyndns.fcgi

以下(のようなコマンド)を忘れずに・・。パスワードが盗まれないように、セキュリティ対策をしましょう。

# chown root:root update_yi_org.sh (root権限でファイルを作成した場合はこっちは不要)
# chmod 700 update_yi_org.sh

起動時にスクリプトを実行させる(PPPoEではない場合用)

起動時に実行させるには、ネットワークインタフェースの開始時にスクリプトが実行されるように、ネットワークの設定を変更するとよいでしょう。

Ubuntuを含むDebian

/etc/network/interfacesの、該当するiface行の後に、以下のような行を追加します。

up /path/to/update_yi_org.sh
CentOSFedoraを含むRedHat

/etc/sysconfig/network-scripts/ifup-postの最後に書いてあって見つけたけど、こんなんわかるかよ・w・;。/sbin/ifup-localというファイルを作成しておけば、そのファイルがインタフェースの開始後に呼び出されて、その引数はデバイス名らしい。というわけで、以下のようなスクリプトを/sbin/ifup-localというファイル名で(root権限で)保存し、実行権限を付与(「chmod +x /sbin/ifup-local」)します。

#!/bin/sh
if [[ "$1" = "(インタフェース名、eth0など)" ]]; then
	/path/to/update_yi_org.sh
fi

または、「http://jfut.integ.jp/2007/02/25/rhel-and-entos-network-config-for-lvs-keepalived-vrrp-dsr/」で述べられているように、symlinkを作成します。具体的には、上記のスクリプトを(実行権限を付与してユーザもグループもrootの)ファイルに保存し、/sbin/ifup-localというファイル名で、当該スクリプトを保存したファイルに対するsymlinkを作成します(/sbin/ifup-local→update_yi_org.sh)。
ちなみにif文を書かないとlo(ループバックインタフェース)が開始されたタイミングで起動されるなど、不必要なタイミングで起動されてややこしいことになるかもしれません。

Gentoo

以下のようなシェルスクリプトを、/etc/conf.d/netに追加します。詳しくは/etc/conf.d/net.exampleを参照してください。

postup() {
	if [[ "${IFACE}" = "(インタフェース名、eth0など)" ]]; then
		/path/to/update_yi_org.sh
	fi
}

PPPoE環境の人はここから重要!!

PPPoEを使っている場合、前述のような方法で、インタフェースの開始に合わせてスクリプトを実行するだけでは、上手くいかないかもしれません。なぜならば、インタフェースの起動スクリプト自体は「開始」状態になっていても、実はまだPPPoEセッションが開始されていなかったり、自動的に再接続してIPアドレスが変化していたりするかもしれません。PPPoEセッションが開始されたタイミングに必ずスクリプトが実行されるべきなのですが、実際は(起動スクリプトからはそのことが分からないため)実行されるようになっていない可能性が高いです。

pppdを使っている場合(当該ホストからPPPoEセッションを張っている場合は主にこれ?)

pppdを用いてPPPoE接続を行っている環境の場合、pppdの設定として設置すると、PPPoEセッション開始後に自動的に実行されるようになります。なお、恐らく再接続時にも実行されると思います。

具体的には、/etc/ppp/ip-up.localというファイルを使います。存在しなければroot権限で作成し実行権限を付与(「chmod +x」)しておきます。そこに、update_yi_org.shを呼び出す行(「/path/to/update_yi_org.sh」)を追加します。

/etc/ppp/ip-up.localがそもそも存在しない場合は、update_yi_org.shを/etc/ppp/ip-up.localとして作成しても良いでしょう(もちろんこの場合は所有権やパーミッションに注意)。

ルータ側でPPPoEを設定している場合

ルータ側のIPアドレスが更新されたことを検知するには、定期的にIPアドレスをチェックするぐらいしか方法がないでしょう。http://checkip.dyndns.org/などでチェックしてみて、もしIPアドレスが変化していたら更新というのが正しいのですが、これについては面倒になりそうなので、今日は割愛します。