CloudFront + Amplify 構成では Host ヘッダーを転送してはいけない

実施したかったこと

以下のように Amplify の前段に CloudFront を配置し、AWS WAF の IP 制限を実装しようとしていました。

Amplify の Basic 認証機能を設定しますが、CloudFront からアクセスする際はカスタムヘッダー (Authorization) を付与して Basic 認証を通過します。

悪意のある第三者 (攻撃者) は、CloudFront (cloudfront.example.com) にアクセスしようとすると IP 制限によりブロックされ、(図の青い線)

IP 制限をバイパスするためにオリジンである Amplify (amplify.example.com) にアクセスしようとすると Basic 認証によってブロックされる (図の赤い線) … という形でアプリケーション保護を提供できます。

 

こちらの構成は以下の通り AWS のガイダンスにも記載されているような内容なのですが、本構成でエラーが発生したため対策と併せて共有します。

AWS Amplify がホストするウェブアプリケーションの AWS WAF を有効にする

エラー内容

CloudFront のドメイン (cloudfront.example.com) にアクセスすると 403 Forbidden となりました。

WAF のログを確認したところ、なぜかアクセス元がユーザーの拠点IPではなく 130.176.135.77 等の CloudFront の IP (※1) になっており、WAF の IP 制限ルールでブロックされていました。

※1 これが CloudFront の IP であることは、AWSマネージドプレフィックスリストから確認しています

原因

CloudFront のオリジンリクエストポリシーで「AllViewer」を使用して全ての HTTP ヘッダー・Cookie・クエリ文字列をオリジン (Amplify) に転送するようにしていたのですが、

実は多段 CloudFront の構成で Host ヘッダーを転送してしまうとアクセスのループが発生してしまうようです。

Amplify も内部的には CloudFront を利用しているので、このケースに当てはまります。図にすると以下のようなものになると推測しています。

今回のケースでは、IP 制限によりループが途中でブロックされています。

対処方法

Host ヘッダーを転送しないよう、AWS マネージドのオリジンリクエストポリシー「AllViewerExceptHostHeader」を利用するか、

もしくは以下のように Host ヘッダーのみ転送しないオリジンリクエストポリシーを作成し、対象のディストリビューションに適用することで本事象は解消しました。