CloudflareでDDNS

:::note warn
個人メモ
:::

### まとめ
下記APIを投げれば更新される
```shell:api
PUT
https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records/{dns_record_id}

HEADER
  Content-Type: application/json
  X-Auth-Email: {XAuthEmail}
  X-Auth:Key: {XAuthKey}

BODY
  {
      content:{content}
      name:{name}
      proxied:{proxied}
      type:{type}
      comment:{comment}
      tags:{tags}
      ttl:{ttl}
  }
```
:::note info
参考
[Cloudflare API Documentation](https://developers.cloudflare.com/api/operations/dns-records-for-a-zone-update-dns-record "Cloudflare API Documentation")
:::

### 手順

#### APIトークンの発行
##### ログイン～ドメイン画面の表示まで
下記にアクセスしてログイン
https://dash.cloudflare.com/login

下記画面が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/f63c99af-1cf3-12e8-98d1-f1d86ae21261.png)

下記画面で、自分のドメイン名をクリック（赤枠部分）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/454b7520-c877-9096-65bf-0cc260917e1b.png)

下記画面が表示される
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/7206cfae-8370-25a9-be71-d387240a6aab.png)

##### Global APIキー／APIトークンの取得
ドメインの画面で、「Get your API token」をクリックする（２つめの赤枠部分）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/e5b6aa7f-09dc-2e4c-f87c-8218a974b36d.png)

下記画面で、API KeysのGlobal API Keyにて「View」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/ed9dae53-58a2-3c96-a698-873cf9290cba.png)

パスワード入力を求められるので、パスワードを入力し「View」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/80367e9f-de29-fdf2-99a6-d89c5e4299ea.png)

API Keyが表示されるのでコピーしておく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/9aa4893b-a752-2f2a-9478-8355cefd7d33.png)

元の画面に戻るので、今度は「Create Token」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/5efeab1c-21b1-3f97-b302-5a3886930117.png)

下記画面で、Edit zone DNSの「Use template」をクリックする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/b8126816-9222-4d5f-0c07-6a9e85e35878.png)

下記画面で、以下情報を設定し「Continue to summary」をクリックする
+ Permissionsに下記を追加
  + Zone / DNS / Edit
    →　これから作るAPIトークンを使用して特定ZoneのDNSを編集できるようにする
  + Zone / Zone / Read
    →　これから作るAPIトークンを使用して特定ZoneのZone情報を取得できるようにする
+ Zone Resourcesに下記を追加
  + Include / Specific Zone / [選んだドメイン名]
    →　アクセスできるZoneを指定のドメインのみにする

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/50e78e58-4c85-6510-d9f6-95ac46bffd8c.png)

編集内容の概要がでてくるので、内容に問題がなければ「Create Token」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/ba0f1e56-33c5-50b8-4e4e-32fe6ec2af5e.png)

発行されたトークンが出てくるのでコピーして保存しておく（赤枠部分）
（この画面は１度しか表示されないため必ず保存すること）
※その下のTest this tokenのコマンドを実行すればテスト可能
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/c1841dd1-9fb4-ac58-53bf-303799117880.png)

#### Zone IDの取得
ドメインの画面で、Zone IDをコピーする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3492164/73124865-7e9f-68de-40c0-54a978d21c34.png)

もしくは下記コマンドを実行し取得する
```shell:コマンド
curl -w "\n" --request GET 
  --url https://api.cloudflare.com/client/v4/zones?name={ドメイン名} 
  --header "Content-Type: application/json" 
  --header "X-Auth-Email: {メールアドレス}"
  --header "X-Auth-Key: {Global API Key}"
```

#### DNS Record IDの取得
下記コマンドを実行し取得する
```shell:コマンド
curl -w "\n" --request GET 
  --url https://api.cloudflare.com/client/v4/zones/{Zone ID}/dns_records
  --header "Content-Type: application/json" 
  --header "X-Auth-Email: {メールアドレス}"
  --header "X-Auth-Key: {Global API Key}"
```

### 更新スクリプトの作成
自分のHomeディレクトリに下記を作成
```shell:コマンド
$ vi Cloudflare_IPUpdate.sh
```

```shell:Cloudflare_IPUpdate.sh
#!/bin/bash

# ドメイン名
DOMAIN_NAME="ktrnet.net"

# Cloudflareで取得したAPIトークン
API_TOKEN="hcG1ZC-slFWkbp62-axPqrUe45I09lPuYWhKvDLC"
# Cloudflareの登録メールアドレス
EMAIL="circle.ktrnet@gmail.com"
# Cloudflareで取得したZONE ID
ZONE_ID="e6d6e6619d25ded0ec613c9e7aff9e0c"
# Cloudflareで取得したRECORD ID
RECORD_ID="324476fc43c49db922b6571b98fe812c"

# 出力するログファイル
LOG_FILE="./Cloudflare_IPUpdate_log.txt"


# Get IP Address
# Global IP Addressを取得するサービスURLの一覧
services=(
    "https://domains.google.com/checkip"
    "https://checkip.amazonaws.com"
    "https://ipinfo.io/ip"
    "https://ipecho.net/plain"
    "https://api.ipify.org/"
    "https://ipv4.icanhazip.com/"
    "https://4.icanhazip.com/"
)

# 先頭のサービスURLから取得（失敗したら次のURLで取得を繰り返す）
for service in "${services[@]}"; do
    address=$(curl -s -4 "$service")
    if [[ $address =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        break
    fi
done

# ログ用に日時を出力
DATE_TIME=$(date +"%Y-%m-%d %H:%M:%S")
echo ${DATE_TIME} >> ${LOG_FILE}

# 更新APIの発行
curl -s -w "\n" --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: $EMAIL" \
    --header "Authorization: Bearer $API_TOKEN" \
    --data '{
        "content": "'"$address"'",
        "name": "'"$DOMAIN_NAME"'",
        "proxied": true,
        "type": "A",
        "comment": ""
    }' >> ${LOG_FILE}
```

実行権限を付加
```shell:コマンド
$ chmod +x Cloudflare_IPUpdate.sh
```

### 更新スクリプトのスケジュール化
crontabに登録
```shell:コマンド
$ sudo crontab -e
```

下記を登録
毎日01:00にシェルを実行する
```shell:
0 1 * * * /home/xxx/Cloudflare_IPUpdate.sh
```
:::note info
cronの設定内容
最初の５文字は、コマンドを実行するタイミング
順番に、「分　時　日　月　年」を示す
上記設定は、分：0、時：1のとき＝1時00分にコマンドを実行することを意味する
（*は設定なしを示す）
:::

以上

##### 参考
下記記事を参考にさせていただいています。
https://qiita.com/napspans/items/455103748f3a0dd7ee18
https://carloalbertoscola.it/2023/linux/infrastructure/how-to-update-dynamic-ip-cloudflare/
https://qiita.com/kazu_wsx/items/790a31409524d3b4e7fd