cloudfront + WAF でソーリーページを表示する

この記事の目次
ゴール
- Cloudfrontへアクセスした際、以下のパターンに当てはまるときは事前に準備したS3上のファイルを表示させる。
- WAF遮断時
- メンテナンス時
- サーバ停止時
- ALBへのアクセス元をCloudfrontのみに制限する。
- 設定自体は簡単だが、詳細を記載
検証
初めに通常時のアクセスをするための構築を行う。
その後、各パターンによってS3上のファイルを表示させる。→方法としてCloudfrontのエラーページ設定を行う。
通常時
以下の構成とする。

- 設定内容(※東京リージョンで構築)
- ACM
- パブリック証明書:xxx.mynavi.jp
- Cloudfront(バージニア北部)用とALB(東京)用
- Cloudfront
- オリジン:ALB
- ビヘイビア:デフォルトでALBに転送
- ACMをアタッチ(代替ドメイン名:xxx.mynavi.jp)
- 443のみを受け付け、443でオリジンへ転送
- ALBが同じ証明書を使用するため、hostヘッダーの転送
- WAF
- マイナビIPを許可
- デフォルトはblock
- block時は403を返す
- ALB
- ACMをアタッチ(xxx.mynavi.jp)
- リスナーは443で、ターゲットのportは80
- セキュリティグループでアクセス元をCloudfrontに制限
- EC2
- apacheでport80からのアクセスを受け付け
- セキュリティグループでアクセス元をALBに制限
- ACM
アクセスした際の画面(apache表示)

ALBへのアクセス元をCloudfrontのみに制限する方法
AWSマネージドプレフィックスリストを使用することで制限が可能となる。
参考:公式ドキュメント
VPC>マネージドプレフィックスリストより、3つの設定が確認できる。
これはデフォルトで用意されているものとなっており、それぞれCloudfront,S3,dynamodbのCIDRが登録されている。
※デフォルト設定は所有者IDがAWSとなっている。
この設定を使用して、ALB側で制限をかける。

ALBのセキュリティグループの設定をする際に、ソースからプレフィックスリストを選択することができる。
アクセス元をCloudfrontのみに制限するため、CloudfrontのプレフィックスリストIDを選択する。

AWSマネージドプレフィックスリストが使用可能になる前のアクセス制限方法
- AWSが公開しているIPの範囲で制限
- AWSが公開しているIP一覧より、CloudFrontエッジサーバのIPを使用
- "service": "CLOUDFRONT_ORIGIN_FACING"→オリジンに接続するCloudFrontエッジサーバのIP
- "service": "CLOUDFRONT":クライアントからCloudFrontに接続しようとした際に、クライアント側でのアクセスするエッジサーバのIP
- AWSが公開しているIPは変更する可能性あり
- AWSが公開しているIP一覧より、CloudFrontエッジサーバのIPを使用
- カスタムヘッダーで制限
- cloudfront側でカスタムヘッダーを追加
- ヘッダー名と値は任意で推測されないような文字列を使用
- ALBのリスナールールで、IF条件(HTTPヘッダーがCloudfrontで指定したものになっているか)を使用
- 条件に当てはまったものを通常のターゲット先へ転送
- デフォルトアクション(条件に当てはまらなったもの)は503表示等で対応
- cloudfront側でカスタムヘッダーを追加
WAF遮断時
以下の構成とする。

- 設定内容
- Cloudfront
- オリジンにS3バケットを追加
- エラーページ設定
- 403の場合(WAF遮断時は403を返す設定)、/waf_block.htmlへ飛ばす
- ビヘイビア設定
- waf_block.htmlの場合、S3に飛ばす
- デフォルトはALBへ飛ばす
- WAF
- デフォルトはblock
- S3
- waf_block.htmlを配置
- Cloudfront
アクセスした際の画面(S3上のwaf_block.html)

サーバ停止時
以下の構成とする。

- 設定内容
- Cloudfront
- オリジンにS3バケットを追加
- エラーページ設定
- 503の場合(サーバ停止時は503を返す設定)、/server_stop.htmlへ飛ばす
- ビヘイビア設定
- server_stop.htmlの場合、S3に飛ばす
- デフォルトはALBへ飛ばす
- WAF
- マイナビIPを許可
- デフォルトはblock
- S3
- server_stop.htmlを配置
- EC2
- 停止
- Cloudfront
アクセスした際の画面(S3上のserver_stop.html)

メンテナンス時
以下の構成とする。

- 設定内容
- Cloudfront
- オリジンにS3バケットを追加
- エラーページ設定
- 403の場合(WAF遮断時は403を返す設定)、/maintenance.htmlへ飛ばす
- ビヘイビア設定
- maintenance.htmlの場合、S3に飛ばす
- デフォルトはALBへ飛ばす
- WAF
- デフォルトはblock
- S3
- maintenance.htmlを配置
- Cloudfront
アクセスした際の画面(S3上のmaintenance.html)

各htmlファイルを保管しているS3バケット
同じバケットの中にhtmlファイルを配置して検証を行った。

まとめ
- 商用サービスの場合、以下のような構成とすることでsorryページ等を表示することが可能
- Cloudfrontのエラーページ設定をすることで、各ステータスコードに対応するS3ファイルを表示可能
- 本記事では403と503を扱ったがその他のエラーコードにも対応
- メンテナンス時はWAFで特定のIPのみを許可し、デフォルトはブロックすることで、WAF遮断時にメンテンナスページを表示可能
- 本来のWAF遮断ページをメンテナンスページに変更する
- 本来のWAF遮断ページをメンテナンスページに変更する
- ALBへのアクセス元をCloudfrontのみに制限
- AWSマネージドプレフィックスリストを使用
- 2022/02/07からCloudfrontプレフィックスリストが使用可能
- 従来と比べて便利
- AWSマネージドプレフィックスリストを使用
※本記事は2022年08月時点の情報です。