AWS
SSL
HTTPS
CloudFront

Cloudfront-Origin間のHTTPS通信エラー原因と対策(502:Bad Gateway)

More than 3 years have passed since last update.

Cloudfrontの動作確認を行っていたところ、HTTPS通信周りでハマったのでメモ。


1.ユースケース

今回の構成は以下の通りです。

 ①:アプリケーションとしてのエンドポイントはCloudfrontに統一

 ②:キャッシュさせたいbahavior、キャッシュさせたくないbehaviorを持つ

 ③:CloudfrontとOrigin間の通信はHTTPSにする

このパターン自体はよくあるユースケースだと思います。

■構成例

この構成で問題となったのは、「キャッシュさせたくないbehavior」の設定です。



2.キャッシュ対象外のbahavior設定(Forward Headers = ALL)

Cloudfrontでキャッシュさせたくない設定を実現する場合は、

Forward Headers = Allにするのが手っ取り早い設定になります。

実際、アプリケーションがどんなheaderを使っているかを洗い出す作業は面倒ですし、

ある程度大きい組織やプロジェクトだと、アプリケーション側の挙動まで把握できていないことも多く、

アプリケーション側の担当者の協力が不可欠ですし、色々な政治的な理由も相まって、

no-cache,no-storeヘッダーを埋め込むこともできないこともあり、こうするケースが多いです。

この設定を行ったとき、CloudrontとOrigin間のHTTPS通信に罠がありました。



3.SSLハンドシェイクに失敗する

Cloudfrontは、Defaultではhostヘッダーを削除しますが、

Froward headers = Allにすると、当然hostヘッダーも透過させることになります。

この設定を行うと、Cloudfront経由でOriginにアクセスした場合、

CloudfrontはHostヘッダーにCloudfront自身のDNS名をセットしてOriginにアクセスすることになります。

この状態で通信すると、SSLハンドシェイクに失敗し、502:Bad Gatewayエラーが返されます。

Cloudfrontによる証明書の検証に失敗してしまうのです。。。

■通信の流れ



4.対応策

対処策は明白で「Hostヘッダーを透過させない」ということになります。



5.Forward HeadersのBlack List設定はできない

ただ、Forward Headers = Allにしていたせいで、

Hostヘッダーだけ透過させない、という設定が簡単にはできませんでした。。。

CloudfrontのForward HeadersはWhite Listしか設定できません。。。

結果、必要なヘッダーを洗い出してWhite Listに設定するハメに。。。

安易にForward Headers = Allにしてしまうと、こんな状態に陥ってしまいますので、

アプリケーションとして透過すべきHeaderを明示的に洗い出す作業は、逃げずに事前にやっておいた方がよいですね

(当たり前と言えば当たり前なのですが)。。。

というか、CloudfrontのForward Headersの設定で、Black Listの設定ができればいいのにーーーー

と痛感しました(HostヘッダーだけBlack Listに登録できれば万事OKな事象なので)。



6.まとめ

そもそも、キャッシュコンテンツとキャッシュ対象外コンテンツの両方をCloudfront経由にする

という構成自体が無しなのかもしれません。

キャッシュ対象だけCloudfrontを経由させるのが定石なので、それに倣った方が無難だということを痛感しました。

(CloudfrontとOrigin間の余計な通信が発生しないので、通信料も節約できるし。。。)






最後に、、、これはあくまで私的なメモですので、

特定の環境の情報を公開するものではありません(お約束)。