AWS
route53
aws-cli
DDNS

AWS: Amazon Route 53 をコマンドラインから更新して DDNS として使う

Cluster,Inc. Advent Calendar 2018、6日目の記事です。

この記事では、aws-cli コマンドを利用して AWS Route 53 の DNS Entry を DDNS として利用した話を書きます。

Motivation

クラスター株式会社は、リモートワーク可能・社内のリソースにアクセスする為に VPN が利用できるのですが、インターネット接続は通常のフレッツ光のため、たまに Office IP が変更になって困っている、という話がありました。

解決しましょう

IP を隠蔽する抽象化というと真っ先に DNS が思い浮かびます。特にダイナミックに変わる IP に追従するようにダイナミックに DNSレコードを変えていけばいいじゃないかという発想の元に

ダイナミックドメインネームシステム とは

IPアドレスを割り当てられたクライアントコンピュータの側から、自分のIPアドレスとホスト名をDNSサーバに登録することにより、IPアドレスを動的に割り当てながらもホスト名を一定に保つという発想が生まれた。これがダイナミックDNSである。

https://ja.wikipedia.org/wiki/ダイナミックドメインネームシステム

これにより、 *.example.com ドメインを所有していれば、常に office.example.com = オフィス(のルーター)の IP ということが可能です。

実装

クラスター株式会社はサービスインフラおよび社内で利用される DNS の管理に AWS を利用しています。

(個人的な話で失礼しますが、転職経験としては4社目となるのですが、AWS便利で感動しました)

AWS の DNS 管理サービスは Route53 で、これをコマンドラインからレコードの修正をする aws-cli がありますので、こちらを利用します。

実装された手順としては以下の通りで、社内の Jenkins サーバーで動作しています。

  1. オフィス内の Jenkins サーバー上から、Public IP として出て行く場合のIPを取得します
  2. AWS Route53 更新テンプレートの IP 欄を、 1. で入手した IP に置き換えてリクエストボディを作成します
  3. リクエストボディを元に AWS にリクエストします。

1. オフィス内の Jenkins サーバー上から、Public IP として出て行く場合のIPを取得します

自分のIPが知りたくなったら、確認君、、、が有名ですが。
今回は IP API で検索したなかでシンプルだった https://www.ipify.org/ を利用しました。

% curl -s https://api.ipify.org
114.164.185.104

末尾の \n が無い非常にシンプルなテキストでデータが返ってきます

2. AWS Route53 更新テンプレートの IP 欄を、 1. で入手した IP に置き換えてリクエストボディを作成します

準備したテンプレート

template.json
{
  "Comment": "Update by update_office_ip.sh",
  "Changes": [
    {
      "Action": "UPSERT",
      "ResourceRecordSet": {
        "Name": "office.example.com",
        "Type": "A",
        "TTL": 60,
        "ResourceRecords": [
          {
            "Value": "<IP>"
          }
        ]
      }
    }
  ]
}

実際にはこんな流れで <IP> が現在のIPに置換された JSON が入手できます。

ip=$(curl -s https://api.ipify.org)
cat template.json | perl -pe"s/<IP>/$ip/"

3. リクエストボディを元に AWS にリクエストします。

aws --debug --output=table route53 change-resource-record-sets --hosted-zone-id ここがぞーんID --change-batch "$(cat template.json | perl -pe"s/<IP>/$ip/")"

--debug を付けておくことでリクエスト&レスポンスの wire log が表示されます。
また、--output=tableを追加すると、最終的な出力結果が表になります。

結果は以下の用になります。

----------------------------------------------------
|             ChangeResourceRecordSets             |
+--------------------------------------------------+
||                   ChangeInfo                   ||
|+--------------+---------------------------------+|
||  Comment     |  Update by update_office_ip.sh  ||
||  Id          |  /change/DEADBEEFV3RI3          ||
||  Status      |  PENDING                        ||
||  SubmittedAt |  2018-12-06T07:53:08.504Z       ||
|+--------------+---------------------------------+|
Notifying upstream projects of job completion
Finished: SUCCESS

これで次回から office.example.com で常に Office の Public IP が取得できるようになりました。

それでは、リモートワーク・VPNライフを、固定IP無しでお楽しみ下さい。