去年までここのブログのドメイン管理はvalue-domainで行っていたのですが、つい最近同じGMOグループのお名前.comにドメイン移管しました。
ただ、value-domainではダイナミックDNS機能が標準で提供されており、自宅のIPアドレスをRaspberry Piからcurlコマンドで自動更新できていたのですが、お名前.comではその機能が提供されていないことに移管してから気づき、手動で更新する羽目に。。
よくよく調べると、WindowsであればDiCEなどで自動更新できるみたいですが、DNSレコード更新のためだけにWindows機を常時起動しておくわけにもいかず、できれば今まで通りRaspberry Piから自動更新できる方法を模索していました。
(DiCEはLinux版もあるみたいですが、Raspbery Piで動くものは無いようでした)
そこで今回は、ヘッドレスブラウザのPhantomJSを使った自動テストフレームワークであるCasperJSを使って、お名前.comの管理ページからDNSレコードを変更するまでの操作をスクリプト化し、無理やり自動更新するようにしてみました。
注意:本方法を使った場合、設定によっては先方のサーバに思わぬ負荷を与えてしまうことがあります。ご利用にあたっては自己責任でお願い致します。
- Raspberry Pi(raspbian)にPhantomJSをインストール
apt-getではインストールできないため、こちらのビルド版を/usr/local/bin以下にコピーして利用 - 続けてCasperJSをインストール
公式サイトにある1.1.0-beta3のzipファイルをダウンロードし、/usr/local/casperjsに展開後、PATH環境変数に/usr/local/casperjs/binを追加 - 以下スクリプトをonamaedns.jsの名前でコピー
var casper = require('casper').create({
pageSettings: {
userAgent: 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0)'
},
logLevel: 'info',
waitTimeout: 30000,
verbose: true
});
casper.on('remote.message', function(msg) {
this.log(msg, 'info');
});
var new_ip = null;
function exit_usage() {
casper.echo('usage: casperjs --ssl-protocol=any --ignore-ssl-errors=true onamaedns.js [options]');
casper.echo('options:');
casper.echo(' --userid onamae.com id');
casper.echo(' --passwd onamae.com password');
casper.echo(' --domain update domain');
casper.echo(' --host update hostname');
casper.exit();
}
var options = casper.cli.options;
if (!options['userid'] || !options['passwd'] || !options['domain'] || !options['host']) {
exit_usage();
}
casper.start();
casper.thenOpen('http://whatismyip.akamai.com/', function() {
new_ip = this.fetchText('body');
this.log('new_ip=' + new_ip, 'info');
});
casper.thenOpen('https://www.onamae.com/domain/navi/domain.html', function() {
this.evaluate(function(options) {
document.querySelector('input[name="username"]').value = options['userid'];
document.querySelector('input[name="password"]').value = options['passwd'];
document.querySelector('input[name="login"]').click();
}, options);
});
casper.waitForSelector('a[href*="domain/navi/menu/domain"]', function() {
this.click('a[href*="domain/navi/menu/domain"]');
});
casper.waitForSelector('a[href*="domain/navi/dns_manage"]', function() {
this.click('a[href*="domain/navi/dns_manage"]');
});
casper.waitForSelector('input[type="radio"][value="' + options['domain'] + '"]', function() {
this.click('input[type="radio"][value="' + options['domain'] + '"]');
});
casper.waitForSelector('a.btn07.idSubmitexternal > span', function() {
this.click('a.btn07.idSubmitexternal > span');
});
casper.waitForSelector('a[title*="domain/navi/dns_controll/input"]', function() {
this.click('a[title*="domain/navi/dns_controll/input"]');
});
casper.waitForSelector('#dns_controll_inputForm', function() {
var ret = this.evaluate(function(new_ip, options) {
var num = document.querySelector('input[value="' + options['host'] + '.' + options['domain'] + '"]').getAttribute('id').replace('hostNameUsed', '');
var old_ip = document.querySelector('#hdd_add_recvalue_a_used' + num).value;
if (new_ip == old_ip) {
return false
}
document.querySelector('#hdd_add_recvalue_a_used' + num).value = new_ip;
document.querySelector('#idSubmit').click();
return true;
}, new_ip, options);
if (ret === false) {
this.die('same ip adress');
}
});
casper.then(function() {
this.click('#idSubmit');
});
casper.waitForSelector('a[href*="submitDnsconfirmForm"] > span', function() {
this.click('a[href*="submitDnsconfirmForm()"]');
});
casper.waitForUrl(/domain\/navi\/dns_controll\/result/, function() {
this.exit();
});
casper.run();
- お名前.comの管理ページにログインして、本スクリプトで更新するDNSレコードを登録しておく
- スクリプトを実行してみて動作テスト(問題なければcronに登録)
casperjs --ssl-protocol=any --ignore-ssl-errors=true onamaedns.js
ハマった所としては、
- PhantomJSのバージョンが古いため、(お名前.comを含む)POODLE対策を行ったサーバにHTTPS接続できない
→casperjs –ssl-protocol=any(またはtlsv1) –ignore-ssl-errors=trueをつける - たまにタイムアウトで失敗する
→Raspberry Pi(特に初期のやつ)だと重い処理らしく、waitForSelector()で応答を待つようにした
なところで、一応1ヶ月前くらいから毎朝3時に無線LANルーターの再起動とともに実行するよう仕掛けていますが、無事に成功しているようです。
(その度にお名前.comから更新完了の通知メールが届くのが難点ですが。。)