AWS Route53でダイナミックDNSを実現してみた

# はじめに
長いこと独自ドメインをダイナミックDNSで運用していましたが、これをAWSのクラウドDNSサービス、Route53を使用するように変更しました。手続きも含めた手順を紹介します。

DNSレコードの自動更新は、aws-cliを使用した独自スクリプトを作成したので、こちらもあわせて紹介します。

# 背景
自宅サーバをインターネットに公開するために、10年以上前から[マイドメインレジストリサービス](http://www.my-domain.jp/)と[DiCE DynamicDNS Client](http://www.hi-ho.ne.jp/yoshihiro_e/dice/)(古い・・・)を使用してダイナミックDNSを実現していました。

DiCEはだいぶ前から更新されていないので、DNSレコードの自動更新は自作のPythonスクリプトに変更していましたが、コスト削減もしたかった(マイドメインは更新費用が年間,6000円かかるので...)ので、ドメイン指定事業者を[さくらインターネット](https://www.sakura.ad.jp/)に変更し、DNSサーバはAWSの[Route53](https://aws.amazon.com/jp/route53/)を使用するようにしました。

DNSもさくらインターネットにしても良かったのですが、いまのところコマンドラインからDNSを更新する手段が用意されておらず、更新用のスクリプトを書くのもかったるかったので、aws-cliが使えるRoute53を採用しました。

また、Route53で汎用JPドメインを維持することもできますが、[価格表](https://d32ze2gidvkk54.cloudfront.net/Amazon_Route_53_Domain_Registration_Pricing_20140731.pdf)を見ると、汎用JPドメインの場合は取得/更新費用が年額90USDと比較的高額です。一方、さくらインターネットは[取得/維持ともに年間3,909円](https://www.sakura.ne.jp/domain/)なので、ドメイン維持はさくらインターネットを使用することにしました。


# ドメイン指定事業者の変更
自分のドメインは、マイドメインレジストリサービスで取得したので、まずドメイン指定事業者をさくらインターネットに変更します。

基本的には、さくらインターネットが公開している[マニュアル](https://help.sakura.ad.jp/hc/ja/articles/206052992--JP%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3-%E8%BB%A2%E5%85%A5-%E6%8C%87%E5%AE%9A%E4%BA%8B%E6%A5%AD%E8%80%85%E5%A4%89%E6%9B%B4-%E3%83%9E%E3%83%8B%E3%83%A5%E3%82%A2%E3%83%AB)を参考にして、手続きするだけです。

1. さくらインターネットの会員メニューから「ドメイン指定事業者変更（転入）依頼」を申し込む
2. 現在の事業者に指定事業者変更の承認を依頼（マイドメインの場合は会員メニューから簡単に依頼できました）
3. さくらインターネットからの連絡を待つ

これらの手続きが終わるまで、2日程度。費用もかかりませんでした。

# Route53の設定
次に、Route53にDNSレコードを登録します。

## Hosted Zoneの作成
1. AWSの管理コンソールからRoute53コンソールにアクセスします。「Hosted zones」メニューを開き、「Create Hosted Zone」ボタンを押します。
2. 「Domain Name」に自分のドメイン名を入力して、「Create」ボタンを押します。
3. これでHosted Zone が登録できました。画面に表示される「Hosted Zone ID」は、あとでレコード更新を自動化するときに必要となるので、控えておきます。私の場合は、以下のようになっていました。

```
ns-673.awsdns-20.net. 
ns-1156.awsdns-16.org. 
ns-1701.awsdns-20.co.uk. 
ns-427.awsdns-53.com.
```

## Route53での名前解決確認
まずは、Route53の管理画面から手作業でDNSのAレコードを作成しておきます。また、HostedZoneの作成と同時に自動登録されているNSレコードの内容を控えておきます。

IPアドレスはルーターの管理画面で調べるか、自宅ネットワークから[こちら](https://www.cman.jp/network/support/go_access.cgi)のようなIPアドレス確認サービスにアクセスすることで確認できます。

次に、さくらインターネット側で、ドメインのネームサーバをRoute53のネームサーバに設定します。

さくらインターネットの会員メニューにログインし、「会員メニュー > ドメイン > 管理ドメインとネームサーバの一覧」を開きます。Route53をネームサーバにするドメインの「WHOIS情報」を開きます。この画面でネームサーバ1〜4が設定できるので、ここに、先ほど控えたRoute53のネームサーバ4つを設定します。詳しくは[ネームサーバ情報の変更に関するマニュアル](https://help.sakura.ad.jp/hc/ja/articles/206205831)を参照すると良いです。

なお、WHOIS情報のネームサーバ情報を更新すると、反映されるまで数時間〜48時間かかるとのことです。自分の場合、計測はしませんでしたが数時間程度で反映されました。

WHOIS情報が反映されたかどうかは、```whois```コマンドで確認できます。

```
$ whois ドメイン名
[Querying whois.jprs.jp]
[whois.jprs.jp]
[ JPRS database provides information on network administration. Its use is    ]
[ restricted to network administration purposes. For further information,     ]
[ use 'whois -h whois.jprs.jp help'. To suppress Japanese output, add'/e'     ]
[ at the end of command, e.g. 'whois -h whois.jprs.jp xxx/e'.                 ]

Domain Information:
[Domain Name]                   XXXXXXXXXXXX.JP

[Registrant]                    XXXXXX XXXXXX

[Name Server]                   ns-1701.awsdns-20.co.uk
[Name Server]                   ns-1156.awsdns-16.org
[Name Server]                   ns-673.awsdns-20.net
[Name Server]                   ns-427.awsdns-53.com
[Signing Key]

[Created on]                    2005/05/08
[Expires on]                    2018/05/31
[Status]                        Active
[Last Updated]                  2018/04/15 14:39:21 (JST)

Contact Information:
[Name]                          SAKURA Internet Inc.
[Email]                         nic-staff@sakura.ad.jp
[Web Page]
[Postal code]                   530-0011
[Postal Address]                Osaka
                                Osaka
                                35F,4-20,ofukacho,kitaku
[Phone]                         06-6376-4800
[Fax]
```

Name Serverの欄に、さきほど登録したネームサーバが表示されていれば、反映完了です。

これで、Route53で名前解決できるようになったはずなので、```nslookup```コマンドで確認してみます。以下は、GoogleのDNSサーバ(8.8.8.8)で名前解決した例です。Route53の管理コンソールに設定したIPアドレスが表示されていれば成功です。(※ ここに示したIPアドレスは例示用のものです)


```terminal
$ nslookup XXXXXXXXXX.jp 8.8.8.8
Server:         8.8.8.8
Address:        8.8.8.8#53

Non-authoritative answer:
Name:   XXXXXXXXXX.jp
Address: 203.0.113.0
```

`dig`コマンドを使えば、もう少し詳しい情報が得られます。

```terminal

$ dig @8.8.8.8 XXXXXXXXXX.jp

; <<>> DiG 9.9.4-RedHat-9.9.4-51.el7_4.2 <<>> @8.8.8.8 XXXXXXXXXX.jp
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 56337
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;XXXXXXXXXX.jp.               IN      A

;; ANSWER SECTION:
XXXXXXXXXX.jp.        599     IN      A       203.0.113.0

;; Query time: 84 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: 火  5月 01 15:06:45 JST 2018
;; MSG SIZE  rcvd: 60
```

# レコード更新を自動化する
ここまでの作業で、独自ドメインの名前解決をRoute53で実現することができました。あとは、IPアドレス変更時に自動でAレコードを更新できるようにすればダイナミックDNSが実現できます。

Route53では、[AWS CLI](https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-chap-welcome.html)を使うことでコマンドラインからレコードを更新することができます。AWS CLIのインストールや初期設定方法はさまざまなサイトで紹介されているので、ここでの説明は割愛します。Route53の操作ができる権限のユーザを作成し、アクセスキーIDとシークレットアクセスキーが得られているものとして説明を続けます。

AWS CLIからRoute53のDNSレコードを操作するには、`route53`サブコマンドを使用します。ただ、更新用のJSONを作成しなければならず、使い勝手があまり良くないため、レコードを簡単に更新するための[ラッパースクリプト(aws-r53)](https://github.com/little-forest/aws-r53)[^1]を作成しました。

[^1]: [cli53](https://github.com/barnybug/cli53)という素晴らしいツールがありますが、今回はaws-cliの勉強も兼ねて自作してみました。

## aws-r53のダウンロード
aws-r53は[GitHubに公開](https://github.com/little-forest/aws-r53)しています。cloneしても良いですが、単一のbashスクリプトなので、curlで取得した方が早いです。取得したら実行権限をつけておいてください。

なお、本スクリプトを実行するには、`aws`コマンドと`jq`コマンドにパスが通っている必要があります。

```terminal
$ curl -o aws-r53 https://raw.githubusercontent.com/little-forest/aws-r53/master/aws-r53
$ chmod +x aws-r53
```

## aws-r53によるRoute53へのアクセスチェック
以下のように実行することで、指定されたホストゾーンの情報を取得してJSON形式で表示します。`-z`オプションの`ZONE_ID`の部分には、自分のホストゾーンIDを指定してください。

```terminal
$ aws-r53 get -z ZONE_ID -V
```

JSONが表示されれば、Route53に正しくアクセスできています。

## aws-r53によるレコードの更新
次に、Aレコードを更新する方法です。`-n`オプションにはドメイン名を指定し、`-v`オプションに名前解決するIPアドレスを指定します。

また、`-w`オプションを指定すると、レコードの反映がRoute53側で完全に反映されるまで待ちます(30秒〜1分程度かかります)。指定しない場合は更新リクエストを送るだけでスクリプトを終了します。

```terminal
$ aws-r53 update -z ZONE_ID -t A -n example.jp -v IP_ADDRESS -w
Waiting for /change/C3UQZ4MJNKJKXD ... [ OK ]
```

また、`-l`オプションでTTLを指定することもできます。

```terminal
$ aws-r53 update -z ZONE_ID -t A -n example.jp -v IP_ADDRESS -l 300 -w
```

これで、Route53のDNSレコードを更新できるようになりました。あとは、IPアドレスの変更検知スクリプト等と組み合わせて実行すれば、ダイナミックDNSが実現できます。

私の場合は、ZABBIXと組み合わせてしまっているので、こちらは別途紹介します。