[UPDATE] Amazon CloudFrontでResponse headers policiesがサポートされました!

Amazon CloudFrontでポリシーによるレスポンスヘッダの追加が可能になりました。Lambda@EdgeやCloudFront Functionsを使うよりもよりもシンプルにレスポンスヘッダの挿入が可能かと思います。
2021.11.03

はじめに

清水です。本日お伝えするアップデート情報はこちら、AWSのCDNサービスであるAmazon CloudFrontでResponse headers policiesがサポートされ、オリジンの変更やコードの記述なしでレスポンスにヘッダを追加することが可能になりました。日本時間本日(2021/11/03)早朝にポストされたアップデートになります。(現地時間では2021/11/02。)

CloudFrontを利用するケースで、オリジンではなくCloudFront側で特定のレスポンスヘッダを挿入してクライアントに返したい、という場合があります。例えばCORS用のAccess-Control-Allow-Originヘッダや、セキュリティ用のStrict-Transport-Securityヘッダ、またブラウザキャッシュ制御用のCache-Controlヘッダなどを挿入するケースですね。これまではLambda@EdgeやCloudFront Functionsを使用してCloudFront側でレスポンスヘッダの追加を行う必要がありました。関数実行のためコードの作成ならびにこれらの運用保守についても必要になるため、少し導入に慎重になるようなケースもあったのではないでしょうか。

今回のアップデートResponse headers policiesを使用することでコードの作成をすることなく、CloudFrontのPolicyの設定でレスポンスヘッダの挿入が行なえます。従来よりもよりシンプルに実現、運用できる大変うれしいアップデートかと思います。CORSやセキュリティ用の事前に定義されたManaged policiesを利用するほか、個別に設定可能なCustom policiesを作成、利用することも可能です。本エントリでは速報として、このResponse heders policiesをざっとですが確認してみたのでまとめてみたいと思います。

Response headers用のManaged policiesを確認してみる

まずはResponse headers用のManaged policiesをマネジメントコンソールから確認してみましょう。CloudFrontのマネジメントコンソール、左側PoliciesからResponse headersのタグに進みます。

CORSならびにSecurityHeaders関連の、合計5つのManaged policesが確認できます。一番上の「Managed-CORS-and-SecurityHeadersPolicy」の詳細画面に進むと、以下のようにCloudFront側で追加されるレスポンスヘッダ内容が確認できます。

これらManaged policiesについてはAmazon CloudFront Developer Guideにも記載があります。各Managed policiesの項目によって、オリジンのレスポンスヘッダがあった場合の上書きの対応(Override origin?)が異なる点に注意しましょう。

このManaged policiesを実際にCloudFrontディストリビューションにアタッチしてみます。Cache Behavior設定の「Cache key and origin requests」設定のあとに、Response headers policyの項目が追加されていますね。「Managed-CORS-and-SecurityHeadersPolicy」を選択して進みます。なお今回の動作確認では、Cache policyは「CachingDisabled」、Origin request policyは「All Viewer」としています。以下のスクショのとおりです。またオリジンにはAmazon Linux 2のEC2にApacheをインストールしました。

実際にレスポンスヘッダが追加されるか確認してみましょう。まずはResponse headers policyを設定していないCloudFrontディストリビューションのレスポンス(オリジンは同一)です。CORSの確認のため「-H "Origin: http://www.example.com"」をリクエストヘッダに付与しています。strict-transport-securityAccess-Control-Allow-Originなどのレスポンスヘッダがないことがわかります。これはオリジン側でこれらのレスポンスヘッダを返していないからですね。

% curl -i -H "Origin: http://www.example.com" https://d1prxxxxxxxxxx.cloudfront.net
HTTP/2 200
content-type: text/html; charset=UTF-8
content-length: 11
date: Wed, 03 Nov 2021 03:23:23 GMT
server: Apache/2.4.51 ()
last-modified: Wed, 03 Nov 2021 02:54:44 GMT
etag: "b-5cfd988448e75"
accept-ranges: bytes
x-cache: Miss from cloudfront
via: 1.1 90fa5c5ef559c4e8601bb399752b00bc.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT12-C4
x-amz-cf-id: 4-eZXs8CY-fyvBzyzPr5ake6vvv0tOfyrjA6JlxRu7ElrzbwOKpo4A==

index.html

続いて、Response headers policy 「Managed-CORS-and-SecurityHeadersPolicy」をアタッチしたCloudFrontディストリビューションです。レスポンスヘッダのx-xss-protectionヘッダ以降、access-control-allow-originヘッダまでがCloudFrontにより追加されています。

% curl -i -H "Origin: http://www.example.com" https://d1fkxxxxxxxxxx.cloudfront.net
HTTP/2 200
content-type: text/html; charset=UTF-8
content-length: 11
date: Wed, 03 Nov 2021 03:23:42 GMT
server: Apache/2.4.51 ()
last-modified: Wed, 03 Nov 2021 02:54:44 GMT
etag: "b-5cfd988448e75"
accept-ranges: bytes
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
referrer-policy: strict-origin-when-cross-origin
x-content-type-options: nosniff
strict-transport-security: max-age=3153600
access-control-allow-origin: *
x-cache: Miss from cloudfront
via: 1.1 6fc9bea777dbb883661b140062657912.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT20-C3
x-amz-cf-id: 1AbOfYzrToj0G49sUbCm4TH4_FM74x1nw2CcmNvb9mkXQZ9MTxFMBg==

index.html

Response headers用Custom policiesを作成して使ってみる

続いては、Custom policiesを作成してみます。今回はCache-Controlヘッダを追加してみるとしましょう。CloudFrontのマネジメントコンソール、左側PoliciesからResponse headersのタグ、[Create response headers policy]ボタンで進みます。

Response headers policyの名称として「Cache-Control-max-age-60」、説明として「Cache-Control: max-age=60.」を入力しました。この名の通り、Cache-Controlヘッダでmax-age=60を追加するとします。Custom headersの箇所、デフォルトでは項目がありませんが[Add header]ボタンで入力欄を追加し、実際に追加する内容を入力します。

Response headers policyが作成できたら、このポリシーをCloudFrontディストリビューションにアタッチします。

実際にレスポンスヘッダの付与を確認してみます。まずはResponse headers policyをアタッチしていないCloudFrontディストリビューションです。オリジン側からCache-Controlレスポンスヘッダが付与されていないため、CloudFrontからのレスポンスにもCache-Controlヘッダが含まれていません。

 % curl -i https://d1prxxxxxxxxxx.cloudfront.net
HTTP/2 200
content-type: text/html; charset=UTF-8
content-length: 11
date: Wed, 03 Nov 2021 03:33:08 GMT
server: Apache/2.4.51 ()
last-modified: Wed, 03 Nov 2021 02:54:44 GMT
etag: "b-5cfd988448e75"
accept-ranges: bytes
x-cache: Miss from cloudfront
via: 1.1 aaaa38f6638fefc2221f20ff18eceef2.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-P2
x-amz-cf-id: KFqILGoIKgSF8dL_EoLqqWoAld9S347zbdAC2Z-1Kq9IhKn8kxZWfw==

index.html

続いてResponse headers policy「Cache-Control-max-age-60」をアタッチしたCloudFrontディストリビューションです。指定したとおり、cache-control: max-age=60が付与されていることがわかります。

 % curl -i https://dz9jxxxxxxxxxx.cloudfront.net
HTTP/2 200
content-type: text/html; charset=UTF-8
content-length: 11
date: Wed, 03 Nov 2021 03:36:04 GMT
server: Apache/2.4.51 ()
last-modified: Wed, 03 Nov 2021 02:54:44 GMT
etag: "b-5cfd988448e75"
accept-ranges: bytes
cache-control: max-age=60
x-cache: Miss from cloudfront
via: 1.1 9dbab677f8be787117e804696d7d4017.cloudfront.net (CloudFront)
x-amz-cf-pop: NRT57-C1
x-amz-cf-id: LXmLr5ZmBz5S3EGsF9vX2XqiCO8klNvVDx1hn5NFL9m0FeyOdaBTPQ==

index.html

なお、今回、動作検証ということもありCloudFront側のキャッシュはCache policy「CachingDisabled」を選択していますが、実際にはオリジン側のキャッシュ用レスポンスヘッダの有無、CloudFront側のキャッシュ設定などを含め、設定するのが適切かと思います。(あくまで本エントリでの検証は、レスポンスヘッダが付与されることの確認にとどまります。)

まとめ

Amazon CloudFrontで新たに利用可能になったResponse headers policiesを使い、CloudFrontからクライアントへのレスポンスにヘッダを追加できることを確認してみました。これまでもLambda@EdgeやCloudFront Functionsで同様のことは行えていましたが、ポリシーの設定というシンプルな手段でレスポンスヘッダが追加できるようになったのはうれしい限りです。

あわせて読みたい

個人的に大変うれしいアップデートだったこともあり、速報のつもりでエントリとしてまとめてみましたが、弊社岩田が先にまとめていました!こちらもあわせてご覧ください。

またAWS BlogのNetworking & Content Deliveryにも今回のアップデートに関するエントリが公開されています。こちらもチェックしましょう!