CloudFlareからCloudFrontに移行してハマった話

  • 2
    Like
  • 0
    Comment

簡単に切り替えればいいだけかと思いましたが、違いました。

初期の構成

(HTTPS) -> CloudFlare -> (HTTP) -> Heroku -> Rails

移行後の構成1

(HTTPS) -> CloudFront -> (HTTP) -> ELB -> (HTTP) -> Elastic Beanstalk -> Rails

Distribution Settings

Alternate Domain Names (CNAMEs): exsample.com
SSL Certificate: Custom SSL Certificate (ACMで作成)

Origin Settings

Origin Domain Name: ELB
Origin Protocol Policy: HTTPS Only

Default Cache Behavior Settings

Viewer Protocol Policy: Redirect HTTP to HTTPS
Allowed HTTP Methods: GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE

移行後の構成2

移行後の構成1は、単純にはうまく行きません。まず、CloudFrontはデフォルトでは多くのヘッダーを削除します。

カスタムオリジンの場合のリクエストとレスポンスの動作 - Amazon CloudFront

例えば、Hostが削除されるのでredirect_toしたときに、RailsがURLをELBのURLで返してしまってexsample.comからELBのURLに移動してしまいます。

もともと、コンテンツ配信用でCloudFlareのような使用方法ではなかったからだと思います。そのため、いくつかのヘッダーを許可しましょう。

Default Cache Behavior Settings

Whitelist Headers:
Authorization
Host
Refere
X-Forwarded-For

※ CloudFlontの設定を変更した時は念の為にStatusがDeployedになるまで待ちましょう。

移行後の構成3

移行後の構成2は、またまたうまく行きません。CloudFront -> (HTTP) -> ELBの通信が、HTTPなのでX-Forwarded-ForにHTTPが入ってしまい、これまたRailsがredirect_toをhttpsからhttpに書き換えてしまいます。

X-Forwarded-ForはLoad Balancerのための仕様なので、Railsも対応してくれていて、そこにhttpsが入っていれば実際のリクエストがhttpでもうまく処理してくれます。

CloudFrontからの通信はCloudFront-Forwarded-Protoに入ってるのですが、ちょっと新しい概念だったりするのでRailsでは単純には対応してくれていません。

通常は、Nginxでリバースプロキシを設定するのだと思いますが、面倒なのでHTTPS化してしまいましょう。

AWSの無料SSL ACMはTokyo Regionとかでは現時点では使えません。いつか使えることを夢見つつSSL証明書を購入しましょう。
一番安いSecure Core SSLに乗り換える | デフよん

EC2 -> ロードバランサー -> リスナー -> 編集から追加し、HTTPS - HTTPで追加しましょう。SSL 証明書からSSLを追加できるので、追加しましょう。
ELB の ComodoSSL 証明書を更新 - Qiita

(HTTPS) -> CloudFront -> (HTTPS) -> ELB -> (HTTP) -> Elastic Beanstalk -> Rails

また、ロードバランサーにRoute53からAレコードのエイリアスでelb.exsample.comとかを設定してCloudFrontのoriginをelb.exsample.comに変更しましょう。

ちなみに証明書を削除する方法はこちらです。
ELBに設定したSSL証明書の削除~|期限切れ ロードバランサ 方法 セキュア 対処 対応 設定 トラブルシューティング | ナレコムAWSレシピ

移行後の構成4

さて、移行後の構成3はうまく行きません。CloudFrontはCloudFlareと違って、Cookiesの転送はしてくれません。あと、Queryを転送してくれません。設定しましょう。これで、うまくいきました!

Default Cache Behavior Settings

Forward Cookies: All
Query String Forwarding and Caching: Forward all, cache based on all