Amazon Web Services ブログ

Amazon CloudFront がレスポンスヘッダーポリシー を導入

はじめに

Amazon CloudFront は、エッジロケーションとグローバルネットワークを利用して、静的および動的な Web コンテンツを配信するコンテンツ配信ネットワーク(CDN)です。CloudFront をアーキテクチャに組み込むことで、Web アプリケーションのパフォーマンスや信頼性の向上、セキュリティの強化などのメリットが得られます。レスポンスヘッダーを簡単に変更・管理できることは、お客様からよくいただくご要望でした。このニーズにお応えするため、CloudFront ではレスポンスヘッダーポリシーを導入し、お客様がヘッダー変更の定義を柔軟にコントロールできるようにしました。これまでも CloudFront と Lambda@Edge や CloudFront Functions を組み合わせてレスポンスヘッダーを操作することは可能でしたが、通常のユースケースはこのようなカスタムロジックを必要としないものが大半でした。このブログ記事では、レスポンスヘッダーポリシーによってヘッダーの操作プロセスがどのように簡素化されるか、どのようなヘッダーがサポートされるのか、どのように配信設定に統合できるかをご紹介します。

レスポンスヘッダーのポリシーは CloudFront のワークフローにどのように適合しますか?

Amazon CloudFront は Lambda@Edge や CloudFront Functions を組み合わせることで、独自のカスタムロジックをエッジに展開することができます。より複雑で計算負荷の高いオペレーションには Lambda@Edge が適切なソリューションであることが多く、超大規模でシンプルなリクエストやレスポンスの操作には CloudFront Functions が利用可能です。各オプションの特徴や対応するユースケースについては、CloudFront Functions のブログをご参照ください。レスポンス操作のカテゴリーでよく見られるパターンは、レスポンスをビューアーに提供する前に、ほとんど、あるいは全く条件を付けずにレスポンスヘッダーを挿入することです。一般的には CORS(Cross Origin Resource Sharing)ヘッダーや、HSTS(HTTP Strict Transport Security)などのブラウザとサーバー間の通信のセキュリティ関連の詳細を指定する、セキュリティヘッダーを挿入することが多いです。また、オリジンがデフォルトで生成できない欠落したヘッダーを追加したり、クライアントが実行するアプリケーションに関連する追加情報を含む、静的なヘッダーを渡したりすることもあります。今日、お客様はこのようなユースケースで CloudFront Functions を使用しています。CloudFront Functions はそのサポートに適した環境ですが、お客様がコード開発の手法をアーキテクチャの CDN 部分にまで拡張する必要がある場合、オーバーヘッドが発生します。また、異なるワークフロー間で共通のヘッダーセットを適用するための一貫性を保つには、ある程度の努力が必要です。

レスポンスヘッダーポリシーは、HTTP ヘッダーレスポンス操作のプロセスを簡素化し、マネジメントコンソールや API を通じて CloudFront の設定として CORS、セキュリティ、カスタムレスポンスヘッダーを定義できるようにします。ヘッダーセットの複数の組み合わせを定義し、それらを別々の再利用可能なポリシーとして保持することができます。そして、これらのポリシーを 1 つまたは複数のビヘイビアと関連付けることで、目的のアプリケーションの機能を実現することができます。レスポンスヘッダーポリシーによるヘッダーの追加は、レスポンスに追加処理が必要な場合、 Lambda@Edge や CloudFront Functions と連携することができます。この種のワークフローでは、レスポンスヘッダーポリシーと自分のコードロジックが同じヘッダーに依存している場合は特に、レスポンスが処理される順序を覚えておくことが重要です。下記の図はキャッシング層、レスポンスヘッダーポリシー、Lambda@Edge または CloudFront Functions の間の操作の順番を示しています。なお、任意のビヘイビアの Viewer Response トリガーには、一度に 1 つの関数(Lambda@Edge または CloudFront Functions のどちらか)しか関連付けすることはできません。

図1 レスポンスヘッダーポリシーのワークフロー

図1 で説明したように、レスポンスヘッダーポリシーは CloudFront のキャッシング層に保存されているオリジンの提供したヘッダーには影響を与えません。ポリシーで設定されたヘッダーは、レスポンスがキャッシュを離れた後、設定されていれば関数をトリガーするビューアのレスポンスイベントの前に挿入されます。同じビヘイビアにエッジ関数をアタッチしている場合、ポリシーで挿入されたヘッダーは、レスポンスに関連するすべてのヘッダーをリストアップしたイベントオブジェクトを通じて、関数内でアクセス可能になります。ポリシーによって生成されたヘッダーを、コードの実行方法に影響を与える関数の入力として扱うことで、この機能を使用することができます。これは環境変数を使うのと似ています。

レスポンスヘッダーポリシーの構成

レスポンスヘッダーの設定は、Cache ポリシーや Origin Request ポリシーで導入された構成要素であるポリシーにまとめられています。ポリシーは CloudFront の設定を再利用可能なセットにグループ化することで、設定と管理を容易にするために使用されます。通常、レスポンスヘッダーのポリシーを設定・管理するための大まかな流れは以下のようになります。

・ポリシーを作成:信頼できるドメインで使用する API エンドポイントには、より厳しい設定のポリシー、公開したい静的なアセットには 2 つ目のポリシーを設定するなど、異なるワークロードの要件に合わせてポリシーを作成します

・ポリシーの適用:アカウント内の複数の CloudFront ディストリビューションとビヘイビアに、各ポリシーを適用します

・ポリシーの変更:API ワークロード用の信頼できるドメインを追加する必要がある場合は、対応するポリシーを編集すると、更新された設定がそのポリシーにリンクされた全てのキャッシュビヘイビアに反映されます

・ビヘイビアへの追加:CloudFront ディストリビューションとキャッシュビヘイビアを追加する際には、既存のポリシーを適用できるかどうかを確認します。適用できない場合は、必要なヘッダー設定を持つ別のポリシーを作成し、それを新しいキャッシュビヘイビアに関連付けます

既存のポリシーを確認したり、新しいポリシーを作成するには、次のスクリーンショットに示すように、ナビゲーションパネルに表示される Policies ページからアクセスできます。


図2 CloudFront コンソールのレスポンスヘッダーポリシー

レスポンスヘッダーのポリシーページの上部には、一般的なヘッダー設定の様々な組み合わせを持つマネージドポリシーのリストがあり、基本的な設定を素早く適用することができます。これらのポリシーの詳細は、ビューアーのエクスペリエンスを阻害しないように特別な注意を払って作成されていますが、各ポリシーが何をするのか、どのようなヘッダーが挿入されるのかを必ず確認してください。そうすることで、あなたのウェブアプリケーションがうまく動作するようになります。ブラウザはこれらのヘッダーに含まれる情報を長期間にわたってキャッシュすることができるため、ポリシーに含まれるいくつかのヘッダーを実装した効果を元に戻すには、ビューアーのビヘイビアに影響を与えるまでに時間がかかることがあります。各ポリシーは、マネージドポリシーとカスタムポリシーのいずれも3つの異なるセクションで構成されており、それぞれのレスポンスヘッダーのセットを管理可能です。

図3 カスタムレスポンスヘッダーのポリシー構造

Cross-Origin Resource Sharing (CORS)

Cross-Origin Resource Sharing(CORS)は、ブラウザやウェブアプリケーションのオリジンが使用するメカニズムで、通常は同一オリジンのポリシー制限に違反するリクエストを条件付きで許可するものです。この制限は Web サイトを訪れたユーザーが、第三者のドメインへの意図しないリクエストを引き起こしてしまうことを防ぐために設けられています。例えば Webサイトに挿入された悪意のあるスクリプトが、新しいトランザクションの指示を送ったり、機密情報を収集したりすることがあります。ウェブアプリケーションの所有者としては、同一オリジンポリシーの原則により、ユーザーに害を及ぼす可能性のある不正なリクエストの受信を防ぐことができます。しかし、この制限を意図的に緩和して、信頼できるドメインから開始されるクロスドメインリクエストを許可したいケースもあります。適切な CORS レスポンスヘッダを挿入することで、リクエストとレスポンスを許可するために、リクエストの許容範囲と満たすべき条件を Web ブラウザに指示します。レスポンスヘッダーポリシーには、6 つの CORS 関連のレスポンスヘッダーがあらかじめ定義されており、シンプルなリクエストとプリフライトリクエストの両方に適用できます。この機能により、キャッシュキーの定義に「Origin」ヘッダーを含めなくても、複数のオリジン(ソースドメイン)を定義できるようになり、キャッシュヒット率の低下を防ぐことができます。

セキュリティヘッダー

CORS ヘッダーの他にも、ウェブサイトのセキュリティを向上させるために追加できる、よく知られているセキュリティヘッダーがあります。このセクションにまとめられているヘッダーは、ウェブサイトのコンテキストで従うべき制限に関するブラウザの指示として機能します。例えば HTTP Strict-Transport-Security ヘッダーを設定すると、ユーザがアドレスバーに http:// と入力した場合でも、ブラウザが同じドメイン上のページに対してそれ以降に行う全ての要求について、HTTPS 接続へ変更することが指示されます。これらの各ヘッダーを含めることは任意であり、どのヘッダーを使用するかはユーザーが決めることができます。ポリシーに含めることができる6つのセキュリティヘッダーは以下の通りです。

・HTTP Strict Transport Security (HSTS)
・X-XSS-Protection
・X-Content-Type-Options
・X-Frame-Options
・Referrer-Policy
・Content-Security-Policy

カスタムヘッダー

上記以外のタイプのヘッダーを追加したいというご要望をいただくことがあります。このようなユースケースは、アプリケーションのコンテキストによって異なるため、カスタムヘッダーとして静的なレスポンスヘッダーをシンプルなキーと値のペアで定義することができます。カスタムヘッダーのユースケースには次のようなものがあります。

・下流のキャッシュやブラウザに対して、cache-control ヘッダーを挿入または上書きする
・レスポンスに CDN の識別子や、アプリケーションのバージョンをタグ付けする
・オリジンのメタデータを伝える
・互換性情報を追加する

注意:レスポンスヘッダーポリシーで指定したヘッダーが、オリジンから提供されたヘッダーと衝突する可能性があります。具体的には CloudFront が複数のオリジンで運用されている場合、各オリジンがいつ、どのようなヘッダーセットを設定するかで不整合が生じる可能性があります。この問題に対処するため、レスポンスヘッダーポリシーを使用して、重複するヘッダーの管理方法を設定することができます。オリジンから送られてくるレスポンスヘッダーをオーバーライドするか、オリジナルのレスポンスにすでにヘッダーが含まれていて、オーバーライドオプションを無効にしている場合は、ヘッダーの挿入を省略することができます。

入力検証とCORSヘッダーの条件付け

何故レスポンスヘッダーのポリシーが 3 つのセクションに分かれているのかと思われるかもしれませんが、ポリシーをキーと値のペアの単純なリストとして維持する代わりに、最初の 2 つには限定された定義済みのヘッダーセットが含まれています。2 つのセキュリティヘッダーセットを分離することには、以下の重要なメリットがあります。

・入力の検証:これらのよく知られたヘッダーのほとんどは想定される値が限られており、手動で入力するとエラーが発生しやすいものです。可能なオプションの数を制限することで、誤って不正なヘッダーを生成することを回避し、ウェブサイト上で予期しない動作を引き起こす可能性を制限します。

・CORS 条件:CORS ヘッダーの管理に関しては、正しいヘッダーの組み合わせとその値に関して、Fetch standard で義務付けられた特定のルールがあります。CloudFront はレスポンスヘッダーポリシーに追加のロジックを実装し、リクエストヘッダーの詳細に基づいて正しい CORS ヘッダーが返されるようにしています。

この例として Access-Control-Allow-Origin ヘッダーで CORS の条件付けがどのように機能するかを考えてみましょう。これは CORS のコンテキストにおいて重要なヘッダーの 1 つで、どのドメインが Web サイトのコンテンツの読み込みを許可されているかをブラウザに伝えます。許可したいドメインが複数ある場合は、そのリストを CORS セクションに入力して送信する必要があります。ただし CORS の仕様では、そのヘッダーでは 1 つの値しか返せないことになっています。そのため CloudFront のホストは、Origin ヘッダーを通じてリクエストの発信元のドメインを判断し、Access-Control-Allow-Origin の定義された値のリストと照合します。

例えば、ポリシーの CORS ヘッダーが以下のように定義されているとします。

図4 CORSヘッダーの設定における複数のオリジン

シンプルな CORS リクエストでは、これら 2 つの値のどちらか一方のみが適宜返されます。

$curl -I -H "Origin: https://aws.amazon.com" https://d12345abcde789.cloudfront.net 

HTTP/1.1 200 OK 
(...) 
Access-Control-Allow-Origin: https://aws.amazon.com 
Vary: Origin

ポリシーとキャッシュビヘイビアの関連付け

カスタムポリシーを作成するか、マネージドポリシーのリストから 1 つを選択したら、次のステップでは、そのポリシーを適切なキャッシュビヘイビアに関連付けます。設定のワークフローは、キャッシュおよびオリジンリクエストポリシーの場合とよく似ています。キャッシュ動作の設定に移動すると、キャッシュキーとオリジンリクエストの設定の下にレスポンスヘッダーポリシーのリストがあり、そこからこの動作に使用するものを選択できます。


図5 レスポンスヘッダーポリシーとキャッシュビヘイビアの関連付け

レスポンスヘッダーのポリシーは任意の設定であることに注意してください。この機能によって既存のビヘイビアや新規のビヘイビアに、デフォルトのポリシーが適用されることはありません。ポリシーがビヘイビアに関連付けられると、CloudFront の設定変更が伝搬されるまでの時間内に、返されるレスポンスヘッダーにポリシーの効果が現われます。

$curl -I -H "Origin: https://example.com" https://d12345abcde789.cloudfront.net 
HTTP/1.1 200 OK 
Content-Type: text/html 
Content-Length: 90
##security headers## 
x-xss-protection: 1; mode=block; report=http://example.com/report 
x-frame-options: SAMEORIGIN 
referrer-policy: strict-origin-when-cross-origin 
content-security-policy: default-src https: 
x-content-type-options: nosniff 
strict-transport-security: max-age=31536000
##custom headers## 
x-cdn: CloudFront 
##CORS headers## 
access-control-allow-credentials: true 
access-control-allow-origin: https://example.com 
vary: Origin 
access-control-expose-headers: X-ExposedHeader 

X-Cache: Miss from cloudfront 
Via: 1.1 1e4c7e8afcaf6e21a729c3a37d8d3094.cloudfront.net (CloudFront) 
X-Amz-Cf-Pop: PHX50-C2 
X-Amz-Cf-Id: Vn5R_GXTLzBmb2rhJATR6iii8vSzHCgeMDoYgZzJ3QFb_-Hdszvkng==

おわりに

この記事では、コードを管理することなくエッジでのレスポンス操作を効率化するための一歩として、レスポンスヘッダーポリシーをご紹介しました。このポリシーは Lambda@Edge やCloudFront Functions といったサーバーレス環境からレスポンスヘッダーの変更を切り離し、より高度なロジックに対応できるようにしたものです。ポリシーでサポートされるヘッダーは、CORS(標準に準拠するための追加ロジックもあります)、セキュリティ、カスタムヘッダーの 3 つのカテゴリーに分かれているため、お客様は Origin の種類が異なる様々なワークロードをサポートするのに十分な柔軟性を備えています。お客様がレスポンスヘッダーのポリシーを一度定義すると、複数のアプリケーションや CloudFront のディストリビューションで再利用することができます。ポリシーはキャッシュビヘイビアに適用されるため、アプリケーションの別の部分や異なるオリジンタイプに対して、レスポンスヘッダーをきめ細かく定義することができます。CloudFront のレスポンスヘッダーポリシーは、CloudFront コンソールAWS SDKAWS CLI ですぐに使用することができます。詳細については CloudFront Developer Guide を参照してください。

著者について


Kamil Bogacz
Kamil は AWS のエッジスペシャリスト・ソリューションアーキテクトです。AWS Edge Services を利用したパフォーマンスの最適化とセキュアなソリューションの構築について、様々な業界のお客様にアドバイスを行っています。


Megha Kande
Megha はワシントン州シアトルにある Amazon CloudFront チームのプロダクトマネージャーです。

翻訳は SA 森が担当しました。原文はこちらをご覧ください。