[新機能] Amazon CloudFrontでHostヘッダを転送する

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ども、大瀧です。
本日CloudFrontの大規模アップデートが実施され、様々な機能拡張が行われました。
その中でも、個人的にインパクトが大きかったのがHostヘッダが転送できるようになったことです。

Hostヘッダはデフォルトでは転送されない

これまでCloudFrontでWebコンテンツを配信する場合、リバースプロキシ/キャッシュサーバーとして動作することからHTTPヘッダが書き換えられていました。以下の簡単なPHPスクリプトを作成し、EC2への直接アクセスとCloudFront経由のアクセスでの結果を比較してみます。

<pre><?php var_dump(getallheaders()) ?></pre>

EC2の場合

array(7) {
  ["Host"]=>
  string(10) "ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com"
  ["User-Agent"]=>
  string(81) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0"
  ["Accept"]=>
  string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
  ["Accept-Language"]=>
  string(23) "ja,en-us;q=0.7,en;q=0.3"
  ["Accept-Encoding"]=>
  string(13) "gzip, deflate"
  ["Connection"]=>
  string(10) "keep-alive"
  ["Cache-Control"]=>
  string(9) "max-age=0"
}

CloudFront経由の場合

array(6) {
  ["Host"]=>
  string(51) "ec2-XX-XX-XX-XX.ap-northeast-1.compute.amazonaws.com"
  ["User-Agent"]=>
  string(81) "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:30.0) Gecko/20100101 Firefox/30.0"
  ["Accept"]=>
  string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
  ["Accept-Language"]=>
  string(23) "ja,en-us;q=0.7,en;q=0.3"
  ["Accept-Encoding"]=>
  string(13) "gzip, deflate"
  ["Connection"]=>
  string(10) "keep-alive"
}

Webブラウザのアクセス先はCloudFrontなので、CloudFront経由の場合でもオリジンに届くリクエストのHostヘッダにはCloudFrontのDNS名が入ってほしいのですが、CloudFrontはリバースプロキシとしてオリジン(今回はEC2)にアクセスするため、HostヘッダをオリジンのDNS名に書き換えてしまいます。これは、オリジンでバーチャルホストを構成しようとすると都合が悪いことがあります。

CloudFrontのビヘイビアでForward Headersを編集する

今回のアップデートにより、CloudFrontのビヘイビア(転送ルール設定)に転送するHTTPヘッダの選択項目が追加されました。以下3つから選択します。デフォルトではNoneが選択され、上記の結果になります。

  • None (Improves Caching)
  • Whitelist
  • All

White Listでは、転送したいHTTPヘッダを選択するフォームが表示され、左の一覧から右の一覧に選択していくスタイルです。

cloudfront-forwad-host-header01

今回のお目当てであるHostヘッダをはじめとする一般的なHTTPヘッダのほか、CloudFront独自のユニークなヘッダもありますね。こちらは、弊社の他のメンバーが別の記事でフォローすると思います(笑)

一点、注意が必要なのがAllを選ぶ場合です。以下のように警告文が表示され、全ヘッダを転送する場合にはTTLが0になるようです。TTLが0ということは、CloudFrontでのキャッシュが無効になるので気をつけましょう。

cloudfront-forwad-host-header02

動作結果

では、Hostを含めいくつかのヘッダを選択し、動作を確認してみます。

CloudFront経由の場合

array(9) {
  ["Host"]=>
  string(29) "d3mx5h2ys7cfml.cloudfront.net"
  ["Via"]=>
  string(64) "1.1 fce22d309c4260a69fd75ca9144688ca.cloudfront.net (CloudFront)"
  ["Connection"]=>
  string(10) "Keep-Alive"
  ["X-Amz-Cf-Id"]=>
  string(56) "hVsvOV2OViBLEMKbjPlA1k4f026yo_3UbBPIAfYlIzar6iV53Tpkiw=="
  ["Accept-Encoding"]=>
  string(4) "gzip"
  ["User-Agent"]=>
  string(17) "Amazon CloudFront"
  ["X-Forwarded-For"]=>
  string(13) "59.146.77.152"
  ["Accept"]=>
  string(63) "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
  ["CloudFront-Forwarded-Proto"]=>
  string(4) "http"
}

ちゃんとHostヘッダに、CloudFrontのDNS名が入っていますね!CloudFrontにCNAMEで独自ドメインを指定する場合でも、もちろん問題なく動作します。

まとめ

Hostヘッダが転送できるようになったことで、オリジンのWebサーバー構成の幅がぐっと広がりました。ますます使いやすくなっていくCloudFrontをどんどん活用して行きましょう!