Amazon Web Services ブログ

AWS WAF のログ分析に関する考慮事項

2022年11月 アップデート:

  • マネージドルールグループ内のルールに個別に Action を設定できるようになりました。その結果、 “EXCLUDED_AS_COUNT” ではなく “COUNT” としてログ出力できるようになりました。
  • 新たなルールの Action として、Challenge が追加されました。

本記事は、2022年11月のアップデート以前のログの仕様に基づいています。最新の情報はデベロッパーガイドを参照ください


この投稿では、AWS ウェブアプリケーションファイアウォール (AWS WAF) を初めて利用される方が 、ログ分析にあたって考慮すべき事項について説明します。
WAF のログは、攻撃検知の分析やチューニングには欠かせないものです。ログの分析ではウェブ ACL に設定したルールによって検知された結果がどのように出力されるかを理解することが重要となります。
AWS WAF の導入にあたっては、ルールのアクションを Count に設定し、検知状況を把握した上で、誤検知がないことを確認してから Block に切り替えるのが通常の手順となりますが、この誤検知がないことの確認に際して、Count で取得されたログを正しく分析する事が重要です。そのためには、この Count で取得されるログがルールの設定によって異なる内容で出力されることに注意する必要があります。

AWS WAF のログ出力先は当初 Amazon Kinesis Data Firehose 経由のみでしたが、2021年12月に新たなログの出力先に対応しております。現在では、Amazon CloudWatch LogsAmazon Simple Storage Service (Amazon S3) も選択可能となり、様々な方法で AWS WAF のログを分析できるようになりました。Amazon S3 に保存されたログは、Amazon Athena を利用して任意のクエリを実行することで分析することができます。また、CloudWatch Logs に保存されたログは、CloudWatch Logs Insights で分析できます。これは AWS WAF のマネジメントコンソールと統合されていますので、セットアップなしですぐにログの分析が可能となっています。
本記事では、初めてAWS WAF を利用される方がログを分析する際に理解すべきポイントや注意点、Count で取得されたログを Amazon Athena や CloudWatch Logs Insightsで抽出する方法についても簡単に説明します。

ログフィールドを理解する

AWS WAF のログは JSON 形式で出力されます。ログのフィールドについてはこちらのデベロッパーガイドで説明されていますが、ここではログフィールドを理解するために重要なポイントをいくつか列挙します。

“action” フィールド

ログの最初に記録される “action” フィールドは、“ALLOW” か “BLOCK”、または “CAPTCHA” (ルールの Action に CAPTCHA が利用され、リクエストに有効なトークンがない場合)のいずれかとなり、ここに “COUNT” は記録されません。Count されたかどうかは、最初の Action とは別のフィールドに記録されます。
“ALLOW” は、Action が Block に設定された全てのルールにリクエストが合致せず Default web ACL action によって許可された場合、または、Action が Allow に設定されたルールにリクエストが合致した時に記録されます。“BLOCK” は、Action が Block に設定されたルールにリクエストが合致した時に記録されます。(Default web ACL action を Block に設定した場合は、Action が Allow に設定されたルールにリクエストが合致しない場合、 “BLOCK”として記録されます)

以下に実際のログの例を示します。

図1: “BLOCK” のケース

図2: “ALLOW” のケース

完全なログのサンプルはこちらのドキュメントを参照ください

“action” フィールドは、上記の最初に記録されるもの以外に、 “nonTerminatingMatchingRules” 内に記録されるもの (“COUNT” の場合)と ” terminatingRule” 内に記録されるもの(”BLOCK” の場合)もあります。”COUNT” については、設定内容によって、”action” フィールドでは無く、“excludedRules” 内に “exclusionType”: “EXCLUDED_AS_COUNT” として記録されるケースもありますので、次にその違いについて詳しく説明します。

“COUNT” と “EXCLUDED_AS_COUNT” の違い

AWS WAF のウェブ ACL 内のルールを Count に設定した場合、以下の二種類の Count のログのパターンが存在します。設定上は同じ Count に見えますが、設定方法やルールによって Count ログのエントリが変化することに注意が必要です。

1: “nonTerminatingMatchingRules”内に“action”:“COUNT” として記録

2: “excludedRules”内に“exclusionType”: “EXCLUDED_AS_COUNT” として記録

1 の“nonTerminatingMatchingRules”内に“action”:“COUNT” として記録されるケース(図5)は、以下のルール設定の場合となります。

  • カスタムルール(Add my own rulesで作成)の Action を Count に設定した場合
  • マネージドルールグループの “Override rule group action to count” を有効化した場合

図3: カスタムルール の設定

図4: Override rule group action の設定

図5: “action”:“COUNT” のログの例

マネージドルールグループのルールが “Use action defined in the rule” (Block の設定)で “Override rule group action to count” を有効化した場合に、ルールに合致した際、図5のように “nonTerminatingMatchingRules” 内に “action”:“COUNT” として記録されますが、”terminatingRule” 内には、”action”: “BLOCK” が記録されます。これはマネージドルールグループのアクションが “Override rule group action to count” によって Count に上書きされる為、実際には Block されずに Count の挙動となります。

2 の“excludedRules”内に“exclusionType”: “EXCLUDED_AS_COUNT”として記録されるケース(図7)は、以下のルール設定の場合となります。

  • マネージドルールグループで ”Set all rule actions to count” で Count に設定した場合
  • マネージドルールグループで個別のルールを Count に設定した場合

図6: Rule action の Count 設定

図7: “EXCLUDED_AS_COUNT” のログの例

“matchedData“ フィールド

“matchedData” は、AWS WAF が受信したリクエストの中でルールに合致した部分を確認する為に利用できます。ルールの Action が Block に設定されている場合は 、図8のように “terminatingRuleMatchDetails” 内 、または、Override rule group action to count が有効になっている場合は、図9のように “nonTerminatingMatchingRules” の “ruleMatchDetails” 内に記録されますが、”EXCLUDED_AS_COUNT” の場合は記録されないことに注意してください。
(2022年9月現在、 “matchedData” に対応するルールセットは、SQL インジェクションとクロスサイトスクリプティング のルールです)

図8: リクエストが BLOCK され、“matchedData” が記録された例

図9: リクエストが COUNT され、“matchedData” が記録された例

ログ分析のための抽出方法

AWS WAF のルールの設定の違いにより、記録されるフィールドが変わるケースについて説明してまいりましたが、それらのフィールドを抽出するにはどのような方法があるでしょうか? 「“COUNT” と “EXCLUDED_AS_COUNT” の違い」で述べたとおり、Count 設定のログエントリには二種類のパターンが存在するため、設定の内容に応じて抽出条件を使い分ける必要があります。例えば、マネージドルールグループでルールグループ内の個々のルールを Count に設定した場合、または ”Set all rule actions to count” で Count に設定した場合 (図6: Rule action の Count 設定) は “EXCLUDED_AS_COUNT” を含むログエントリを抽出する必要があります。 ここでは、参考として CloudWatch Logs Insights や Amazon Athena を使って “EXCLUDED_AS_COUNT” を含むログエントリを抽出する方法と “action”:”COUNT” を含むログエントリを抽出する方法について簡単な例を示します。

例: CloudWatch Logs Insights で “EXCLUDED_AS_COUNT” を抽出するためのクエリ

fields @timestamp, @message
| filter @message like "EXCLUDED_AS_COUNT"
| sort @timestamp desc
| parse @message '"excludedRules":[{*}]' as excludedRules
| display @timestamp, httpRequest.clientIp, httpRequest.uri, httpRequest.country, excludedRules

filter コマンドを利用して “EXCLUDED_AS_COUNT” を含むログエントリを抽出

例: CloudWatch Logs Insights で “action”:”COUNT” を抽出するためのクエリ

fields @timestamp, @message
| filter @message like /"action":"COUNT"/
| sort @timestamp desc
| parse @message '"nonTerminatingMatchingRules":[{*}]' as nonTerminatingMatchingRules
| display @timestamp, httpRequest.clientIp, httpRequest.uri, httpRequest.country, nonTerminatingMatchingRules

filter コマンドを利用して “action”:”COUNT” を含むログエントリを抽出

例: Athena で “EXCLUDED_AS_COUNT” を抽出するためのクエリ

SELECT timestamp,
	httprequest.clientip,
	httprequest.uri,
	httprequest.country,
	t.rulegroupid,
	t.excludedrules
FROM "waf_logs"
CROSS JOIN UNNEST(rulegrouplist) AS t(t)
WHERE t.excludedrules IS NOT NULL

excludedrules が記録されている(NULLで無い) ログを検索することで、 “EXCLUDED_AS_COUNT” のログエントリを抽出

例: Athena で “action”:”COUNT” を抽出するためのクエリ

SELECT timestamp,
	httprequest.clientip,
	httprequest.uri,
	httprequest.country,
	t.ruleid
FROM "waf_logs"
CROSS JOIN UNNEST(nonTerminatingMatchingRules) AS t(t)
WHERE t.action='COUNT'

nonTerminatingMatchingRules 内の “action”:”COUNT” を検索することで、”COUNT” のログエントリを抽出

CloudWatch Logs の WAF ログ分析の設定については、Amazon CloudWatch Logs による AWS WAF ログの分析のブログを参照してください。また、Amazon Athena によるログ分析の設定については、こちらのユーザーガイドを参照してください。その他のクエリについては、AWS ナレッジセンターのドキュメントを参照ください。

ログのフィルタリングで COUNT ログを設定する際の注意点

AWS WAF のログのフィルタリング機能を活用し、必要なログのみを出力することで、ログの保管と分析に関わるコストを最適化することが可能です。以前はマネジメントコンソールでは “EXCLUDED_AS_COUNT” のログをフィルタリングすることができない為、CLI などで設定する必要がありましたが、マネジメントコンソールでも “EXCLUDED_AS_COUNT” を設定できるようになりました。(2022年9月29日現在)Count で取得されたログをフィルタリングする場合は、ルールの設定内容に応じて、Filter conditions で “Count” または、”EXCLUDED_AS_COUNT”を選択してください。

図10: ログのフィルター設定

CLI で “EXCLUDED_AS_COUNT” をフィルタリングする場合は、putLoggingConfiguration API を使用して設定することができます。

CLI コマンド例:

$ aws wafv2 put-logging-configuration --cli-input-json file://<下記のJSONを指定>

{
    "LoggingConfiguration": {
        "ResourceArn": "<ウェブACLのARN>",
        "LogDestinationConfigs": [
            "<ログの宛先のARN>"
        ],
        "ManagedByFirewallManager": false,
        "LoggingFilter": {
            "Filters": [
                {
                    "Behavior": "KEEP",
                    "Requirement": "MEETS_ANY",
                    "Conditions": [
                        {
                            "ActionCondition": {
                                "Action": "BLOCK"
                            }
                        },
                        {
                            "ActionCondition": {
                                "Action": "COUNT"
                            }
                        },
                        {
                            "ActionCondition": {
                                "Action": "EXCLUDED_AS_COUNT"
                            }
                        }
                    ]
                }
            ],
            "DefaultBehavior": "DROP"
        }
    }
}

ログフィルターの設定を含むJSON

CloudFormation については、こちらのデベロッパーガイドを参照ください。

例えば、上記の設定にて “COUNT” と “BLOCK”、”EXCLUDED_AS_COUNT” のログだけを出力するようにフィルタリングを実施した場合、マネジメントコンソール上では以下の様に表示されます。

図11: ログフィルターコンディションの例

まとめ

本記事では、AWS WAF ログを分析する際の考慮事項についてご説明しました。特に AWS WAF 導入時には、通常 Count モードにてモニタリングを開始することから運用を始めることが多いですが、Count の設定におけるログ出力の違いについて間違った理解をしている場合、正しく分析することができません。Amazon Athena や CloudWatch Logs Insights を活用して分析をする場合、ウェブ ACL 内のルールの設定内容に合わせてログの抽出方法を考慮する必要があります。また、ログのフィルタリング設定はログのコストを最適化するためにも利用できる機能ですが、必要なログが出力されるようにフィルターを正しく設定することも重要です。
以下に AWS WAF のログ分析をするにあたり参考となる資料へのリンクを記載しましたので、こちらもご確認ください。

(本記事は、2022 年 9 月時点の AWS WAF ログの仕様に基づいた内容となります。最新の情報はデベロッパーガイドを参照ください)

参考リンク

AWS WAF のログフィールド

ログの例

CloudWatch Logs Insights のクエリ構文

Amazon Athena AWS WAF ログのクエリ例

CloudWatch または Amazon S3 に保存されている AWS WAF ログを分析するオプションは何ですか?

Amazon CloudWatch Logs による AWS WAF ログの分析

このブログの著者

岡 豊 (Yutaka Oka)
Solutions Architect, Edge Services