前回Google DomainsからCloudFlareにドメインとDNSを移管する記事を書きました。
動的IPでwebサーバーを運用している方はIPが更新されたら通知してあげる必要があります。今回はこの手順について記述していきます。IP更新していくために材料をそろえるのが少しめんどくさいですがお付き合いください。
目次
前提
- CloudFlareでDNSを運用していること。
- Linuxサーバーでwebサーバーが運用されていること。
- sudo 権限
コード、コマンドの***で囲んでいるメールなどの情報は適宜自身の環境にあった項目に書き換えてください。
【材料1】 APIキーの取得
DNSを遠隔で編集するために、2種類の
上記リンクから自身のCloudFlaredのAPIトーク画面を開き、APIキーのGlobal API keyを表示します。
パスワードを入力し、表示された文字列をコピーしてグローバルAPIキーとわかるように保管しておきます。
次に、APIトーク画面に戻りトークンを作成します。
ゾーンDNSを編集する
のテンプレートで作成します。
次の画面でアクセス許可
とゾーンリソース
を編集します。
- アクセス許可
- ゾーン -> DNS -> 編集
- ゾーン -> ゾーン -> 読み込み
- ゾーンリソース
- 包含 -> 特定のゾーン -> ドメイン名
次の確認画面でドメイン名 - ゾーン:読み取り, DNS:編集
となっていればOKです。トークンを作成するをクリックしてください。
トークンが作成されたらAPIトークンとテストコードが発行されます。ここで表示されるキーはこの画面でのみ表示されますので、一度閉じると再表示できませんので大切に保管してください。先ほどと同様にDNS編集用トークンとわかるようにしましょう。DNSレコードを修正する場合はこちらのトークンを使用します。
表示されているテストコードを実行します。
curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify"
-H "Authorization: Bearer ***APIトークン***"
-H "Content-Type:application/json"
実行するとidなどが返ってきます。
{"result":{"id":"*****","status":"active"},"success":true,"errors":[],"messages":[{"code":10000,"message":"This API Token is valid and active","type":null}]}
This API Token is valid and active
とメッセージが入っていればAPIトークンアクセスは正常です。
【材料2】ゾーンIDの取得
curl -w "\n" --request GET \
--url https://api.cloudflare.com/client/v4/zones?name=***example.com*** \
--header 'Content-Type: application/json' \
--header 'X-Auth-Email: ***CloudFlareアカウントメールアドレス***'\
--header 'X-Auth-Key: ***グローバルAPIキー***'
出力が下記の通りとなっていれば成功です。jsonの"name":"example.com"
が自身のドメインとなっていれば"id":"***32文字乱数***"
がゾーンIDとなります。これ次の項で使用しますのでゾーンIDとわかるようにメモしておきます。
{"result":[{"id":"***32文字乱数***","name":"example.com","status":"active",...
【材料3】DNSレコードIDの取得
curl -w "\n" --request GET \
--url https://api.cloudflare.com/client/v4/zones/***ゾーンID***/dns_records \
--header 'Content-Type: application/json' \
--header 'X-Auth-Email: ***メールアドレス***'\
--header 'X-Auth-Key: ***グローバルAPIキー***'
ゾーンID取得と同様にjsonが帰ってきます。"zone_id":"***ゾーンID***"
の項目が入力したIDと合っていれば最初の項目の"id":"***32文字乱数***"
がDNSレコードIDになります。
"result":[{"id":"***32文字乱数***","zone_id":"***ゾーンID***",...
ここまでで取得したゾーンID、DNSレコードIDと最初に生成したAPIトークンを使ってIPを更新していきます。
シェルスクリプトの作成
遠隔でDNSのAレコードを更新する際には下記のコマンドを使います。
curl --request PUT \
--url https://api.cloudflare.com/client/v4/zones/***ゾーンID***/dns_records/***DNSレコードID*** \
--header 'Content-Type: application/json' \
--header "X-Auth-Email: ***メールアドレス***" \
--header "Authorization: Bearer ***APIトークン***" \
--data '{
"content": "'"***新しいIPアドレス***"'",
"name": "'"***更新するドメイン***"'",
"proxied": false,
"type": "A",
"comment": "Domain verification record"
}'
また、サーバーのIPアドレスが変更された際にサーバー自身は自分のアドレスを知ることができない為、ipアドレスを取得するサービスを利用して新しいIPを知る必要があります。ただし、回数制限やサービスエラーが起こった場合に対処するために複数のサービスで取得できるようにしておきます。
ip_address=""
# IPアドレスを取得する関数
get_ip_address() {
local url="$1"
ip_address=$(curl -s "$url")
}
# IPアドレスの正規表現パターン
ip_pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
# 正規表現でIPアドレスが検証できるかチェック
is_valid_ip() {
[[ $ip_address =~ $ip_pattern ]]
}
# IPアドレス取得のループ
for service in "${services[@]}"; do
get_ip_address "$service"
if is_valid_ip; then
break
fi
done
上記のコードを組み合わせてアクセス情報を追加したのが下記のコードになるので、update_ip.sh
など名前を付けて保存します。
#!/bin/bash
# 更新するドメイン
MY_DOMEIN="***sample.com***"
# API アクセス情報
ZONE_ID="***ゾーンID***"
RECORD_ID="***レコードID***"
AUTH_EMAIL="***メールアドレス***"
API_TOKEN="***APIトークン***"
# IPアドレス取得サービスのリスト
services=(
"https://api.ipify.org/"
"https://checkip.amazonaws.com/"
"https://ipv4.icanhazip.com/"
"https://4.icanhazip.com/"
)
ip_address=""
# IPアドレスを取得する関数
get_ip_address() {
local url="$1"
ip_address=$(curl -s "$url")
}
# IPアドレスの正規表現パターン
ip_pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
# 正規表現でIPアドレスが検証できるかチェック
is_valid_ip() {
[[ $ip_address =~ $ip_pattern ]]
}
# IPアドレス取得のループ
for service in "${services[@]}"; do
get_ip_address "$service"
if is_valid_ip; then
break
fi
done
# ipアドレス更新テスト
# ip_address = 8.8.8.8
# CloudFlare API Aレコード更新
curl --request PUT \
--url https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID \
--header 'Content-Type: application/json' \
--header "X-Auth-Email: $AUTH_EMAIL" \
--header "Authorization: Bearer $API_TOKEN" \
--data '{
"content": "'"$ip_address"'",
"name": "'"$MY_DOMEIN"'",
"proxied": false,
"type": "A",
"comment": "Domain verification record"
}'
私の場合はユーザフォルダの直下にscriptフォルダを作成し、その中に保存しています。
保存したらbushコマンドで実行してみます。
~$ bash script/update_ip.sh
実行結果としては大量のjsonオブジェクトが帰ってきますが、最後の方に"success":true
となっていれば更新が正常に行われています。不安な方はスクリプトの# ipアドレス更新テスト# ip_address = 8.8.8.8
をコメントアウトを削除して試してみるといいと思います。
..."success":true,"errors":[],"messages":[]}
Crontabで自動実行
作成したスクリプトを自動実行してもらえるようにcrontabに設定していきますが、その前にファイルの権限を変更します。
chmod +x script/update_ip.sh
次にcrontabを呼び出します。
sudo crontab -e
*/10 * * * * bash /home/napspans/script/update_ip.sh
追記したコマンドは10分毎に実行するコマンドです。各自サーバーの重要性に応じて設定してください。
追加したらctrl+X
で保存して終了です。
crontabで本当に実行されているか心配な方はスクリプトの最後に>> /path/to/update-ip.log 2>&1
を追加してログを取ってみるといいです。
curl --request PUT \
--url https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID \
--header 'Content-Type: application/json' \
--header "X-Auth-Email: $AUTH_EMAIL" \
--header "Authorization: Bearer $API_TOKEN" \
--data '{
"content": "'"$ip_address"'",
"name": "'"$MY_DOMEIN"'",
"proxied": false,
"type": "A",
"comment": "Domain verification record"
}'>> /path/to/update-ip.log 2>&1
まとめ
googleやmyDNSはwgetだけでペペっと簡単だったのに、今回はややこしかったですね。
以上で動的IPの方も安心して夜眠れると思います。
お疲れ様でした。 ではまた。
参考文献