エムオーテックス株式会社が運営するテックブログです。

AWS WAF導入時にはまず「カウントモード」を使おう!

f:id:mo-nishida:20211126174728j:plain

こんにちは。インフラチームの倉橋です。

みなさんWAF導入してますか?

弊社ではAWSが提供している「AWS WAF」を利用しています。

今回は、そのWAF導入による「誤検知」を防ぐために活用した「カウントモード」について書いていきます。

AWS WAFの「カウントモード」

カウントモードとは、

  • ルール一致時に検知はするが「許可」も「拒否」も行わない

ものとなります。

この機能を適用することで事前に「どのようなリクエスト」「どのようなルールに一致」しているかを知ることができます。

「正常なリクエストをブロック」する「誤検知」を事前に知ることができる素晴らしい機能です。

「カウントモード」の適用方法

カウントモードを適用する方法は、

  1. ルール全体を「カウントモード」とする方法
  2. 一部ルールを「カウントモード」とする方法

の2種類があります。

それぞれについて、

  • AWSコンソール
  • CloudFormationテンプレート

で適用する方法を以下に記載していきます。

※今回対象としているルールは「AWSマネージドルール」となります。

AWSマネージドルールについては以下リンクを参照

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/aws-managed-rule-groups.html

ルール全体を「カウントモード」とする方法

AWSコンソール

  1. ルール編集画面を開きます
  2. 「Override rule group action - optional」にチェックを入れます
    f:id:mo-kurahashi:20211214230627p:plain
  3. 保存します
  4. ルール詳細で「Override rule group action to count」と設定が入っていればOK
    f:id:mo-kurahashi:20211214230713p:plain

CloudFormationテンプレート

テンプレートで指定する場合は OverrideAction: を指定することで適用できます。

ルール1つ1つに指定する必要があります。

Resources:
  # Client WebACL for Regional
  CountModeWAF:
    Type: AWS::WAFv2::WebACL
    Properties: 
      Name: CountModeWAF
      Description: Protect Client API for Regional Service.
      Scope: REGIONAL
      DefaultAction: 
        Allow: {}
      VisibilityConfig:
        MetricName: CountModeWAF
        CloudWatchMetricsEnabled: true
        SampledRequestsEnabled: true
      Rules:
        - Name: AWS-AWSManagedRulesAmazonIpReputationList
          Priority: 1
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesAmazonIpReputationList
          # ココから
          OverrideAction:
            Count: {}
          # ココまで
          VisibilityConfig:
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesAmazonIpReputationList
            SampledRequestsEnabled: true

一部ルールを「カウントモード」とする方法

AWSコンソール

  1. ルール編集画面を開きます
  2. 「カウントモード」としたいルールの「Count」にチェックを入れます
  3. 保存します
  4. ルール詳細で「Count」と設定が入っていればOK

f:id:mo-kurahashi:20211214230840p:plain
2. 「カウントモード」としたいルールの「Count」にチェックを入れます

f:id:mo-kurahashi:20211214230857p:plain
4. ルール詳細で「Count」と設定が入っていればOK

CloudFormationテンプレート

テンプレートで指定する場合は ExcludedRules: で「カウントモード」にするルールを指定することで適用できます

OverrideAction:None で指定します。

こちらもルール1つ1つに指定する必要があります。

Resources:
  # Client WebACL for Regional
  CountModeWAF:
    Type: AWS::WAFv2::WebACL
    Properties: 
      Name: CountModeWAF
      Description: Protect Client API for Regional Service.
      Scope: REGIONAL
      DefaultAction: 
        Allow: {}
      VisibilityConfig:
        MetricName: CountModeWAF
        CloudWatchMetricsEnabled: true
        SampledRequestsEnabled: true
      Rules:
        - Name: AWS-AWSManagedRulesCommonRuleSet
          Priority: 1
          Statement:
            ManagedRuleGroupStatement:
              VendorName: AWS
              Name: AWSManagedRulesCommonRuleSet
          # ココから
              ExcludedRules:
                - Name: NoUserAgent_HEADER
                - Name: SizeRestrictions_BODY
          OverrideAction:
            None: {}
          # ココまで
          VisibilityConfig:
            CloudWatchMetricsEnabled: true
            MetricName: AWSManagedRulesCommonRuleSet
            SampledRequestsEnabled: true

「カウントモードの」ログ出力と監視

上記の方法で「カウントモード」の適用ができた後は監視フェーズに移ります。

監視する方法として以下があります。

  1. サンプルによる監視
  2. WAFログによる監視

「サンプルによる監視」はルール一致した一部のリクエストを監視します。

f:id:mo-kurahashi:20211214232344p:plain
1. サンプルによる監視

「WAFログによる監視」はCloudWatchやAthenaでログを監視します。

全てを監視するにはログを確認する必要があります。

WAFログの出力方法

WAFログはS3とCloudWatchLogsへの出力に対応しています。

今回はS3出力を取り扱います。

S3出力設定は2021年11月に WAFからS3 へ直接出力できるアップデートがあり、より簡単に設定できるようになりました!

それ以前は間に KinesisFirehose が必要でした。

S3出力

  1. ログ出力先のS3バケットを作成します
    1. バケット名の先頭は aws-waf-logs- で始める必要がある点に注意
  2. WebACLの「Logging and metrics」を開きます
  3. 「Logging destination」で「S3 bucket」にチェックをいれます
  4. バケットは 1. で作成したバケットを指定します
  5. 「Filter logs」の設定を行い出力されるログを「Block」および「Count」だけに絞ります
    1. 「Allow」を出力する場合リクエスト数が多いサービスと、S3ストレージコストに影響を与える可能性があるので要注意です
  6. 設定を保存します
  7. S3にログが出力されているか確認します

WAFログの監視方法

S3へログ出力されるようになったので次にログの監視に入ります。

S3のログは Athena でクエリをかけて閲覧します。

Athenaテーブルの作成

S3にあるデータにクエリをかけるためにはテーブルを作成する必要があります。

テーブル作成方法はAWS公式ドキュメントに記載がありますのでご参照ください。

https://docs.aws.amazon.com/ja_jp/athena/latest/ug/waf-logs.html#create-waf-table-partition-projection

今回はパーティション管理を自動化できる「パーティション射影」を使用したテーブル作成を行っています。

「パーティション射影」を使うことでパーティションが自動化され、いつでも最新のログをクエリすることが可能となるのです。(便利ですね)

Athenaでクエリ

テーブルの作成ができたらクエリをかけてログを閲覧していきます。

クエリは以下を作成しました。

with dataset as (
    select webaclid,
        nonterminatingmatchingrules,
        httpsourcename,
        httpsourceid,
        labels,
        terminatingrulematchdetails,
        httpRequest.clientip,
        httpRequest.country,
        from_unixtime(timestamp / 1000, 'Asia/Tokyo') AS JST,
        httprequest
    from [table]
    where day in ('2021/11/02') 
        and webaclid = '[webaclid]'
)
SELECT webaclid,
    nonterminatingmatchingrule.ruleid as ruleid,
    httpsourcename,
    httpsourceid,
    label.name as label,
    terminatingrulematchdetails,
    httpRequest.clientip,
    httpRequest.country,
    JST
FROM dataset
    CROSS JOIN UNNEST(labels) as t(label)
    CROSS JOIN UNNEST(nonterminatingmatchingrules) as t(nonterminatingmatchingrule)

今回参考にするログ項目は以下になります。

参考にするログ項目

項目 内容 備考
timestamp タイムスタンプ (ミリ秒単位)
webaclid ウェブ ACL の GUID このIDでWebACLを識別します
ex) arn:aws:wafv2:us-east-1:[account_id]:global/webacl/[WebACL_NAME]/[WebACL_ID]
terminatingrulematchdetails リクエストに一致した終了ルールに関する詳細情報
SQLi および XSS に一致するルール時だけ出力
httpsourcename リクエストの送信元 CloudFront, ALB などの識別に使用
ex) CF,APIGW,ALB,APPSYNC
httpsourceid ソース ID 関連付けされたリソースのIDが入る
ALB,APIGWなどの識別に使用
nonterminatingmatchingrules (JSON配列) リクエストに一致するルールグループ内の終了しないルールのリスト カウントモードでどのルールに一致したか解析するために使用
labels ウェブリクエスト上のラベル (JSON配列) どのルールによってリクエストが評価されたか解析するために使用
httprequest.clientip クライアントIP
httprequest.country
httprequest リクエストに関するメタデータ (JSONオブジェクト)

より詳細な情報はAWS公式ドキュメントを参照ください。

docs.aws.amazon.com

ログの精査

出力したログの確認方法ですが、

  • labels がどのルールに一致したか確認する
  • httprequest を見てリクエストが正常か異常かを判断する

がベースになるかと思います。

サービスによって何が正常であるか異なってくるので、それぞれのサービスの観点を見つけていくことが大事だと思います。

ルールの見直し

最後に「カウントモード」の結果を受けてルール修正を行いましょう。

その後、修正したルールによるログを再度監視することも忘れずに。

おわりに

AWS WAFの「カウントモード」について書いていきました。

サービス影響を出さないためにも、AWS WAF適用時には「カウントモード」で事前確認は必須であると考えいますので、ぜひ活用していきましょう!