Site search / サイト内検索

必要な情報を探す

ページ内の言葉を探す検索と、意味が近い内容を探す検索を使い分けられます。

「検索する」を実行すると、入力した検索語をOpenAI APIへ送り数値表現に変換し、その数値表現をCloudflare Vectorizeで当サイトの公開情報と照合します。あわせて、Acecore共通検索API(acecore.net)へ送信し、 Acecore関連サイトの公開情報を下部に表示することがあります。個人情報や機密情報は入力しないでください。個人情報の取り扱い

Insights / 技術解説

Cloudflare Pages で実現するセキュアな静的サイト配信

Cloudflare Pages での静的サイトデプロイと、_headers によるセキュリティヘッダー・CSP 設定の実践ガイドです。Worker から Pages に戻した経緯も紹介します。

  • 技術
  • Cloudflare
  • セキュリティ
Cloudflare Pages で実現するセキュアな静的サイト配信
この記事の目次
  1. デプロイ構成:Worker をやめて Pages に戻した理由
  2. _headers によるセキュリティ設定
  3. Content-Security-Policy(CSP)
  4. その他のセキュリティヘッダー
  5. キャッシュ制御
  6. Pages デプロイの設定
  7. まとめ

Cloudflare Pages は静的サイトのホスティングに最適なプラットフォームです。この記事では、実際のデプロイ構成と、_headers ファイルを使ったセキュリティ設定について紹介します。

SSL 証明書まわりの選定は、Cloudflare の Advanced Certificate Manager 解説もあわせて確認してください。CMS 管理画面を静的サイトに追加する設計はSveltia CMS導入ガイドにまとめています。外部コメントサービスに頼らず、Cloudflare Pages Functions と D1 でコメント機能を足す設計は CloudflareだけでAstroブログにコメント機能を作る方法 に分けました。

デプロイ構成:Worker をやめて Pages に戻した理由

当初、お問い合わせフォームのバックエンド処理を Cloudflare Worker で行う予定でした。Worker であればサーバーサイドでメール送信やバリデーションが可能です。

しかし、実際に構成してみると以下の課題がありました:

  • ビルドの複雑化:Astro のビルド出力を Worker で配信するには追加設定が必要
  • デバッグの手間:ローカルでの wrangler dev と本番の挙動差異
  • キャッシュ制御:Pages のほうが Cloudflare CDN との統合が自然

最終的に、お問い合わせフォームは ssgform.com という外部サービスを利用することで、フォーム送信のためだけにWorkerを持つ必要をなくしました。この時点では、純粋な静的サイトとして Pages にデプロイできる状態へ戻せました。現在は、コメント機能のように最小限の動的処理だけを Cloudflare Pages Functions で追加しています。

_headers によるセキュリティ設定

Cloudflare Pages では、public/_headers ファイルに HTTP レスポンスヘッダーを記述できます。以下は実際に使用している設定の抜粋です。

Content-Security-Policy(CSP)

CSP はクロスサイトスクリプティング(XSS)攻撃を防ぐための重要なヘッダーです。許可するリソースの取得元をホワイトリスト方式で指定します。

Content-Security-Policy: default-src 'self';
  script-src 'self' 'unsafe-inline' https://challenges.cloudflare.com https://pagead2.googlesyndication.com;
  style-src 'self' 'unsafe-inline';
  img-src 'self' https://acecore.net data:;
  connect-src 'self' https://challenges.cloudflare.com https://pagead2.googlesyndication.com;
  frame-src https://challenges.cloudflare.com https://googleads.g.doubleclick.net;
  form-action https://ssgform.com;

ポイントは以下のとおりです:

  • script-src:Cloudflare Turnstile(challenges.cloudflare.com)と AdSense を許可
  • img-src:同一オリジンの Cloudflare Images エンドポイントと Unsplash を許可
  • form-action:ssgform.com のみにフォーム送信を制限
  • frame-src:Turnstile の iframe と AdSense の広告フレームを許可

その他のセキュリティヘッダー

X-Content-Type-Options: nosniff
X-Frame-Options: DENY
Referrer-Policy: strict-origin-when-cross-origin
Permissions-Policy: camera=(), microphone=(), geolocation=()
  • X-Content-Type-Options:MIME スニッフィングを防止
  • X-Frame-Options:クリックジャッキング対策として iframe 埋め込みを禁止
  • Referrer-Policy:クロスオリジンではオリジンのみ送信
  • Permissions-Policy:不要なブラウザ API(カメラ・マイク・位置情報)を無効化

キャッシュ制御

静的アセットには長期間のキャッシュを設定し、HTML には短めのキャッシュを設定しています。

/_astro/*
  Cache-Control: public, max-age=31536000, immutable

/*.html
  Cache-Control: public, max-age=3600

Astro が出力する _astro/ ディレクトリのファイルにはコンテンツハッシュが含まれるため、immutable で1年間キャッシュしても安全です。HTML は更新頻度がある程度あるため、1時間のキャッシュに留めています。

Pages デプロイの設定

Cloudflare Pages のプロジェクト設定はシンプルです:

項目 設定値
ビルドコマンド npx astro build
出力ディレクトリ dist
Node.js バージョン 22

GitHub リポジトリを接続すれば、main ブランチへの push で自動デプロイされます。プレビューデプロイも PR ごとに自動生成されるため、レビューが捗ります。

まとめ

「サーバーサイド処理が本当に必要か?」を見極めることが大切です。外部サービスの活用で Worker を排除でき、結果的にデプロイもセキュリティ管理もシンプルになりました。_headers での CSP 設定は最初こそ手間ですが、一度書けばすべてのページに適用されるため、コストパフォーマンスの高いセキュリティ施策です。

デプロイ構成の変遷

  1. 初期構成

    Cloudflare Pages で静的サイトを配信。

  2. Worker 移行

    お問い合わせ処理のため Worker に移行。

  3. Pages 回帰

    外部フォームサービス採用で静的に戻す。

  4. セキュリティ強化

    _headers で CSP・セキュリティヘッダーを設定。

よくある質問

Cloudflare Pages と Workers のどちらを選ぶべきですか?

サーバーサイド処理が不要な静的サイトなら Pages が最適です。CDN との統合がシームレスで、デプロイも簡潔です。フォーム処理などは外部サービスで代替できます。

_headers ファイルで設定すべきセキュリティヘッダーは何ですか?

Content-Security-Policy、X-Frame-Options、X-Content-Type-Options、Referrer-Policy、Permissions-Policy が基本です。CSP はサイトで使用する外部リソースに合わせて調整してください。

CSP の設定で AdSense や Analytics を許可するにはどうしますか?

script-src に googletagmanager.com や googlesyndication.com のドメインを追加します。img-src や connect-src にも関連ドメインの許可が必要な場合があります。