Synology NASでWebサイト(Web Stationなど)を構築する場合、動的に変化する自宅回線のグローバルIPアドレスに対応するため、DDNS(Dynamic DNS)を利用するのが一般的です。
DDNSとは、IPアドレスが変わっても常に同じドメイン名でアクセスできるようにする仕組みで、Synology純正DDNSをはじめ、いくつかの選択肢があります。
独自ドメインを使用する前提でSynology NAS上にWebサイトを公開する場合、無料で高機能なDNSおよびセキュリティ機能を提供する Cloudflare DNS は、非常に有力な選択肢の一つです。
ただし、CloudflareのDNSをDDNS用途として利用する場合、Synology標準のDDNS機能は使用できないため、CloudflareのWeb APIを用いてDNSレコードを自動更新する仕組みを別途構築する必要があります。
本記事では、実際にSynology NAS上でCloudflare APIを用いたDDNS構成を実現した例をもとに、設定方法と運用上のポイントを紹介します。
以下の記事で、Synology NASに構築したWebサイトに独自ドメインを設定し、Let's EncryptによるSSL証明書を設定してWebサイトを常時HTTPS化設定する手順について紹介しています。
参考 Synology NASで構築したWebサイトに独自ドメイン設定およびLet’s EncryptによるHTTPS化設定
上記記事内では、DDNSサービスとしてMyDNS.JPによるDDNSを用いていましたが、この度、DDNSサービスとしてCloudflareのDNSに移行しましたので、本記事では、実際にSynology NAS上でCloudflare APIを用いたDDNS構成を実現した例をもとに、設定方法と運用上のポイントを紹介します。
※)本記事ではCloudflareのCDNやWAF、プロキシ機能の設定については扱いません。
前提 本記事でのDSM(OS)バージョンはSynology DSM 7.3を用いています。
1.Cloudflareとは
Cloudflareは、DNSホスティング、CDN、WAFなどを提供するグローバルなインターネットインフラサービスです。
DNSサービスは高速かつ安定しており、APIを通じたレコード操作にも対応しています。
一般的にはリバースプロキシとしてトラフィックをCloudflare経由にする使い方が多いですが、本記事ではプロキシ機能は利用せず、DNSを動的に更新するDDNS用途に限定して使用します。
Cloudflare APIを用いてAレコード、およびAAAAレコードを自動更新することで、独自ドメインを用いたDDNS構成を実現します。
2.Cloudflareにドメインを登録する
すでにCloudflareへのアカウント登録は済である前提です。
[アカウントホーム]>[ドメインのオンボード]を選択し、ドメイン入力欄に移行元のドメインを入力し、「DNSレコードのクイックスキャン」または「DNSレコードの手動で入力する」を選択して、[続行]を選択します。

3.CloudflareのDDNSレコード編集
「DNSレコードのクイックスキャン」を選択した場合は、入力したドメインの既存DNSレコードを自動スキャンします。「DNSレコードの手動で入力する」の場合は全て自分で別途入力が必要です。
[DNS]>[レコード]を選択し、Aレコード(IPv4アドレスのレコード)とAAAAレコード(IPv6アドレスのレコード)を必要に応じて編集します。
「DNSレコードのクイックスキャン」を選択した場合は、現状のIPアドレスが入力済ですので、内容に齟齬がないかを確認しておきます。
「プロキシステータス」はDNSのみ(灰色雲マーク)としておきます。
入力完了したら[保存]をクリックしてレコードの編集内容を確定させます。

AレコードとAAAAレコードが編集できたら、CloudflareネームサーバのNSの内容をメモっておきます。(ネームサーバ委譲の設定で必要となるため)

4.CloudflareDNSへのネームサーバ委譲
ドメインレジストラについてはXServerDomainを使用しているため、XServerDomainの管理画面でネームサーバーの委譲(CloudflareにDNSの管理を行わせる設定)を実施する必要があります。
Cloudflareで新規ドメインの取得を行ったり、ドメインレジストラをCloudflareに移管した場合は本手順は必要ありません。
(XServerDomaini以外のレジストラの場合も同様な手順があると思いますので、適宜読み替えてください。)
Xserverドメインの管理ページの左側メニューにある[ネームサーバ設定]をクリックします。
XServerDomainのネームサーバ設定で、ドメイン適用先サービスのネームサーバーをCloudflareネームサーバのNSの内容に設定します。

確認画面で[設定を変更する]をクリックし、ネームサーバ設定を確定させます。本設定で、Xserverドメインで登録したドメインをCloudflareのDNSで使用可能となります。
5.DNSレコード自動更新の設定
Synology DSMのDDNS登録サービス(コントロールパネル>外部アクセス>DDNS)には、Cloudfrareに対応したDDNS登録の仕組みがサポートされていないため、独自スクリプトを実装してDNSレコードの自動更新の仕組みを構築します。処理概要としては、Synology NASのグローバルアドレスを取得し、CloudflareのAPIを用いてDNSレコードの更新を行うものとします。これをタスクスケジューラに登録して定周期実行させます。
5-1.Cloudflareの情報取得
CloudflareのAPI操作を行うために以下2つの情報を予め取得する必要があります。
ゾーンID
Cloudflareのダッシュボードのアカウントホームよりアカウントを選択し、[概要]ページに移動し、ページ下部にあるAPIセクションに表示されていますのでこの値を取得しておきます。

APIトークン
APIトークンはDNS編集に必要な最小権限のものを作成します。
Cloudflareのダッシュボードのアカウントホームより[ アカウントの管理] >[ アカウントAPIトークン]ページに移動し、[トークンを作成する]ボタンをクリックします。

APIトークンテンプレートの[ゾーンDNSを編集する]を選択します。
必要事項が予めプリセットされていますので、[ゾーン」のみ選択して、[確認に進む]をクリックします。

次のページで[トークンを作成する]をクリックすると、トークンが作成され、APIトークンが表示されます。
APIトークンはこのページを離れると2度と表示できないため、内容をコピーして保存しておきます。

5-2.スクリプトの実装
取得した情報をもとにDNSレコードを更新するスクリプトを実装します。
既に同様なスクリプトが公開されているのかもしれませんが、探すのが面倒だったのと、大した内容でなさそうなので自作しました。(正確には仕様を提示してChatGPTに作ってもらいました。)
bashスクリプトで、以下のような内容としています。
- IPV4とIPV6のグローバルアドレスを取得
- CloudflareのDNSレコードをAPIを用いて取得(参照)
- グローバルアドレスとDNSレコードを比較し、差分があればAPIを用いて更新
- エラーやWarning事象についてはloggerコマンドを用いてSynologyのログセンターに出力
cloudfrare_ddns.conf
#!/bin/bash
# ========================================
# Synology DSM Cloudflare DDNS 更新スクリプト
# IPv4 / IPv6 同時対応 / 複数レコード対応(効率化版)
# ========================================
# スクリプト自身のディレクトリを取得
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
CONFIG_FILE="${SCRIPT_DIR}/cloudflare_ddns.conf"
# 設定ファイルが存在するか確認
if [ ! -f "$CONFIG_FILE" ]; then
echo "[ERROR] Config file not found: $CONFIG_FILE"
exit 1
fi
# 設定を読み込み
source "$CONFIG_FILE"
NOW=$(date '+%Y-%m-%d %H:%M:%S')
# 現在のグローバルIPを取得
# IPv4取得
CURRENT_IPV4=$(curl -s --max-time 10 https://checkip.synology.com | grep -oE '([0-9]{1,3}\.){3}[0-9]{1,3}')
if ! [[ $CURRENT_IPV4 =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
logger -n localhost -P 514 --rfc3164 -t DDNS -p local1.info "$NOW : ERROR - Failed to get valid IPv4 address"
CURRENT_IPV4=""
fi
# IPv6取得
CURRENT_IPV6=$(curl -6 -s --max-time 10 https://ifconfig.co)
if ! [[ $CURRENT_IPV6 =~ ^([0-9a-fA-F:]+)$ ]]; then
logger -n localhost -P 514 --rfc3164 -t DDNS -p local1.info "$NOW : ERROR - Failed to get valid IPv6 address"
CURRENT_IPV6=""
fi
# Cloudflareのゾーン内全DNSレコードを取得
ALL_RECORDS=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json")
# レコードごとに処理
for NAME in "${RECORDS[@]}"; do
for TYPE in A AAAA; do
if [ "$TYPE" = "A" ]; then
CURRENT_IP=$CURRENT_IPV4
else
CURRENT_IP=$CURRENT_IPV6
fi
# 無効なIPならスキップ
if [ -z "$CURRENT_IP" ]; then
continue
fi
# 該当レコード情報を抽出
RECORD_INFO=$(echo "$ALL_RECORDS" | jq -r --arg name "$NAME" --arg type "$TYPE" '
.result
| map(select(.name==$name and .type==$type))
| .[0]
| {id: .id, content: .content, proxied: .proxied, ttl: .ttl}
')
RECORD_ID=$(echo "$RECORD_INFO" | jq -r '.id')
CF_IP=$(echo "$RECORD_INFO" | jq -r '.content')
CF_PROXIED=$(echo "$RECORD_INFO" | jq -r '.proxied')
CF_TTL=$(echo "$RECORD_INFO" | jq -r '.ttl')
# ttlがnullや空の場合は Auto (1) にフォールバック
if [ -z "$CF_TTL" ] || [ "$CF_TTL" = "null" ]; then
CF_TTL=1
fi
# レコードが存在しない場合はスキップ
if [ -z "$RECORD_ID" ] || [ "$RECORD_ID" = "null" ]; then
logger -n localhost -P 514 --rfc3164 -t DDNS -p local1.info "$NOW : $TYPE $NAME not found in Cloudflare, skipping."
continue
fi
# 差分があれば更新
if [ "$CURRENT_IP" != "$CF_IP" ]; then
logger -n localhost -P 514 --rfc3164 -t DDNS -p local1.info "$NOW : Updating $TYPE $NAME ($CURRENT_IP != $CF_IP)"
RESPONSE=$(curl -s -X PATCH "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
-H "Authorization: Bearer $API_TOKEN" \
-H "Content-Type: application/json" \
--data "{
\"type\":\"$TYPE\",
\"name\":\"$NAME\",
\"content\":\"$CURRENT_IP\",
\"ttl\":$CF_TTL,
\"proxied\":$CF_PROXIED
}")
logger -n localhost -P 514 --rfc3164 -t DDNS -p local1.info "$NOW : $TYPE $NAME response: $RESPONSE"
fi
done
done
cloudfrare_ddns.conf(スクリプトと同じフォルダに配置し、API更新のための情報と更新対象のレコードを記載する)
# Cloudflare DDNS 設定ファイル
ZONE_ID="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
API_TOKEN="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
# 更新対象レコード(スペース区切りで列挙)
RECORDS=(
"example.com"
"aaa.example.com"
"bbb.example.com"
)
5-3.スクリプトの定期実行設定
上記スクリプト本体と設定ファイル(設定内容を定義したもの)をSynology NASの管理者アカウントのホームディレクトリ以下にサブディレクトリ(例:cloudfrare_script)を作成して格納します。
[コントロールパネル]>[タスクスケジューラ]>[作成]>[予約タスク]>[ユーザ指定のスクリプト]を選択
タスク:適切な名称(例:cloudfare_DDNS等)を入力
ユーザー:実行ユーザですが、root権限は不要なので管理者アカウントで問題ありません。

スケジュール画面で10分周期の実行を設定します。
開始時刻:00:00
繰り返し:10分ごと
最終実行時刻:23:50

タスク設定画面で[ユーザー指定のスクリプト]欄にスクリプトのフルパスを記載します。
入力完了したら[OK]ボタンをクリックして確定させます。

6.注意点
6-1.TTLとIP変更頻度について
TTL設定について
本記事の構成では、DNSレコードのTTLは Cloudflareの「自動(Auto)」設定 を使用しています。
CloudflareにおけるTTL自動設定は実質的に 約5分 となっており、DDNS用途として十分に短く、安定した値です。
TTLを手動で最短値に設定することも可能ですが、本構成ではIPアドレスの変更頻度が高くないこと、および運用の簡素化を優先し、TTLは自動設定のままとしています。
スクリプト実行間隔の考え方
スクリプト実行間隔がTTL(約5分)より長いため、IPアドレス変更からDNSレコード更新までに最大でスクリプト実行間隔分(約10分) の遅延が発生する可能性があります。
ただし、DNSレコード更新後はTTL相当の時間経過後に新しいIPアドレスが参照されるため、実運用上は大きな問題にならないと判断しています。
IPアドレス変更時の挙動まとめ
本構成における、IPアドレス変更時の最大遅延は以下の通りです。
- IP変更検知まで:最大 約10分
- DNSキャッシュ切り替え:最大 約5分
合計で 最大約15分程度 の遅延が発生する可能性があります。
本記事の想定用途では、この遅延は許容範囲としています。
運用方針としての割り切り
Pアドレス変更がより頻繁に発生する環境や、即時性が求められる用途では、スクリプト実行間隔を短くする、もしくはTTLを手動設定するなどの調整が必要になります。
本記事では、
「過剰に短い間隔で更新しない」ことを前提とした、安定性と運用負荷のバランスを重視した設定
を採用しています。
6-2.プロキシ設定(オレンジ雲)について
Cloudflareでは、DNSレコードをプロキシ化(オレンジ雲)することで、CDNやWAFなどの機能を利用できます。
しかし本記事では、CloudflareをDDNS用途として使用することを目的としているため、DNSレコードは基本的にプロキシ無効(グレー雲)で運用します。
なお、将来的にWebサイト公開用途としてCloudflareのプロキシ機能を利用する場合は、DNSレコード更新自体は同じ仕組みで継続利用できます。










