DDNSもどきを作ったメモ

メモなのでまとまってません

流れ

  1. Google Cloud Platform でDNS更新スクリプト用のサービスアカウントを取得(権限はCloud DNSのR/Wのみ)
  2. スクリプトを定期実行するための systemd-timer を設定、サービスを有効化

GCPのサービスアカウントを用意する

GCP > IAMと管理 > サービスアカウント から新規作成。権限はCloud DNSのみ

サービスアカウントキー(認証情報が入ったJSONファイル)が払い出されるので保存する。

gcloud auth activate-service-account --key-file /path/to/file/key.json

サービスアカウントの認証情報が追加される。

$ gcloud auth list

                  Credentialed Accounts 
ACTIVE  ACCOUNT 
*       fugafuga@hoge.iam.gserviceaccount.com
...

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

で確認できる。

認証情報はユーザー毎に保存されるため、sudoを使う場合は注意。

Systemd

/etc/systemd/system/gcloud-update-dns.service

[Unit]
Description=Update DNS Record through Google Cloud SDK

[Service]
Type=simple
ExecStart=/opt/gcloud/update-dns.sh
Restart=on-failure
StartLimitInterval=60s
StartLimitBurst=3
User=root

[Install]
WantedBy=multi-user.target

異常終了したら1分おきに3回まで再試行する。

/etc/systemd/system/gcloud-update-dns.timer

[Unit]
Description=DNS Update Timer

[Timer]
OnCalendar=*:0,30
Persistent=true

[Install]
WantedBy=timers.target

毎時00分と30分に実行する。

有効化・タイマーを確認

sudo systemctl enable gcloud-update-dns.timer
sudo systemctl enable gcloud-update-dns.service
$ systemctl list-timers --all
NEXT                         LEFT         LAST                         PASSED       UNIT                         ACTIVATES
Thu 2019-07-25 09:00:00 JST  8min left    Thu 2019-07-25 08:30:01 JST  21min ago    gcloud-update-dns.timer      gcloud-update-dns.service
...

5 timers listed.

更新スクリプト

#!/bin/bash

# DNS自動更新スクリプト

gcloud config set account "fugafuga@hoge.iam.gserviceaccount.com"
gcloud config set project "hoge"

ZONE="example-com"
DOMAIN="example.com."

CURRENT_IP=$(curl -sS inet-ip.info)
RECORD_IP=$(gcloud dns record-sets list --zone=${ZONE} --name=${DOMAIN} --type=A | grep "$DOMAIN" | awk '{ print $4 }')

echo "Debug: DNS=$RECORD_IP, SELF=$CURRENT_IP"
if [ "$CURRENT_IP" != "$RECORD_IP" ]; then
        echo "IP has changed! $RECORD_IP -> $CURRENT_IP"
        gcloud dns record-sets transaction start --zone=${ZONE}

        gcloud dns record-sets transaction remove --zone=${ZONE} --name=${DOMAIN} --type=A
        gcloud dns record-sets transaction add --zone=${ZONE} --name=${DOMAIN} --type=A --ttl=300 "${CURRENT_IP}"

        gcloud dns record-sets transaction execute --zone=${ZONE}
else
        echo "IP has not changed. (Current global ip address: $CURRENT_IP)"
fi
  • 自身のグローバルアドレスは外部サービスで取得している
  • 実際のレコードの書き換えは、「当該レコードを削除」→「新規レコードを作成」で行う

参考


全レコード確認

#!/bin/bash

for zone in $(gcloud dns managed-zones list | tail -n +2 | awk '{ print $1 }')
do
    echo "[$zone]"
    gcloud dns record-sets list --zone $zone | tail -n +2
    echo
done

ログ確認

sudo journalctl -u gcloud-update-dns.service
linux 

関連記事