AWS WAF のレートベースルールの設定について
概要
AWS WAF のレートベースルールについて、日本語情報があまりなかった[1]ので、 設定内容や選択肢の意味、公式のドキュメントに記載されている内容で気をつけたほうがいいことなど、自分なりにまとめました!
そもそも、AWS WAF とは
一般的に WAF (Web Application Firewall) は、Web アプリケーションへの脆弱性を悪用した攻撃に対して、ブロックしたり、解析・検査を行ったりすることで、アプリケーションを保護するものです。
とくに、Web サーバーの前段に設置することで、自環境への侵入を防ぐ構成になります。[2]
そして、今回のテーマである AWS WAF は、AWS が提供する WAF で、Amazon CloudFront、Application Load Balancer (ALB) などの AWS リソース[3]に関連付けることで、上記のような Web アプリケーションへの攻撃を防御する機能を提供します。
AWS WAF では、IP アドレスやリクエストの内容に応じて、そのリクエストをブロックしたり、カウントのみを行ったり、場合によっては Bot 対策に CAPTCHA 認証をしたりできます。
また、リクエストを判定するルールは、開発者でカスタムすることも可能ですが、AWS マネージドなルールグループも提供されており、開発者がより開発に集中できるようにもなっています。[4]
レートベースルール (Rate-based rule) とは
ここからが本題のレートベースルール (Rate-based rule) についてです。
レートベースルールは AWS WAF で管理する Web ACLs (Web access control lists) [5]内のルールの一つです。
管理コンソールでは、Regular rule
と Rate-based rule
が選べます。
上記の画像内の説明にもある通り、
このレートベースルールを用いることで、特定の評価基準(criteria)に合致したリクエストごとに、レート(時間単位のリクエスト数)の上限値を設けることができます。
設定項目について
ここからは、設定する項目ごとの説明をします。
評価基準(criteria)の画面
Rate-based rule
を選択すると上記の画像に表示された項目を選択・入力する必要があります。それぞれの項目について説明していきます。
Rate limit
(レート制限)
Evaluation window
(後述)でのリクエスト数のしきい値のこと。
設定可能な範囲は 10 から 2,000,000,000 までです。
Evaluation window
(評価ウィンドウ)
リクエストの評価範囲(時間枠)のこと。
「1分(60秒)」、「2分(120秒)」、「5分(300秒)」、「10分(600秒)」の4つから選択できます。
Request aggregation
(リクエスト集約)
リクエストをカウントする際にどの条件で集約させるかを決めます。
現状、以下の 4 種類が選択可能です。
-
Source IP address
(リクエスト元 IP アドレス) -
IP address in header
(ヘッダー内 IP アドレス) -
Custom keys
(カスタム・キー) -
Count all
(全てを対象)
それぞれについて説明します。
Source IP address
(リクエスト元 IP アドレス)
リクエスト元の IP アドレスを条件にする場合はこれを選択します。
自環境の中で一番外側の AWS リソースであれば、これを選択することで、エンドユーザーのリクエストをその IP アドレス単位で集計します。
この場合に注意したいことは、関連づけた AWS リソースにとってのクライアントの IP アドレスを厳密に見ることです。
具体的には、プロキシやロードバランサーを経由後の AWS リソースに対して、このルールを適用すると、意図したエンドユーザーのクライアント IP アドレスではなく、直前のプロキシやロードバランサーの IP アドレスで集約することとなる可能性があります。
(とくに、正常・不正問わず、すべてのリクエストがプロキシやロードバランサーを経由するので、すぐにレート上限に達することが起こり得ます。)
IP address in header
(ヘッダー内 IP アドレス)
HTTP ヘッダーに含まれるクライアントの IP アドレスを条件にする場合はこれを選択します。
先程の Source IP address
にも書きましたが、自身のネットワーク内で中継している場合に IP アドレスがうまく取れない場合はこちらを活用します。
例えば、ALB では、X-Forwarded
ヘッダーの設定ができます。
この X-Forwarded
ヘッダーにクライアントの IP アドレスを設定することで、中継したあとのリソースに対しても、エンドユーザーのクライアント IP アドレスを連携することができます。[6]
そうすることで、この IP address in header
の設定で、前段で設定した HTTP ヘッダー内の IP アドレスでリクエスト件数を集約させることができます。
また、この選択をすると、以下について設定が必要となります。
IP address in header 選択時の追加設定内容
Header field name
(ヘッダー名)
IP アドレスが含まれている HTTP ヘッダー名を設定してください。
基本は X-Forwarded-For
のはずだが、プロキシによってカスタマイズすることも出来るので、その場合はそのカスタマイズしたヘッダー名を設定します。
Position inside header
(ヘッダー内の対象の位置)
2024年12月時点で設定が First IP address
固定です。[7]
X-Forwarded-For
の標準的な仕様・ルール上、複数の IP アドレスがある場合は一番最初の IP アドレスが大元のクライアント IP であるので、これでひとまず OK なはず。。。[8]
Fallback for missing IP address
(IP アドレスがない場合の挙動)
もし設定したヘッダーに有効な IP アドレスがないリクエストに対してルールを適用させるかどうかをハンドリングできます。
ただし、上記で設定した HTTP ヘッダーがそもそもない場合は、ルールを適用しないことは注意が必要です。[9]
ここで選べる選択肢のそれぞれの意味は以下のとおりです。
-
Match
:ヘッダーはあるが、有効な IP アドレスがなくてもルール適用させたい場合に選ぶ -
No match
:ヘッダーはあるが、有効な IP アドレスがないときはルール適用させたくない場合に選ぶ
Scope of inspection and rate limiting
(レートベースルールの対象範囲)
すべてのリクエストに対して管理するのか、更に条件(スコープダウン)を追加して管理するか決められます。
ここでの選択肢のそれぞれの意味は以下のとおりです。
-
Consider all requests
- とくに追加の条件が要らない場合に選択する
- こちらを選択すると、あとはアクションの設定になる
-
Only consider requests that match the criteria in a rule statement
- 追加で条件を加える場合はこちらを選択する
- 例えば、特定の国からのアクセスを条件にするとか、POST メソッドを条件にするとかが可能
- こちらを選択すると、スコープダウンする設定ができるフォームが表示される(詳細は後述)
Custom keys
(カスタム・キー)
IP アドレス以外の条件を使ってリクエストを集約させたい場合に使用する。
設定できる項目は以下の画像の通りです。
Custom key
選択時の集約対象の選択肢
例えば、リクエストの URI パスで集約させたりなどが可能です。
また、最大 5 つまで、条件をかけ合わせることができます。
なので、HTTP メソッドと IP アドレスの掛け合わせや、上記の画像の通り、独自定義した HTTP ヘッダーも条件に加えることが可能です。
また、この Custom keys
を選択すると IP address in header
でも選択対象となった Scope of inspection and rate limiting
が有効になりますが、前述と変わりないので説明は割愛します。
Count all
(全てを対象)
集約単位をとくに設定せず、検査対象とするリクエストのみ条件をつける場合に使用します。
なので、これを選択すると、スコープダウンステートメントの設定のみになります。(詳細は後述。)
スコープダウンステートメントの設定
レートベースルールの選択によって、特定の条件のリクエストのみを対象にできます。[10]
具体的には以下の画像のようなフォームになっています。
スコープダウンステートメントの設定フォーム
また、それぞれの設定項目についても、それぞれ以下である。
スコープダウンステートメントに対しての扱い
スコープダウンステートメントに設定できる条件
条件も AND
や OR
、NOT
を組み合わせて、リクエスト IP の特定の国をはじめとしたリクエストの内容を使って特定のリクエストのみを、このレートベースルールの対象にすることができます。
細かい設定項目については、かなり広範になるため、割愛します。
その代わり、使い方をはじめとした設定例(ユースケース)の例示で説明したいと思います。
アクション
Action の設定部分
こちらはレートベース特有のものではないので、詳細は割愛しますが、上記で設定した内容に合致した場合のアクションを設定します。
ここでは、許可やブロックだけでなく、CAPTCHA 認証も選択可能です。
作成例
(1) 海外(日本国外)からのリクエストに対して、特定時間単位で同一 IP アドレスからの一定以上のアクセスは遮断するケース
サービスが日本国内に限ったものである場合は、海外 IP アドレスからの DoS 攻撃をレートベースで軽減することが可能です。
具体的には下記の画像のような設定にすることで、海外からの同一 IP アドレスで分間 300 リクエストを上限とした設定ができます。[11][12]
(2) 特定のエンドポイントへのリクエストに対して、特定時間単位で一定数以上のアクセスは遮断するケース
特定のエンドポイント /foo/bar
を保護するためにも、平時では考えられない急激なアクセスへのブロックが可能です。
設定のイメージは下記の画像になります。
注意点や考慮事項
Block
設定にするのではなく、まずは Count
設定にすること
いきなり これはレートベースルールに限らない話ですが、WAF の設定において共通しては気をつけたほうがいいことです。
よほど自信がない限りは、最初に設定を始める際は Count
モードにしてから、WAF が意図したリクエストを捕捉できているかを確認してから進めるのが良いでしょう。
いきなり、Block
に設定して、正常なリクエストまでもブロックしてしまうと目も当てられない状況になります。
なので、まずは様子を見るためにも、Count
モードで試しましょう。
レートベースの検知に関してはある程度のベストエフォートであること
AWS WAF のドキュメントには下記の通り、記載があります。
AWS WAF rate limiting is designed to control high request rates and protect your application's availability in the most efficient and effective way possible. It's not intended for precise request-rate limiting.
- AWS WAF estimates the current request rate using an algorithm that gives more importance to more recent requests. Because of this, AWS WAF will apply rate limiting near the limit that you set, but does not guarantee an exact limit match.
- Each time that AWS WAF estimates the rate of requests, AWS WAF looks back at the number of requests that came in during the configured evaluation window. Due to this and other factors such as propagation delays, it's possible for requests to be coming in at too high a rate for up to several minutes before AWS WAF detects and rate limits them. Similarly. the request rate can be below the limit for a period of time before AWS WAF detects the decrease and discontinues the rate limiting action. Usually, this delay is below 30 seconds.
- If you change any of the rate limit settings in a rule that's in use, the change resets the rule's rate limiting counts. This can pause the rule's rate limiting activities for up to a minute. The rate limit settings are the evaluation window, rate limit, request aggregation settings, forwarded IP configuration, and scope of inspection.
上記を簡単に訳して、大事な箇所を太字にすると、
AWS WAF のレート制限は、高いリクエスト率を制御し、アプリケーションの可用性をできるだけ効率的かつ効果的に保護するよう設計されています。 これは、正確なリクエストレートを制限することを目的としたものではありません。
- AWS WAF は、現在のリクエストレートを推定する際、最近のリクエストにより重みを置くアルゴリズムを使用しています。 そのため、設定した制限に近いレートでレート制限が適用されますが、正確な制限値が保証されるわけではありません。
- AWS WAF がリクエストレートを推定するたびに、設定された評価ウィンドウ内で発生したリクエストの数を参照します。このため、また伝播遅延などの要因により、リクエストが高すぎるレートで数分間送信され続けても、それを検知してレート制限を適用するまでに時間がかかる場合があります。 同様に、リクエストレートが制限以下に達しても、AWS WAF が減少を検出してレート制限を解除するまでに時間がかかることがあります。この遅延は通常30秒未満です。
- 使用中のルールでレート制限設定を変更した場合、ルールのレート制限カウントがリセットされるため、レート制限の動作が最大で1分間停止する可能性があります。レート制限設定には、評価ウィンドウ、レート制限、リクエスト集計設定、転送されたIPの設定、検査範囲が含まれます。
となります。
この文章からも急激なリクエストの増加や減少に対して、厳密にルール適用ができないケースがあることを頭に入れておいたほうがいいですね。
さいごに
AWS WAF のレートベースルールは急激なトラフィックの増加、特に (D)DoS 攻撃への有効な防御策になります。
一方で、正常なリクエストに対してブロックしてしまわないためにも、ルール適用に際しては、検証や確認を十分に実施して取り組むことをおすすめします!
参考
- AWS WAF
- Application Load Balancers
-
もしかすると誰かがまとめていて、自分が探せていないだけかもしれない。何番煎じでもいい、自分はまだ煎じていない。そんなスタンス。 ↩︎
-
防火壁(Firewall)のイメージにぴったりですね。 ↩︎
-
https://docs.aws.amazon.com/waf/latest/developerguide/waf-chapter.html によると、他には、Amazon API Gateway REST API, AWS AppSync GraphQL API, Amazon Cognito user pool, AWS App Runner service, AWS Verified Access instance があります。 ↩︎
-
とはいえ、無策に AWS が提供しているルールをそのまま適用するのも危ない。具体的には、リクエストボディのサイズで判定するルールもあったりするので、正常なリクエストに対して誤検知していないかの検証は必要。また、コストの観点も把握しておくことがベターです。 ↩︎
-
ここでは、AWS リージョンごと[5]に定義できる制御定義の単位と思ってください。ルールやカスタムレスポンスボディの設定や、トラフィックデータのモニタリングなどができます。 ↩︎
-
X-Forwarded-For
ヘッダーは容易になりすましができるものでもあるので、セキュリティ観点で別途注意が必要です。 ↩︎ -
ちなみに、別のルールタイプである IP set を選んだ場合の設定項目で、同様のヘッダー内の IP アドレスを見るようにすることもできます。ただ、IP set の場合は
Last IP address
とAny IP address
も選択可能です。 ↩︎ -
HTTP ヘッダーなので、リクエスト元のクライアントで書き換えが可能なので、常に正しいかは分からない。 ↩︎
-
HTTP ヘッダーはクライアント側で書き換えできてしまうので、意図しない値にしたり、ヘッダー項目自体を削除したりできるので、その点を押さえて設定しましょう。 ↩︎
-
対象の範囲を狭めるということで、スコープダウンと表現されています。 ↩︎
-
1 秒あたり 5 リクエストぐらいの頻度です。 ↩︎
-
また、上の説明でもしましたが、IP アドレスをどこを見るかは、環境の構成や関連付ける AWS リソースに応じて、適切に選択してください。 ↩︎
私たち BABY JOB は、子育てを取り巻く社会のあり方を変え、「すべての人が子育てを楽しいと思える社会」の実現を目指すスタートアップ企業です。圧倒的なぬくもりと当事者意識をもって、子どもと向き合う時間、そして心のゆとりが生まれるサービスを創出します。baby-job.co.jp/
Discussion