Route53を使ったDynamicDNSサービスの運用

· 2 min read
Route53を使ったDynamicDNSサービスの運用

Route53はAWSのサービスですので、APIが存在します。
またawsコマンドで操作も出来ます。

固定IPをもっていない自宅サーバでもDNSで検索できるようなDynamic DNSサービスも簡単に作れます。
ということで、コマンドラインでの設定方法を説明します。


前提条件

・自宅サーバに立てた仮想サーバ上で動かす。OSはRHEL7.4(CentOSでもだいじょうぶ)

・ドメインは既にRoute53に登録してあること

・IAMユーザのアクセスキーを作成して、Route53を操作できるIAMロールを割り当てておきます。 
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_credentials_access-keys.html 
http://docs.aws.amazon.com/ja_jp/IAM/latest/UserGuide/id_roles.html

AWS CLIをインストールする

公式のリファレンスを参考してインストールします。 
http://docs.aws.amazon.com/ja_jp/streams/latest/dev/kinesis-tutorial-cli-installation.html

  1. pip のウェブサイトからインストールスクリプトをダウンロードし実行します。 
    https://pip.pypa.io/en/latest/installing.html
curl "https://bootstrap.pypa.io/get-pip.py" -o "get-pip.py"
sudo python get-pip.py
  1. pip を使用して AWS CLI をインストールします。
sudo pip install awscli

AWS CLI の設定

aws configure コマンドでIAMユーザの設定をしておきます。

# aws configure
AWS Access Key ID [None]: AKIAIOSFODNN7EXAMPLE
AWS Secret Access Key [None]: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
Default region name [None]: us-west-2
Default output format [None]: json

jqコマンドをインストール

jsonの結果を整形する必要がある為、jqコマンドをインストールします。

sudo curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && sudo chmod +x /usr/local/bin/jq
# jq -V
jq-1.5

Hosted Zone IDの取得

まずは登録しているドメインのHosted Zone IDを調べます。
以下のようなコマンドで調べられます。

aws route53 list-hosted-zones | jq '.HostedZones[] |  {Name , Id } '

実行すると下記のように出力されます。

{
  "Name": "hdserver.info.",
  "Id": "/hostedzone/ZZZZZXXXX3333"
}

この例だと hdserver.info がドメインで、ZZZZZXXXX3333 がhosted zone IDになります。

レコード登録スクリプト

こちら登録スクリプトになります。
スクリプト中の2つのシェル変数を設定してください。

# vi route53_upsert.sh

#!/bin/bash/

DOMAIN_NAME=""              # ★ドメイン名
HOSTED_ZONEID=""            # ★Hosted zone ID
MY_IP=`curl -s ifconfig.io`       # 現在のGIPを確認
NOW_IP=`dig $DOMAIN_NAME +short`  # Route53に登録されているGIPを確認
DATE=`date +"%Y/%m/%d %I:%M"`

if [ -z $MY_IP ];then
  exit 1
fi

if [ $MY_IP != $NOW_IP ];then
SET=`cat <<EOS
{
 "Comment": "update A record $DATE",
 "Changes": [
  {
   "Action": "UPSERT",
   "ResourceRecordSet": {
    "Name": "$DOMAIN_NAME.",
    "Type": "A",
    "TTL": 300,
    "ResourceRecords": [
     {
      "Value": "$MY_IP"
     }
    ]
   }
  }
 ]
}
EOS`

aws route53 change-resource-record-sets --hosted-zone-id $HOSTED_ZONEID --change-batch "${SET}" | logger -t route53_upsert
fi

ポイントとしてはグローバルIPを調べるためにcurlとdigコマンドを使用していることと、 awsコマンドの実行結果をloggerコマンドでsyslogに吐き出していることです。

実行すると /var/log/messages にこんな感じで出力されます。

# tail /var/log/messages
Nov 24 13:10:29 HD_RHEL route53_upsert: {
Nov 24 13:10:29 HD_RHEL route53_upsert:    "ChangeInfo": {
Nov 24 13:10:29 HD_RHEL route53_upsert:        "Status": "PENDING",
Nov 24 13:10:29 HD_RHEL route53_upsert:        "Comment": "update A record 2017/11/24 01:10",
Nov 24 13:10:29 HD_RHEL route53_upsert:        "SubmittedAt": "2017-11-24T04:10:28.978Z",
Nov 24 13:10:29 HD_RHEL route53_upsert:        "Id": "/change/ZZZZZXXXX3333"
Nov 24 13:10:29 HD_RHEL route53_upsert:    }
Nov 24 13:10:29 HD_RHEL route53_upsert: }

StatusがPENDINGとなっていますが、登録されると現在のGIPで名前解決ができる様になります。
cron等にいれればIPが更新されても大丈夫です。

参考 
https://qiita.com/tt2004d/items/21c2001bb758dfa6ddde 
https://qiita.com/wnoguchi/items/70a808a68e60651224a4 
https://blog.tonbiworks.com/infrastructure/2016/08/09/awscli-route53/ 
http://ysweb.blog116.fc2.com/blog-entry-19.html