Cloudflare ハンズオン教科書|2026-08 版
第 15 章

CDN・DNS・カスタムドメイン

Cloudflare の原点。キャッシュと DNS を理解して独自ドメインで公開する

この章で学ぶこと

リバースプロキシとしての Cloudflare — オレンジクラウドの意味

Cloudflare の原点は、訪問者とオリジンサーバーの間に立つリバースプロキシです。その入口を制御するのが DNS レコードごとの Proxy status で、ダッシュボードではオレンジ色の雲アイコンで表示されます。

Proxied(オレンジクラウド) ブラウザ DNS 応答 = anycast IP → HTTP はここへ Cloudflare エッジ キャッシュ・WAF・DDoS 防御 キャッシュミス時のみ オリジン 実 IP は隠れ、ゾーン設定が効く DNS only(グレークラウド) ブラウザ DNS 応答 = 実 IP → 直接オリジンへ エッジは挟まらない オリジン 実 IP が露出し、保護は効かない
図 15-1 オレンジクラウドが変えるのは DNS の応答内容で、その結果 HTTP 経路に 1 段増えます。増えた 1 段だけがキャッシュ・WAF・DDoS 防御の効く場所で、右側にはその段が無いため実 IP がそのまま外に見えます。

Proxied にできるのは IP 解決に使われる A / AAAA / CNAME レコードのみで、MX や TXT などは常に DNS only です。Web トラフィックを配信する A / AAAA / CNAME は Proxied にすることが推奨され、ダッシュボードからのドメイン追加時は既定で Proxied になります。逆に、メール関連レコードやサードパーティのドメイン所有権確認用 CNAME は DNS only にします。

TypeNameContentProxy statusDNS 応答
Ablog192.0.2.1ProxiedCloudflare の anycast IP
Ashop192.0.2.2DNS only192.0.2.2(実 IP が露出)

Proxied レコードの TTL は Auto(300 秒)固定で編集できません。Cloudflare 側の anycast IP 変更を素早く反映するための仕様です。また、同名の A / AAAA レコードが複数あり 1 つでも Proxied なら、その名前の全 A / AAAA レコードが Proxied として扱われる点も覚えておきましょう。詳細は Proxy status を参照してください。

ドメインを Cloudflare に載せる — ネームサーバー移管と SSL/TLS

独自ドメインで Cloudflare の機能を使うには、ドメインをゾーンとして Cloudflare アカウントに登録します。最も一般的なのは、Cloudflare を権威 DNS プロバイダーにする full setup(primary setup)で、Free / Pro プランで使える唯一の方式です。流れは 4 ステップです。

  1. ドメインの追加 — ダッシュボードの Domains ページで「Onboard a domain」を選び、apex ドメイン(例: example.com)を入力してプランを選択します。既存の DNS レコードは quick scan で自動インポートできます(すべて拾える保証はないので必ずレビュー)。
  2. DNS レコードのレビュー — apex・www・メール関連(MX / SPF / DKIM / DMARC)の各レコードが揃っているか確認し、A / AAAA / CNAME の Proxy status を用途に応じて調整します。
  3. ネームサーバーの変更 — ゾーンに 2 つの Cloudflare ネームサーバーが割り当てられるので、ドメインを購入したレジストラ側の管理画面でネームサーバーをその 2 つに書き換えます。反映されるとゾーンが Active になります。
  4. SSL/TLS の確認 — ゾーンが Active になると、Universal SSL により無料の DV 証明書が自動発行・自動更新されます。full setup では apex と第 1 レベルのサブドメイン(www.example.com など)をカバーします。

なお Cloudflare Registrar で購入したドメインは最初から Cloudflare ネームサーバーを使うため、移管作業自体が不要です。レジストラがネームサーバー変更を許さない場合は、Business 以上で使える partial(CNAME)setup という選択肢もあります。

SSL/TLS 暗号化モードの基本

ゾーンの SSL/TLS Encryption Mode は、「訪問者 ↔ Cloudflare」と「Cloudflare ↔ オリジン」の 2 区間の暗号化方法を決める設定です。現在は既定の Automatic SSL/TLS がオリジンの証明書と対応状況を検査し、最も安全なモードを自動選択します(段階的ロールアウト中。手動で選ぶ Custom SSL/TLS も選択可能)。

モード訪問者 ↔ CloudflareCloudflare ↔ オリジンオリジン証明書の検証
OffHTTP のみHTTP のみ—
FlexibleHTTPS 可常に HTTP(平文)—
FullHTTPS 可訪問者側に合わせるしない(自己署名可)
Full (strict)HTTPS 可訪問者側に合わせるする(公的 CA / Cloudflare Origin CA)
Strict (SSL-Only Origin Pull)HTTP / HTTPS常に HTTPSする

Cloudflare は Full または Full (strict) の使用を強く推奨しています。Flexible は Cloudflare からオリジンへの通信が平文になるため、ログインや個人情報を扱うアプリでは使うべきではなく、オリジン設定によっては Mixed Content エラーやリダイレクトループの原因にもなります。詳細は Encryption modes を参照してください。

訪問者が HTTPS のとき、モードが決めるのは右の区間 訪問者 Cloudflare オリジン HTTPS 3 モード共通 Flexible HTTP(平文のまま) Full HTTPS(証明書は未検証) Full (strict) HTTPS(証明書を検証)
図 15-2 左の区間は 3 モードとも HTTPS なので、ブラウザの鍵マークはどのモードでも同じように出ます。モードが選び分けているのは右の 1 本だけで、Flexible ではそこが平文、Full は HTTPS でも証明書を見ないため自己署名のオリジンでも通り、そこまで検証するのが Full (strict) です。

CDN キャッシュの基本 — 何がキャッシュされ、どう制御するか

Proxied なホスト名への応答は、Cloudflare のデータセンターにキャッシュされ得ます。まず押さえるべき既定動作は次のとおりです。

よく使う Cache-Control ディレクティブの例です。s-maxage は共有キャッシュ(CDN)専用の TTL で、ブラウザには無視されます。

Cache-Control: public, max-age=86400          # どのキャッシュにも 1 日保存
Cache-Control: no-store                       # 一切キャッシュさせない
Cache-Control: public, max-age=7200, s-maxage=3600  # CDN は 1 時間、ブラウザは 2 時間
Cache-Control: max-age=600, stale-while-revalidate=30  # 失効後 30 秒は stale 配信しつつ裏で再検証

CF-Cache-Status ヘッダーの読み方

キャッシュの実挙動は、応答の CF-Cache-Status ヘッダーで確認できます。主な値を挙げます。

値意味
HITキャッシュから配信された
MISSキャッシュ対象だが未保存だったため、オリジンから取得した
EXPIREDキャッシュにあったが失効しており、オリジンから取得した
DYNAMICリクエスト時点でキャッシュ対象外と判定(拡張子が対象外で、ルールもない)
BYPASS対象ではあったが、オリジン応答側の事情(no-store / private / Set-Cookie 等)でキャッシュしなかった
REVALIDATED / UPDATINGオリジンへの再検証を経て(または裏で再検証しつつ)キャッシュから配信

DYNAMIC と BYPASS の区別が重要です。DYNAMIC は「リクエスト時に対象外」、BYPASS は「対象だったが応答を見てやめた」を意味し、調査の起点が変わります。キャッシュから配信された応答には、キャッシュ滞在秒数を示す Age ヘッダーが付きます。

CF-Cache-Status は 2 か所の判定で決まる エッジにリクエスト到着 URL と Cache Rules を照合 キャッシュ対象? 対象外(HTML・JSON 等) DYNAMIC リクエスト時に確定 はい(既定の拡張子) 有効な複製あり? 複製あり(新鮮) HIT キャッシュから配信 なし・失効(EXPIRED) オリジンから取得し 応答ヘッダーを見る no-store / private / Set-Cookie BYPASS 応答時に確定 保存できる応答 MISS オリジンから取得し保存
図 15-3 縦の流れを 2 つの判定が分けています。DYNAMIC は最初の箱を出た時点、つまりリクエストを見ただけで確定するので調査先は Cache Rules です。BYPASS は強調した箱を通った後、オリジンの応答ヘッダーを見て確定するので調査先はオリジンです。同じ「キャッシュされない」でも切り分けの入口が違います。

Cache Rules とパージ

既定動作を変えたいときは Cache Rules を使います。マッチ条件(ホスト名・パス等)に対して「キャッシュ対象にする / しない」「Edge TTL・Browser TTL の上書き」などを宣言でき、HTML をキャッシュさせる用途が典型です。全プランで利用でき、ルール数はプランで異なります(2026-08 時点: Free 10 / Pro 25 / Business 50 / Enterprise 300)。Cache Rules は対象の DNS レコードが Proxied であることが前提です。

更新したコンテンツを即時反映するにはキャッシュパージを使います。推奨は URL 指定の single-file purge で、パージ後の次リクエストは MISS になりオリジンの最新版が再取得されます。ほかにホスト名・タグ・プレフィックス指定や purge everything があり、レート制限はアカウント単位です(2026-08 時点: single-file は Free で毎秒 800 URL、hostname / tag / prefix / everything 系は Free で毎分 5 リクエスト)。

Workers を独自ドメインで公開する

ここまでの Worker は <WORKER_NAME>.<サブドメイン>.workers.dev で公開してきました。workers.dev は即座に使えて便利ですが、Free 相当のサイトとして扱われる個人・ホビー用途向けの入口です。本番運用では独自ドメインへの接続が推奨され、方法は 3 つあります。

方法位置づけDNS / 証明書向くケース
workers.devWorker 作成時に自動付与されるサブドメイン不要(自動)試作・個人プロジェクト
Custom DomainWorker 自体がそのホスト名のオリジンになるDNS レコードと証明書を Cloudflare が自動作成Worker がアプリ本体(オリジン)のとき
RouteURL パターンにマッチしたリクエストで Worker を実行対象ホスト名の Proxied DNS レコードを自分で用意既存オリジンサーバーの前段に Worker を挟むとき

Custom Domain はゾーン内のドメイン / サブドメインを Worker に直結する方式で、追加すると Cloudflare が DNS レコードの作成と証明書(Advanced Certificate)の発行を代行します。パスやクエリは見ず、ホスト名の完全一致で全パスが Worker に向かいます(ワイルドカード不可。example.com に付けても www.example.com はカバーされません)。Wrangler 設定では routes に custom_domain: true を付けます。

{
	"routes": [
		{
			"pattern": "shop.example.com",
			"custom_domain": true
		}
	]
}

Route は subdomain.example.com/* のような URL パターンと Worker の対応付けです。対象ホスト名に Proxied な DNS レコードが存在することが前提で、ゾーンを zone_name か zone_id で指定します。

{
	"routes": [
		{
			"pattern": "subdomain.example.com/*",
			"zone_name": "example.com"
		}
	]
}
Custom Domain — Worker がホスト名の終点 ブラウザ shop.example.com の全パス Worker 別のオリジンは無い DNS レコードと証明書は自動作成 Route — 既存オリジンの前段に Worker を挟む ブラウザ example.com/api/* Worker fetch() で転送 既存オリジン Proxied な DNS レコードは自分で用意
図 15-4 違いは Worker の後ろに何があるかです。Custom Domain は Worker が終点なので DNS レコードと証明書まで Cloudflare が用意し、Route は既存オリジンの前段に割り込む形なので、宛先となる Proxied なレコードは自分で用意する必要があります。

設定に routes を追加してデプロイすると、workers_dev は明示しない限り false と推論され、workers.dev ルートは無効になります。明示的に制御したい場合は "workers_dev": false(または true)を書きます。詳細は Routes and domains を参照してください。

ハンズオン 15-1|Worker にカスタムドメインを設定する

第 2 章で作った Worker を独自ドメインのサブドメインで公開します。所要 10 分(ゾーンが Active になっていれば)。

独自ドメインが必要です。ドメイン未所持の場合も手順は読み物として完結するので、流れだけ押さえて workers.dev のまま先へ進んで構いません。ドメインは Cloudflare Registrar で購入でき、その場合ネームサーバー移管は不要です(ドメイン代のみ実費)。

  1. ゾーンが Active であることを確認する(ダッシュボードのゾーン Overview でステータス表示。他社レジストラのドメインは事前にネームサーバー移管を済ませる)
  2. Worker プロジェクトの wrangler.jsonc に Custom Domain を宣言する。<YOUR_DOMAIN> は自分の apex ドメインに置き換える
{
	"name": "my-worker",
	"main": "src/index.ts",
	"compatibility_date": "2026-08-01",
	"routes": [
		{
			"pattern": "hello.<YOUR_DOMAIN>",
			"custom_domain": true
		}
	]
}
  1. デプロイする
npx wrangler deploy
  1. 動作を確認する。DNS レコード作成と証明書発行は自動で行われる
curl -s https://hello.<YOUR_DOMAIN>/
# 第 2 章の Worker の応答(例: Hello Worker!)が返れば成功

ダッシュボードから設定する場合は、Workers & Pages で対象 Worker を選び Settings > Domains & Routes > Add > Custom Domain です。設定後、ゾーンの DNS Records ページに Worker 宛のレコードが自動作成されていることも確認しましょう。

ハンズオン 15-2|CF-Cache-Status でキャッシュ挙動を観察する

ドメインがなくても実施できます。Cloudflare 配下で運用されている公式ドキュメントサイトと自分の workers.dev URL に curl を打ち、ヘッダーからキャッシュ挙動を読み取ります。所要 5 分。

  1. Cloudflare 配下の静的アセットへ HEAD リクエストを送り、キャッシュ関連ヘッダーを見る
curl -sI https://developers.cloudflare.com/og-docs.png | grep -iE '^(cf-cache-status|cache-control|age):'

実行例(2026-08 時点の実測。値はアクセスするデータセンターの状態で変わる):

cf-cache-status: HIT
cache-control: public, max-age=0, must-revalidate
  1. 同じコマンドをもう一度実行し、値を比較する。最初が MISS や EXPIRED でも 2 回目は HIT になりやすい。HIT のとき Age ヘッダーが付けばキャッシュ滞在秒数が読める
  2. 自分の workers.dev URL にも同じ観察をする
curl -sI https://my-worker.<YOUR_SUBDOMAIN>.workers.dev/ | grep -iE 'cf-cache-status|cache-control'

Worker が直接生成した応答には CF-Cache-Status が付きません。Workers はキャッシュの手前に位置し、サブリクエストなしで返した応答はキャッシュを経由しないためです(ログ上は none/unknown 扱い)。「CDN キャッシュが効くのは Proxied なホスト名経由の配信」という位置関係を体感できれば成功です。

ハンズオン 15-3|キャッシュをパージして MISS に戻す

自分のゾーンでキャッシュ済みアセットを single-file purge し、HIT → MISS の遷移を観察します。所要 5 分(独自ドメインのゾーンが必要。未所持なら読むだけで OK)。

  1. 自分のゾーン配下でキャッシュされる URL(画像や CSS など既定対象の拡張子)に 2 回 curl し、cf-cache-status: HIT を確認する
  2. ダッシュボードでゾーンの Caching > Configuration を開き、Purge Cache > Custom Purge を選択
  3. Purge by で URL を選び、対象 URL を入力して Purge を実行(URL のパス部分は大文字小文字が区別される)
  4. 直後に同じ URL へ curl し、cf-cache-status: MISS に戻ったことを確認する
curl -sI https://<YOUR_DOMAIN>/style.css | grep -i cf-cache-status
# パージ前: cf-cache-status: HIT
# パージ後: cf-cache-status: MISS(次のリクエストで再キャッシュされる)

パージはアカウント単位のレート制限内で即時にグローバル反映されます。取り消しはできないので、purge everything はオリジン負荷が跳ねる点に注意してください。

つまずきポイント

ネームサーバー変更後もゾーンが Pending のまま / サイトに繋がらない。レジストラ側の反映には時間がかかり、ゾーン有効化の確認は最大 24 時間程度かかることがあります。また DNSSEC を有効にしたままネームサーバーを変えるとドメイン全体が到達不能になり得ます。移管前にレジストラ側で DNSSEC を必ずオフにし、Active 後に Cloudflare 側で再有効化してください。古い DS レコードが残っていないかも確認を。

Custom Domain が追加できない、または www で繋がらない。既存の CNAME レコードがあるホスト名には Custom Domain を作成できません。先にその CNAME を削除してから追加します。また Custom Domain はホスト名の完全一致なので、apex に付けただけでは www は動きません。www 側に Proxied なプレースホルダーレコード(A 192.0.2.0 または AAAA 100::)を作り、リダイレクトルールで apex へ転送するのが定石です。

HTML がキャッシュされない(DYNAMIC のまま)/ 予期せぬ BYPASS。Cloudflare の既定キャッシュは拡張子ベースで HTML / JSON は対象外です。キャッシュしたければ Cache Rules で「Eligible for cache」にします。ルールを作っても BYPASS になる場合は、オリジンが no-store / private / Set-Cookie を返していないかを疑ってください。判定の入口が違う(DYNAMIC = リクエスト時、BYPASS = 応答時)ことを思い出すと切り分けが速くなります。

無効化したはずの workers.dev ルートが復活する。ダッシュボードで workers.dev を無効化しても、Wrangler 設定に "workers_dev": false を書いていないと、次の npx wrangler deploy で再有効化されます。恒久的に無効化するなら必ず設定ファイル側に書いてください。

理解度チェック

Q1. Proxied(オレンジクラウド)にできる DNS レコード種別は? また Proxied にすると DNS 応答はどう変わる?

IP 解決に使われる A / AAAA / CNAME のみです(MX や TXT は常に DNS only)。Proxied のレコードへの DNS クエリにはオリジンの実 IP ではなく Cloudflare の anycast IP が返り、トラフィックが Cloudflare 経由になることでキャッシュ・DDoS 防御・WAF 等が適用されます。

Q2. CF-Cache-Status の DYNAMIC と BYPASS の違いは?

DYNAMIC は「リクエスト時点でキャッシュ対象外」と判定された状態(拡張子が既定対象外でルールもない等)。BYPASS は「リクエスト時点では対象だったが、オリジン応答の no-store / private / Set-Cookie などにより応答時点でキャッシュを見送った」状態です。前者はルール設定、後者はオリジンのヘッダーを調べます。

Q3. HTML ページは既定で CDN キャッシュされる? されない場合はどうする?

されません。Cloudflare の既定キャッシュはファイル拡張子ベースで、HTML と JSON は対象外です。キャッシュしたい場合は Cache Rules で対象パスを「Eligible for cache」にし、必要なら Edge TTL も設定します。

Q4. Custom Domain と Route はどう使い分ける?

Worker 自体がアプリのオリジンなら Custom Domain(DNS レコードと証明書を Cloudflare が自動作成し、そのホスト名の全パスが Worker に向く)。既存のオリジンサーバーがあり、その前段に Worker を挟むなら Route(URL パターンで発火し、対象ホスト名の Proxied DNS レコードを自分で用意する)です。

Q5. SSL/TLS 暗号化モードで Flexible が推奨されない理由は?

Flexible は訪問者 ↔ Cloudflare 間のみ HTTPS で、Cloudflare ↔ オリジン間が常に平文 HTTP になるためです。ログイン等の機微な情報を扱うサイトには不適切で、Mixed Content やリダイレクトループの原因にもなります。Cloudflare は Full または Full (strict) を強く推奨しています。

まとめと次章へ

次章では、動き始めたアプリを運用する視点に移ります。ログ・メトリクスなどの観測、デプロイのバージョン管理、そして料金の考え方を扱います。