「X-Forwarded-For」ヘッダをサポートしたAWS WAFで CloudFront経由の過剰リクエストをELBで止めてみた

X-Foward-For のIPアドレスを判定対象としたレートベースの WAFルールを利用して、CloudFront経由でELBに到達した過剰なリクエストが遮断できる事を確認してみました。
2020.09.15

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

AWSチームのすずきです。

2020年7月、AWS WAF が X-Forwarded-For ヘッダーをサポートするアップデートがありました。

今回 X-Foward-Forに示されたリクエスト元のIPを判定対象とした レートベースのWAFルールを作成、 CloudFront 経由で到達した過剰なリクエストを、ELB用の AWS WAF でブロックできる事を確認する機会がありましたので、紹介させていただきます。

構成図

AWS WAF設定

ELB/CloudFront用

「Regional resources」を指定して、ELB用のACLを作成します。

  • Resource type: Regional resources
  • Region : 東京リージョン

ルール設定

ルールビルダーを利用しました。

2020年7月のアップデートにより、従来の「Souce IP」に加え「IP address in header」の指定が可能になりました。

CloudFront が付与する「X-Forwarded-For」ヘッダを利用する指定で、レートベースのルールを作成しました。

  • Type: Rate Based Rule
  • IP address to use for rate limiting : IP address in header
  • Header field name: X-Forwarded-For

ルール順序設定

複数のルールを利用する場合、評価順序を指定します。

CloudWatch と、AWS WAFダッシュボードで確認できるルールに該当したリクエストのサンプリング設定を行います。

保護対象のELB(ALB)、WAF ACLの設定画面で行います。

動作確認

「X-Forwarded-For」を判定対象とするWAFルールは「ブロック」、 キャッシュは無効となる設定のCloudFrontに対して連続リクエストを試みました。

リクエスト

「curl」コマンドを利用。ループで連続実行しました。(毎秒約50リクエスト)

while true
do
  curl http://xxxx.cloudfront.net -v
done

発動前

< HTTP/1.1 200 OK
< Content-Type: text/html; charset=UTF-8
< Content-Length: 9
< Connection: keep-alive
< Date: Mon, 14 Sep 2020 16:26:23 GMT
< Server: Apache/2.4.43 ()
< X-Cache: Miss from cloudfront

発動後

< HTTP/1.1 403 Forbidden
< Content-Type: text/html
< Content-Length: 134
< Connection: keep-alive
< Server: awselb/2.0
< Date: Mon, 14 Sep 2020 16:27:27 GMT
< X-Cache: Error from cloudfront

まとめ

CloudFront などの CDN を利用するシステムでも、Bot等による過剰なリクエストがオリジンに到達するとサービス影響が生じる事があります。

特定のIPアドレスからの連続したリクエストについてはレートベースのAWS WAFにより緩和が期待できますが、 CloudFrontを保護対象としたAWS WAF は リクエスト数に応じて発生する従量課金が課題となる事がありました。

CDNのキャッシュ利用効率が高い環境の場合、オリジンの ELB を保護対象とした AWS WAFは低コストでの利用が期待できます。 保護要件が満たせる場合、今回のアップデートをご活用ください。

参考リンク