自宅ラズパイ鯖をCLOUD FLAREでDDNS登録した備忘録（Aレコード定期更新）

## 経緯
ラズパイ（Bookworm）でサーバーやWEBサイトの勉強をしています。

勉強の延長線で、2つのDDNSを利用して公開WEBサーバーと踏み台サーバーを作ろうと計画中。固定IPは割高！VPSも自分にはもったいない！という考えから、DDNSによる公開WEBサーバーと踏み台サーバーを作っていこうと考えています。

今まで自宅へのVPNアクセスにはduckdns（DDNSサービス）を利用していましたが、今回はきちんとしたドメインでDDNSしたいため、新規でドメインを取得するところから始めました。

## 今回の流れ
0．DDNS用ドメイン調達先の選定
1．ドメインの新規取得
2．サブドメインの払い出し（Aレコード方式） ※IP初期値はCLOUD FLAREのDNS（1.1.1.1）に向けておきました
3．DNS更新用APIの払い出し
4．APIトークン発行
5．ゾーンIDメモ
6．Aレコード更新用スクリプトの作成

## CLOUD FLARE でのDDNSを採用
調べてみると、CLOUD FLARE は、ドメインの取得、更新料金も国内のドメイン取得サービスより割安、DDNSするのに都合のよいDNS更新用のAPIが整備されていました。

## CLOUD FLARE ドメインの新規取得
直前に他所でjpドメインを購入してしまっていたのですが、CLOUD FLAREにはJPドメインを移管できないことがわかり、新規で取得しました。

## サブドメインの払い出し
CLOUDFLAREのダッシュボードはわかりづらかったです。
レコードの払い出し画面までの遷移は次のとおりでした。参考にしてください。

wwwwwwwwwwwwwwwwwwwwww
ログイン後ダッシュボード
↓
メニュー「WEBサイト」
↓
該当のプライマリドメイン名（hogehoge.hoge）を選択
↓
メニュー「DNS」
↓
レコード
wwwwwwwwwwwwwwwwwwwwww

## APIトークンの発行&メモ
CLOUDFLAREの管理画面でこちらも迷いました。こちらの遷移も記載しておきます。APIトークンはDNS編集権限のついたものを作成してください。

wwwwwwwwwwwwwwwwwwwwww
ログイン後ダッシュボード
↓
マイプロフィール
↓
メニュー「APIトークン」
↓
トークンを作成する
wwwwwwwwwwwwwwwwwwwwww

## ゾーンIDのメモ
こちらも遷移を記載しておきます。

wwwwwwwwwwwwwwwwwwwwww
ログイン後ダッシュボード
↓
メニュー「WEBサイト」
↓
該当のプライマリドメイン名（hogehoge.hoge）を選択
↓
遷移後ページの右下
wwwwwwwwwwwwwwwwwwwwww

## ラズパイ（Bookworm）で動くAレコード更新用スクリプトの作成
[こちらの記事](https://b.muo.jp/2020/03/27/cloudflare-dyndns.html)を参考にさせていただきました。
CLOUD FLAREで Aレコード更新するための成果物は次のとおり

```bash:update_cloudflare_dns.sh
#!/bin/bash

# 設定
LASTIPFILE=$(realpath ~/.lastipaddr)
HOST="hoge.hoge.com"
APITOKEN="********************************" # トークンを入力
ZONEID="*****************************" # Zone IDを入力

# DNSレコードIDを取得
RECORDID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records?type=A&name=$HOST" \
     -H "Authorization: Bearer $APITOKEN" \
     -H "Content-Type: application/json" | jq -r '.result[0].id')

# 現在のグローバルIPアドレスを取得
IP=$(curl -s https://checkip.amazonaws.com)
if [ -z "$IP" ]; then
  echo "グローバルIPアドレスの取得に失敗しました。ネットワークがダウンしている可能性があります。"
  exit 1
fi

# LASTIPFILEにアクセスできるか確認
if ! touch $LASTIPFILE; then
  echo "\"$LASTIPFILE\"にアクセスできません。権限設定を確認してください。"
  exit 2
fi

# 最後に記録されたIPアドレスを読み込む
LASTIP=$(<$LASTIPFILE)
if [ "$IP" != "$LASTIP" ]; then
  echo "DNSレコードを更新しています..."
  # Cloudflare APIを使用してDNSレコードを更新
  RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONEID/dns_records/$RECORDID" \
     -H "Authorization: Bearer $APITOKEN" \
     -H "Content-Type: application/json" \
     --data "{\"type\":\"A\",\"name\":\"$HOST\",\"content\":\"$IP\",\"ttl\":120,\"proxied\":false}")

  # 応答から成功したかどうかを判断
  SUCCESS=$(echo $RESPONSE | jq -r '.success')
  if [ "$SUCCESS" == "true" ]; then
    echo $IP > $LASTIPFILE
    echo "成功しました"
  else
    echo "DNSレコードの更新に失敗しました。"
  fi
else
  echo "IPアドレスは変更されていません。更新は必要ありません。"
fi
```

上記を動かすためにはJSONを処理するためのjqのインストールが必要です
```bash:bash
sudo apt-get update
sudo apt-get install jq
```

スクリプトに実行権限を与えてから実行する。
```bash:bash
chmod +x update_cloudflare_dns.sh
./update_cloudflare_dns.sh
```

DNSに現在のラズパイ鯖のグローバルIPアドレスが登録されているはず！
CLOUD FLAREに登録されているドメインのDNS情報（IP）が更新されているか確認してみてください。

ちなみに、現在のグローバルIPアドレスを調べるコマンドは以下

```bash:bash
curl https://checkip.amazonaws.com
```


## おわってからの振り返り色々
CLOUD FLAREで挑戦する前に、お名前ドットコムでドメイン購入してDDNSできないか思案したのですが、DDNSとして利用するためのAPIなどが揃っていなそうでした。CNAMEで諦めようかとも思ったのですが、タイムラグなども気になり、沼にはまりました。そして、最終的にCLOUD FLAREにたどりつきました。
事前調査が甘かったです。
そもそもDDNSを自身の保有するドメインで実現したいという需要も少ないと思いますが、このケースではCLOUD FLAREが費用対効果がよさそうに感じました。