ForgeVision Engineer Blog

フォージビジョン エンジニア ブログ

AWS WAF Web ACL Rule "Allow" と "Count" の違いを理解したよ

こんにちは、AWSグループの平原です。

皆様は、ダーツという室内競技をプレイしたことがあるでしょうか?
ダーツは円形のボードにアローを投げ、得点を競う室内競技です。
ゲームの種類は、シンプルに得点を競うカウントアップや特定の点数からカウントを減らしていくゼロワン、的のエリアを取り合うクリケットなどがあります。
最近では、ダーツバーやアミューズメント施設などで気軽に楽しむことができます。
私は会社のイベントなどで楽しむ程度ですが、とても面白い競技だと感じています。
皆様も機会があればぜひ挑戦してみてはいかがでしょうか。

といったところで今回は、AWS WAF Web ACL Rule の"Allow"と"Count"の違いを検証しつつ理解した時のことを記事にします。

はじめに

今回は業務で Amazon API Gateway の Rest API に Web ACL を設定した時に、Rule の "Allow"と"Count"の違いが個人的に理解できていなかったので、その際に調査し、検証した時の内容となります。

AWS WAF とは

AWS WAFは、保護されたウェブアプリケーションリソースに転送される HTTP(S) リクエストをモニタリングできるウェブアプリケーションファイアウォールです。

以下のリソースタイプを保護できます。

  • Amazon CloudFront ディストリビューション
  • Amazon API Gateway REST API
  • Application Load Balancer
  • AWS AppSync GraphQL API
  • Amazon Cognito ユーザープール
  • AWS App Runner サービス
  • AWS Verified Access インスタンス
  • AWS Amplify

docs.aws.amazon.com

Rule アクションの種類

Rule アクションの種類(設定時に選択できるオプション)は、以下です。

  • Allow
    AWS WAF リクエストを保護された AWS リソースに転送して処理および応答できるようにします。これは終了アクションです
    定義したRuleでは、リクエストを保護されたリソースに転送する前に、カスタムヘッダーを挿入できます。

  • Block
    リクエストを AWS WAF ブロックします。これは終了アクションです。
    デフォルトでは、保護された AWS リソースは HTTP 403 (Forbidden)ステータスコードで応答します。

  • Count
    リクエストを AWS WAF カウントしますが、許可するかブロックするかは決定しません。 これは非終了アクションです
    AWS WAF がウェブ ACL の残りのRuleの処理を継続します

  • CAPTCHA および Challenge
    CAPTCHA パズルとサイレントチャレンジ AWS WAF を使用して、リクエストがボットから送信されていないことを確認し、トークン AWS WAF を使用して最近成功したクライアントレスポンスを追跡します。

docs.aws.amazon.com

実際に検証してみた

上述のように、"Allow" はその Rule で処理が終了する「終了アクション」、"Count" は処理を続けて次の Rule も評価する「非終了アクション」です。

Web ACLs を設定する

AWS API Gateway - AWS Lambda 構成の API Gateway RestAPI にWeb ACLs を設定します。
(AWS API Gateway - AWS Lambda の構築については、省略します)

  1. AWS マネージメントコンソールにログインし、AWS WAFのページに遷移後、左ペインの Web ACLs をクリック
  2. Web ACLs を作成するリージョンを選択し、「Create Web ACL」をクリック

  3. 下記のように設定し、「Next」をクリック
    ・Resource type: Regional resources
    ・Region: Web ACL を設定するリソースのリージョン(今回の場合はAPI Gatewayのリージョン)
    ・Name: 任意の Web ACL名
    ・Description: 任意
    ・CloudWatch metric name: 自動的に"Name"と同じ値が入る(変更可能)
    ・「Add resources」をクリックし、Web ACL を設定するリソースを選択

  4. 「Add rule」>「Add my own rules and rule groups」をクリック
    ※ 検証のための Rule として、今回は Header でフィルタリングする設定を行います

  5. 下記のように設定し、「Add rule」をクリック
    ・Rule type: Rule builder
    ・Name: 任意の Rule名
    ・Type: Regular rule
    ・If a request: matches the statement
    ・Inspect: Single header
    ・Header field name: 任意のカスタム Headerキー
    ・Match type: Exactly matches string
    ・String to match: 任意のカスタム Headerの値
    ・Text transformation: None
    Action: Count ※この設定を変更しながら検証します

  6. 4, 5の手順を再度実施し、2つ目のRuleを追加
    以下3つを1つ目のRuleと異なる値で設定
    ・Name: 任意の Rule名
    ・Header field name: 任意のカスタム Headerキー
    ・String to match: 任意のカスタム Headerの値

  7. 元ページに遷移後、下記のように設定し、「Next」をクリック
    ・Default action: Allow

  8. 1つ目のRule の priority が上位となるように設定し、「Next」をクリック

  9. 下記のように設定し、「Next」をクリック
    ・Rules: 2つの Rule にチェック
    ・CloudWatch metric name: 任意のメトリクス名
    ・Options: Enable sampled requests

  10. 設定内容を確認し、「Create Web ACL」をクリック

API を実行する

Web ACLを設定した API GatewayのURLに対して、下記のように Header をつけてリクエストを実行します。

curl -H 'x-custom-header01:hogehoge01' -H 'x-custom-header02:hogehoge02' \
https://<API Gateway ID>.execute-api.ap-northeast-1.amazonaws.com/dev/hello

初期設定の状態で実行

1つ目のRuleのアクション: Count
2つ目のRuleのアクション: Count

レスポンス

{"message": "hello world"}

この場合は、Ruleが2つとも処理され、アクションがCountの為、正常レスポンスが返されます。

CloudWatchメトリクスを確認すると、2つのRuleアクションがCountであることが確認できます。

1つ目のRuleのアクションをAllowに変更して実行

1つ目のRuleのアクション: Allow
2つ目のRuleのアクション: Count

レスポンス

{"message": "hello world"}

この場合は、1つ目のRuleのみが処理され、アクションがAllowの為、正常レスポンスが返されます。
1つ目のRuleが終了アクションのAllowなので、2つ目のRuleは処理されません。

CloudWatchメトリクスを確認すると、1つ目のRuleアクションのAllowのみであることが確認できます。

2つ目のRuleのアクションをAllowに変更して実行

1つ目のRuleのアクション: Count
2つ目のRuleのアクション: Allow

レスポンス

{"message": "hello world"}

この場合は、Ruleが2つとも処理され、2つ目のRuleのアクションがAllowの為、正常レスポンスが返されます。
2つ目のRuleが終了アクションのAllowなので、2つ目のRuleまで処理されます。

CloudWatchメトリクスを確認すると、1つ目のRuleアクションはCountで、2つ目のRuleアクションはAllowであることが確認できます。

1つ目のRuleのアクションをBlockに変更して実行(おまけ)

1つ目のRuleのアクション: Block
2つ目のRuleのアクション: Count

レスポンス

{ "message": "403 waf-filter" }

この場合は、1つ目のRuleのみが処理され、アクションがBlockの為、エラーレスポンスが返されます。
1つ目のRuleが終了アクションのBlockなので、2つ目のRuleは処理されません。

CloudWatchメトリクスを確認すると、1つ目のRuleアクションのBlockのみであることが確認できます。

補足ですが、レスポンスのメッセージは、API Gatewayの"ゲートウェイのレスポンス"で設定したものとなります。

さいごに

AWS WAF Web ACL Ruleの "Allow" と "Count" の違いについて検証を踏まえ確認できました。

調査・検証を進める中で疑問に思ったのですが、"Count"アクションは評価のみで、許可やブロックは行わないので、何のために必要なのかと感じました。
"Count"アクションは、Rule を試験的に設定する際などによく使われます。いわゆる「経過観察期間」です。
これは、商用環境などでいきなり "Allow" もしくは "Block" アクションに設定して誤検知が発生した場合に、サービスに悪い影響を与えないようにするためです。

私と同様に "Allow" と "Count" の違いがいまいち理解できていない方などの参考になると幸いです。