本サイトのバックアップサイトへのアクセス制限をIPアドレスでやっていたのですが、ルータに割り当てられるアドレスが変わるたびにIPアドレスを更新するのが面倒になってきました。そこで、自宅の回線にダイナミックDNSで名前を付けることにして、その名前で接続制限するようにしました。
ダイナミックDNSサービスの選定
無料のダイナミックDNSサービスをいろいろ調べてみたところ、httpsでのアップデートができること、3か月間更新がなくてもサブドメインがなくならないことから、今回は、ieServer を使うことにしました。サービスの詳細は、ieServer のサイトをご覧ください。
ReadyNasDuo で更新スクリプトを試す
残念ながら今使っているブロードバンドルータにはダイナミックDNSの更新機能がありません。DiCE などで自分のPCから必要なときに更新するのは煩雑なので自動処理にします。このためには、自宅回線のIPアドレスを監視して、更新を行うために常時稼働しているPCが必要になります。このためだけにサーバー立てるのもばからしいので、ここは常時動作しているNAS(対象としたのはNetgear の ReadyNasDuo )に更新作業を行わせることにします。
現在使っている ReadyNasDuo にはSSHでアクセスするためのアドオンが既に入っています。そこで、sshでログインして、更新できるかを確認してみました。
まずは更新ページを呼び出してみると、
wget "http://ieserver.net/cgi-bin/dip.cgi"
問題なく応答が返ってきます。
次に、httpsでの接続を試すと、
wget "https://ieserver.net/cgi-bin/dip.cgi"
NAS01:~# wget "https://ieserver.net/cgi-bin/dip.cgi" --23:51:35-- https://ieserver.net/cgi-bin/dip.cgi => `dip.cgi' Resolving ieserver.net... 61.197.187.238 Connecting to ieserver.net|61.197.187.238|:443... connected. ERROR: Certificate verification error for ieserver.net: unable to get local issuer certificate To connect to ieserver.net insecurely, use `--no-check-certificate'. Unable to establish SSL connection. NAS01:~#
のようにエラーが返ってきました。メッセージを見るとieServerから渡される証明書の認証ができないようです。ちなみに、PCのブラウザで同じページを開くと問題なく表示されています。
(参考)
SSL証明書をOpenSSLコマンドで取得するときにエラーが出る
上記の参考サイトにもあるように、ReadyNasDuo にCAのルート証明書をインストールすれば問題ないようです。が、これが今一つよくわからなかったです。いろいろ見ていたら、ReadynasDuo はDebian sarge をベースにしているようで、Debian ではca-certificatesというパッケージをインストールすると主要なルート証明書をインストールできそうなことがわかりました。
(参考)
http://t-ta.net/diary/yt/?date=20110322
ReadyNasDuo の設定
そこでまず、ReadynasDuo にルート証明書をインストールします。
最初に、apt-get系のコマンドを使えるようにします。ReadyNasDuo ではAPTアドオンをインストールすることで使えるようになります。インストールは、FrontView から行います。
(参考)
http://www.readynas.com/?cat=36
http://www.readynas.com/?p=145
再起動後、aptコマンドが使えるようになります。SSHでログイン後、
NAS01:~# apt-get update NAS01:~# apt-cache show ca-certificates
として、パッケージがあることを確認しておきます。次に、
NAS01:~# apt-get install ca-certificates
とすると、パッケージのインストールが開始します。途中で、
This package may install new CA (Certificate Authority) certificates when upgrading. You may want to check such new CA certificates and select only certificates that you trust. - "yes", new CA certificates will be trusted and installed. - "no", new CA certificates will not be installed by default. - "ask", Ask you trust each new CA certificates or not 1. yes 2. no 3. ask Trust new CAs certificates? 1 Updating certificates in /etc/ssl/certs....done. NAS01:~#
のようにルート証明書のインストールを行うかどうか聞かれるので、yes(1)を入力します。インストールが無事に終われば準備完了です。
ためしに、httpsで接続してみると、
NAS01:~# wget "https://ieserver.net/cgi-bin/dip.cgi" --23:55:43-- https://ieserver.net/cgi-bin/dip.cgi => `dip.cgi' Resolving ieserver.net... 61.197.187.238 Connecting to ieserver.net|61.197.187.238|:443... connected. HTTP request sent, awaiting response... 200 OK Length: unspecified [text/html] [ <=> ] 1,009 --.--K/s 23:55:45 (8.02 MB/s) - `dip.cgi' saved [1009] NAS01:~#
と問題なく接続できました。
ダイナミックDNS更新の設定
ダイナミックDNSの更新スクリプトは、ieServer が公開している更新スクリプトをほぼそのまま使うことにします。更新の接続はhttps にしています。これをcronで設定し、10分毎にチェックすることにします。
ただ、この更新スクリプトだとIPアドレスが変わらないと更新呼び出しが行われないため、3か月間IPアドレスが変わらなければある日サブドメインが使えなくなる恐れがあります。
そこで、これとは別に無条件に更新呼び出しを行うスクリプトを一か月に一回実行するようにしておきます。
これらの更新スクリプトを /root/ddns ディレクトリに置いておき、/etc/cron.d にddns-update ファイルを作成します。
ddns-updateの内容は/etc/crontab をベースに下記のようにしました。
# ddns-update settings # 2012/11/21, Junichi MORI SHELL=/bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin # m h dom mon dow user command 5,15,25,35,45 * * * * root (cd /root/ddns; nice -19 /root/ddns/ddns-update) 55 10 21 * * root (cd /root/ddns; nice -19 /root/ddns/ddns-force-update) #
毎時、5分・15分・25分・35分・45分にIPアドレスの更新をチェックし、毎月21日10時55分にIPアドレスにかかわらず強制的に更新を行うという設定です。
なお、Debianでは、cron設定に書くコマンド名がピリオドを含んでいると実行できないという情報も見かけましたが、検証はしていません。気になる方は調べてみてください。
(参考)
独自ドメイン名の設定
これでダイナミックDNSの設定は一応できたのですが、このままでは ieServer が提供するドメイン名になります。せっかく独自ドメインを持っているので、独自ドメイン名を割り振ります。
ドメイン名はさくらインターネットで管理しているので、DNS設定でCNAME(別名)を設定することにします
xxxxx CNAME yyyy.dip.jp.
という感じです。これで、自宅回線からのアクセスを独自ドメイン名で識別できるようになりました。
(参考)
DynDNSで運用する動的ドメインをさくらインターネットで取得したドメインのサブドメインに指定する方法
独自ドメインでダイナミックDNSと外部Webサービスを同時に使う設定メモ
.htaccessの更新
さて、これでバックアップサーバー(さくらインターネットのレンタルサーバーです)の.htaccessに
allow from xxxx.mori-soft.com
と記述して、自宅からだけアクセスできるかと試してみたらつながりません。
一瞬、ん?と思いましたが、考えてみると接続元はIPアドレスで判定しているはずで、ダイナミックDNSでホスト名を指定しても逆引きができないので、当然アクセスができないことに気づきました(最初から気づけよと言いたくなりました・・・)。
この場合、ホスト名をIPアドレスに書き換えるシェルをcronで動かせば問題は解決です。今回はこんなのを書きました。
#!/usr/local/bin/bash # # update dynamic DNS hostname in .htaccess # # 2012/11/21, Junichi MORI SRC=${HOME}'/www/htaccess.base' DST=${HOME}'/tmp/htaccess.tmp'.$$ DDNS_HOST='xxxx.mori-soft.com' HTACCESS=${HOME}'/www/.htaccess' cp -p $SRC $DST host $DDNS_HOST | awk '/has address/ { print "allow from " $4 }' >> $DST if [ -f $HTACCESS ] then rm -f $HTACCESS fi mv $DST $HTACCESS
allow from 以外の設定を記述済みのhtaccess.base を作っておいて、DDNSのホスト名から解決したIPアドレスを追記します。
これで、問題なく.htaccessの更新ができます。
ダイナミックDNSなので、更新のタイムラグで予期せぬアクセスもあり得ますがまあ今回の目的からすると十分実用的かと思います。
あとはcronで定期的に実行するように設定して完了です。
(参考)
Dynamic DNS を使って SSH アクセスを制限する方法
Update .htaccess with Dynamic DNS IP Address to Prevent Password Protection