CDN導入の注意点


a-blog cms で構築されたサイトの前段に CDN を配置することは可能です。ただし、CDN を挟むことで a-blog cms 側にいくつかの設定対応が必要になります。

CDN サービス固有の設定手順は各サービスのドキュメントを参照してください。本ドキュメントは a-blog cms 側で必要な設定と注意点をまとめたものです。

1. 接続元 IP アドレスの取得設定

CDN を経由すると、そのままでは接続元 IP がすべて CDN のものになります。正しい IP が取得できないと、以下の機能が期待通りに動作しません。

  • ログイン制限・不正ログイン対策

  • IP アクセス制限

  • 各種ログ記録(監査ログなど)

設定方法

/config.server.php で以下の定数を設定します。


// プロキシでIPアドレスを追加するヘッダーを指定します。
// RFC 7239 の Forwarded ヘッダーを使う場合は HTTP_FORWARDED を指定すると for= に加えて
// proto=・host= も読みます。X-Forwarded-Proto・X-Forwarded-Server を併送する構成もそのまま動作します。
define('PROXY_IP_HEADER', 'HTTP_TRUE_CLIENT_IP');
// プロキシが入っている場合、X-Forwarded-ForヘッダーからクライアントIPアドレスを特定するため、
// 信頼できるプロキシのIPを設定します。 例: define('TRUSTED_PROXY_LIST', 'xxx.xxx.xxx.xxx,yyy.yyy.yyy.yyy');
// CIDRも使えます。例: define('TRUSTED_PROXY_LIST', '10.0.0.0/8');
// プロキシは X-Forwarded-For にクライアントの値を追記する構成である必要があります。
// 接続元がここに一致しないリクエストでは、ヘッダーを無視して接続元のIPアドレスを使います。
// プロキシのIPアドレスが動的に変わる場合は '*' を指定すると接続元だけを信頼します。
// '*' はサーバーへプロキシ経由以外で到達できる構成では使えません(IPアドレスを偽装されます)。
// IPアドレスの範囲が公開されているCDNでは '*' ではなくその範囲をCIDRで指定してください。
// この設定は X-Forwarded-Proto(HTTPS判定)と X-Forwarded-Server(SERVER_NAME)を信頼するか
// どうかの境界も兼ねます。接続元がここに一致せず、プライベート/ループバック/リンクローカル
// アドレスでもない場合、これらのヘッダーは無視されHTTP扱いになります。
// TLSを終端するCDNやロードバランサーが公開IPからオリジンに接続する構成では、この設定が空の
// ままだと常時SSL有効時にhttpsへの301リダイレクトが無限ループします。301はブラウザにキャッシュ
// されるため、設定を直した後もキャッシュの削除が必要です。
define('TRUSTED_PROXY_LIST', '192.0.2.10,198.51.100.20');

PROXY_IP_HEADER のデフォルト値は HTTP_X_FORWARDED_FOR です。CDN が実 IP を渡すヘッダー名に合わせて変更してください。

プロキシが RFC 7239 の Forwarded ヘッダーしか送出できない構成の場合、PROXY_IP_HEADERHTTP_FORWARDED を指定できます。for= パラメータからクライアントIPアドレスを読み取ります(proto=host= も同時に読み取られ、次項のHTTPS判定・SERVER_NAME判定にも使われます)。

TRUSTED_PROXY_LIST に CDN のオリジン接続元 IP を登録すると、X-Forwarded-For ヘッダーのチェーンから信頼できるプロキシ IP を除外して実クライアント IP を特定します。CDN サービスによっては、オリジンへの接続元 IP を固定・公開している場合があります。その IP を TRUSTED_PROXY_LIST に登録することで、実 IP の特定に加え、CDN を経由しないオリジンへの直接アクセスをサーバー側で制限することも安全に行えます。

ロードバランサーのIPアドレスが動的に変わり事前に列挙できない場合は、*を指定できます。*は「すべてのIPアドレスを信頼する」ではなく「接続してきた相手だけを信頼する」という意味で、CIDRと併記も可能です(例: *,10.0.0.0/8)。* は「サーバーへプロキシ経由以外で到達できない」構成でのみ使用してください。直接到達できる構成で使うと、ヘッダーを1つ付けるだけで任意のIPアドレスを偽装できます。IPアドレス範囲が公開されているCDN(Cloudflare等)では、* ではなくその範囲をCIDRで列挙することを推奨します。

2. キャッシュ制御(情報漏えい防止)

管理画面・ログイン中の会員ページ・プレビュー・フォーム送信などをキャッシュしてしまうと、会員向けコンテンツや個人情報が別のユーザーに配信される危険があります。

ログイン判定用 Cookie の活用

a-blog cms には、ログイン中のユーザーにのみ発行される専用 Cookie が用意されています(CDN でのキャッシュ出し分けを想定した機能です)。

/private/config.system.yaml で有効化します。

extra_logged_in_cookie: on
extra_logged_in_cookie_name: acms-logged-in # 任意で変更可能

この Cookie の有無を条件にキャッシュをバイパスするよう CDN 側を設定してください。


セッション Cookie(config.server.php の SESSION_NAME で変更可能)は未ログインの訪問者にも付与される場合があるため、これをキャッシュバイパス条件にすると公開ページもキャッシュされなくなり、CDN の効果が薄れます。ログイン判定には上記の専用 Cookie を使用してください。


POST リクエストのバイパス

フォーム送信などの POST リクエストは必ずキャッシュをバイパスする設定にしてください。

3. HTTPS・プロトコル判定(CDN でSSL を終端する場合)

CDN のエッジで SSL を終端し、オリジン(a-blog cms)へ HTTP で接続する構成では、a-blog cms が正しく HTTPS と判定できるよう対応が必要です。

a-blog cms は以下の順序でプロトコルを判定します。

1. $_SERVER['HTTPS'] が存在する

2. $_SERVER['SERVER_PORT'] が 443 である

3. $_SERVER['HTTP_X_FORWARDED_PROTO']https である

X-Forwarded-ProtoX-Forwarded-Server を信頼するかどうかは、上記の TRUSTED_PROXY_LIST と同じ設定で制御されます。接続元IPアドレスが TRUSTED_PROXY_LIST に一致する場合のみ、これらのヘッダーが信頼され、HTTPS判定・SERVER_NAME(ホスト名)の解決に使われます。一致しない場合はヘッダーが無視されHTTP扱い・接続元のホスト名扱いになります。

そのため、CDN・ロードバランサーでSSLを終端する構成では、接続元IPアドレスの取得設定(前項の TRUSTED_PROXY_LIST)を行わないと、HTTPS判定も正しく機能しません。Secure Cookieなど「HTTPS接続であること」を前提にした機能を使う場合は、前項の設定を先に済ませてください。

CDN 側で X-Forwarded-Proto: https ヘッダーをオリジンへ転送するよう設定することで、a-blog cms が HTTPS として動作します。この設定が漏れると、管理画面やログインページで HTTP へリダイレクトされるなどの問題が発生することがあります。

4. キャッシュのパージ運用

コンテンツを公開・更新したときに、CDN に古いキャッシュが残ったままにならないよう、パージ(キャッシュ消去)の運用を設計してください。

5. WAF によるリクエストブロック

CDN の WAF(Web Application Firewall)を有効にしている場合、a-blog cms の正常な操作がブロックされることがあります。

以下はブロックされやすい操作の例です。

  • 管理画面での HTML を含むコンテンツ編集

  • ファイル・画像のアップロード

  • リッチエディタやブロックエディタからの POST

  • フォーム送信

対処としては、管理画面の URL パス(例: /bid/admin/ など)を WAF ルールの除外対象に設定することが一般的です。WAF のルールチューニングは CDN サービス側での対応となります。

設定項目の一覧

設定ファイル

項目

デフォルト値

config.server.php

PROXY_IP_HEADER

HTTP_X_FORWARDED_FOR

config.server.php

TRUSTED_PROXY_LIST

(空)

private/config.system.yaml

extra_logged_in_cookie

off

private/config.system.yaml

extra_logged_in_cookie_name

acms-logged-in