自宅サーバのDynamicDNSをAWSで運用する

AWSのRoute53に毎月お金を払っているので、自宅サーバのDynamicDNSとしてAWSを利用することにした。

自宅サーバのOSはDebian7。言語はNodejsを使う。

ちなみに、自分はVPSも利用しているので、IPアドレスの確認は、VPSを利用している。

Route53の構築

ここはAWSのコンソールにて作業。

Route53にHosted Zoneとして、DynamicDNSとして利用するドメインを追加する。ここでは、ddns.j74th.comとする。

①Route53→Create Hosted Zone

  • Domain Name : ddns.j74th.com
  • Create

ここで追加されるHostedZoneIdは、アクセスする際に使うのでメモしておく。

ddns.j74th.comを選ぶ→Go To Record Set→Create Record Set

③NSレコードの値をメモする(4つあるはず)

DNSをRoute53に向ける。

自分はお名前.comで、j74th.comを取得している。お名前.comのDNSレコード設定にて以下のレコードを、4つとも追加する。

  • ホスト名: ddns.j74th.com
  • TYPE: NS
  • VALUE: 上記③のNSレコードの値

これで、ddns.j74th.comでRoute53に問い合わせに行くようになった。

Nodejsをインストールする前に、Backportsをaptitudeの取得先に追加

ここからはDebianサーバでの作業。

まだNodejsはBackportsにしか含まれていないため、Backportsをパッケージの取得先に追加する。

参考:http://backports.debian.org/Instructions/

/etc/apt/sources.listに以下の行を追加。

deb http://http.debian.net/debian wheezy-backports main

その後、aptitudeをアップデート

# aptitude update

nodejsをインストール

# aptitude install nodejs

インストールされていることを確認。

# nodejs --version
v0.10.26

よくわからないけど、インストール先はnodeじゃなくて、nodejsなんだよね。ちょっと迷惑なので、nodeにシンボリックリンクをはる。

# ln -s /usr/bin/nodejs /usr/bin/node

npmのインストール

いつものスクリプトでインストールする。上記のnodeにシンボリックリンクを張らないと、動作しなかった。

# curl https://www.npmjs.org/install.sh | sudo sh

IPアドレスを返す何かを作る

IPアドレスを取得して返してくれる何かが必要になる。うちはバッファローのルータなので、このルータのステータス画面にIPアドレスが出ていて、そこから取得すればよい。けど、面倒なので、レンタルサーバIPアドレスを表示するスクリプトPHPで作って置いておくことにする。

<?php
echo($_SERVER["REMOTE_ADDR"]);
?>

npmでaws-sdkをインストール

$ mkdir ~/UpdateAWSDDNS
$ cd ~/UpdateAWSDDNS
$ npm install aws-sdk

IPアドレスを取得して、AWSのRoute53をアップデートするスクリプト

#!/usr/bin/env node
var http = require('http');
var AWS = require('aws-sdk'); 

var DDNS = "ddns.j74th.com";
var HOSTED_ZONE_ID = 'xxx'; // 最初に取得したHosted Zone Id
var AWS_ACCESS_KEY_ID = 'xxx';
var AWS_SERCRET_ACCESS_KEY = 'xxx';

// IPアドレスの取得
function getIpAddress(callback){
    var req = http.get('http://IPアドレスを取得するサイト/echoIp.php', function(res) {
        res.on('data', function(str) {

            // IPアドレスの形式を認識して、コールバックする
            if( str.match(/[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+/i) ){
                console.log("Get IP Address:" + str);
                callback(str);
            }else{
                console.log("Error: not ip address " + str);
            }
        });
    });
    req.on('error', function(err) {
        console.error("Error: " + err.message);
    });
}

function updateMyDNS(ipAddress){

    AWS.config.update({
        accessKeyId: AWS_ACCESS_KEY_ID,
        secretAccessKey: AWS_SERCRET_ACCESS_KEY
    });

    var route53 = new AWS.Route53();

    var params = {
        ChangeBatch: {
            Changes: [
                {
                    Action: 'UPSERT',
                    ResourceRecordSet: {
                        Name: ,
                        Type: 'A',
                        ResourceRecords: [
                            {
                                Value: ipAddress
                            }
                        ],
                        TTL: 300
                    }
                },
            ]
        },
        HostedZoneId: HOSTED_ZONE_ID
    };

    route53.changeResourceRecordSets(params, function (err, data) {
        if (err) {
            console.error(err, err.stack);
        }else {
            console.log("Success Update");
            console.log(data);
        }
    });
}


getIpAddress(function(ipAddress){
    updateMyDNS(ipAddress);
});

上記スクリプトをcronで動かして、更新されていればOK。適当につくったので、いじってください。