LoginSignup
8
6

More than 5 years have passed since last update.

Node.js と Route53 で DDNS を運用する

Posted at

前提条件

  • Route53でHostedZoneを登録してある
  • そのZONE_IDを取得してある
  • そのHostedZoneを操作する権限を持つIAMユーザを作成してある
  • IAMユーザのアクセスキーとシークレットキーを取得してある

必要な権限は下記の通りです。Actionは4つ、ResourceはHostedZoneを指定します。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "route53:GetHostedZone",
                "route53:ListResourceRecordSets",
                "route53:ChangeResourceRecordSets",
                "route53:GetChange"
            ],
            "Resource": [
                "arn:aws:route53:::hostedzone/Z1XUEXAMPLEWR1"
            ]
        }
    ]
}

IDとキーを保存した環境変数ファイルを作成する

DDNSを実現するには HostedZoneのZONE_ID、IAMユーザのアクセスキーとシークレットキーをスクリプト内で参照する必要があります。これらをハードコーディングしたくないので、環境変数として渡すためのファイルを作成しておきます。

.api_keys
# DDNS 
ROUTE53_ZONE_ID=Z1XUEXAMPLEWR1
IAM_DDNS_KEY=AEXAMPLEEXAMPLEU3C7Q
IAM_DDNS_SECRET=YxEXAMPLEEXAMPLEEXAMPLEEXAMPLEEXAMPLEYss

Dockerコンテナを作成する

Node.jsが動けばなんでもよいのですが、Dockerで準備するのが楽なのでそのようにします。

Dockerfile
FROM node:latest
MAINTAINER flny flny@example.com

RUN npm install nice-route53 \
                external-ip
CMD /bin/bash

Route53を操作するために nice-route53 を、自身のグローバルIPを知るために external-ip を それぞれnpmでインストールしています。

docker build と docker runでNode.jsが動作するコンテナを作成します。

$ docker build -t ddns <Dockerfileのあるディレクトリ>
$ docker run -itd --env-file .api_keys --name ddns ddns

スクリプトを記述する

sendDdns.js
#!/usr/bin/env node

var ExtIP = require('external-ip'),
    Route53 = require('nice-route53')
;

var configMap = {
        zoneId  : process.env.ROUTE53_ZONE_ID,
        iam_key : process.env.IAM_DDNS_KEY,
        iam_sec : process.env.IAM_DDNS_SECRET,
    },
    getIP = new ExtIP(),
    r53 = new Route53(
        {accessKeyId :     configMap.iam_key,
         secretAccessKey : configMap.iam_sec}
        ),
    onReceiveIp, sendRecord
;


sendRecord = function(ip) {
    var aRec = {
        zoneId : configMap.zoneId,
        name   : 'foo.example.com.',
        type   : 'A',
        ttl    : 3600,
        values : [ip]
    };
    console.log(aRec);
    r53.setRecord(aRec, function(err, res) {
        if(err) throw err;
        console.log(res);
    });

};


onReceiveIp = function(err, ip) {
    if(err) {
        throw err;
    }
    sendRecord(ip)
}


getIP(onReceiveIp);
  1. getIPでグローバルIPアドレスを取得して、
  2. それを元にAレコードを作成し、
  3. r53.setRecordでAレコードをupsertする

という流れです。パッケージのおかげで楽ちんですね。

動作を確認する

# ./sendDdnsRec.js
{ zoneId: 'Z1XUEXAMPLEWR1',
  name: 'foo.example.com.',
  type: 'A',
  ttl: 3600,
  values: [ '110.233.x.x' ] }
{ changeId: 'C316EXAMPLE9ZO',
  url: '/change/C316EXAMPLE9ZO',
  status: 'PENDING',
  submittedAt: Tue May 24 2016 15:47:34 GMT+0000 (UTC) }

コンテナ上で スクリプトを実行すると、うまくいけば status: 'PENDING' のレスポンスが返ります。'PENDING'という記述ですが Aレコードは既に登録されています。

以上

8
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
6