AWS WAFでカウントされたログ取りこぼしてませんか?
AWS WAFのログでCOUNT
されたリクエストのみを保存しようとしたときに、実はCOUNT
だけではフィルタ条件として不十分だったという経験を共有しておこうと思います。
最初に三行まとめ
- AWSマネージドルールのカウントは
COUNT
ではなくEXCLUDED_AS_COUNT
で記録されるものもある - AWSコンソールからログフィルターの条件として
EXCLUDED_AS_COUNT
を選択できない - 条件マッチのログのみ保存している場合、
BLOCK
とCOUNT
だけをフィルタ条件にしてるとログを取りこぼしてる可能性ある
あくまでログフィルタを使用して条件マッチしたログのみを取得している場合です。全リクエスト分のログを取得している環境は安心して読み飛ばしてください!
COUNTログ少なくない?
AWS WAFでブロックルールを検討するために、COUNT
されたリクエストのみをCloudWatch Logsに出力するつもりで以下のように設定していました。
(補足)
ちなみに今回はルールグループ毎にSet all rule actions to count
を設定してカウントを取得している環境になります。Override rule group action
でカウント設定している場合はCOUNT
で出力されます。
とりあえずログが出力されることを確認するために自分のIPアドレスをカウントするカスタムルールを設定し、以下のようなログが出力されることを確認していました。
nonTerminatingMatchingRules.0.action COUNT nonTerminatingMatchingRules.0.ruleId cm_restrict_ipset
しばらくの間、CloudWatchのメトリクスを眺めながら「ふむふむ、結構、Countedのリクエストも増えてきたな」と、この状態でログを溜めているつもりでした。
「そろそろ収穫時だな」と言わんばかりに、溜まったであろうログに対して分析をかけたところCloudWatchメトリクスで見てたようなCouted
リクエスト数ほどのログ件数がありません。。
何が起きたんでしょう??
EXCLUDED_AS_COUNTで記録される
ログの出力確認をカスタムルールを使って確認していたので、COUNT
されたリクエストのログは全てCOUNT
で出力されるものだと思い込んでました。
しかしながらマネージドルールでCOUNT
と判断されたリクエストのログは以下のようにEXCLUDED_AS_COUNT
として出力されるものがあります。
ruleGroupList.0.excludedRules.0.exclusionType EXCLUDED_AS_COUNT ruleGroupList.0.excludedRules.0.ruleId SignalKnownBotDataCenter ruleGroupList.0.ruleGroupId AWS#AWSManagedRulesBotControlRuleSet
マネージドルール内でも以下のようにCOUNT
として記録されるものもあるので、ある程度ログが取得できてるようにも見えてしまうのも気をつけたいポイントです。ちなみに細かい仕様は解ってないませんので、ここではCOUNT
とEXCLUDED_AS_COUNT
の両方必要、くらいに認識していただければ良いかと思います。(細かな出力条件の違いについて知ってる方がいたら教えてください!)
ruleGroupList.4.excludedRules.0.exclusionType EXCLUDED_AS_COUNT ruleGroupList.4.excludedRules.0.ruleId SignalKnownBotDataCenter ruleGroupList.4.ruleGroupId AWS#AWSManagedRulesBotControlRuleSet ruleGroupList.5.nonTerminatingMatchingRules.0.action COUNT ruleGroupList.5.nonTerminatingMatchingRules.0.ruleId AWSManagedReconnaissanceList ruleGroupList.5.ruleGroupId AWS#AWSManagedRulesAmazonIpReputationList
また、なぜEXCLUDED_AS_COUNT
の存在に気づかなかったというと確認方法を横着したというのもありますが、一番の理由はログフィルターの条件としてEXCLUDED_AS_COUNT
をWebコンソールからは選択できない(見えない)ことだと思います。。
この選択肢を見てしまうとCOUNT
でOKなんだ、と思いますよね。。なので、「これは同じように事故ってる人いるかもな、、」と思い今回記事にしました。
AWS CLIを使ってログフィルターを設定する
EXCLUDED_AS_COUNT
をフィルタ条件に追加するにはAWS CLIなどから設定が必要です。
まず既存のログフィルターを確認しましょう。今回はCloudFront向けのWebACLだったので--scope=CLOUDFRONT
や--region=us-east-1
を指定していますが、CloudFront以外の場合は--scope=REGIONAL
を指定します。
$ aws wafv2 list-logging-configurations --scope=CLOUDFRONT --region=us-east-1 LoggingConfigurations: - LogDestinationConfigs: - arn:aws:logs:us-east-1:XXXXXXXXXXXX:log-group:aws-waf-logs-test-webacl LoggingFilter: DefaultBehavior: DROP Filters: - Behavior: KEEP Conditions: - ActionCondition: Action: BLOCK - ActionCondition: Action: COUNT Requirement: MEETS_ANY ManagedByFirewallManager: false ResourceArn: arn:aws:wafv2:us-east-1:XXXXXXXXXXXX:global/webacl/test_webacl/701xxxxx-xxxx-xxxx-xxxx-d60exxxxxxxx $ aws wafv2 get-logging-configuration --resource-arn arn:aws:wafv2:us-east-1:XXXXXXXXXXXX:global/webacl/test_webacl/701xxxxx-xxxx-xxxx-xxxx-d60exxxxxxxx --region=us-east-1 LoggingConfiguration: LogDestinationConfigs: - arn:aws:logs:us-east-1:XXXXXXXXXXXX:log-group:aws-waf-logs-test-webacl LoggingFilter: DefaultBehavior: DROP Filters: - Behavior: KEEP Conditions: - ActionCondition: Action: BLOCK - ActionCondition: Action: COUNT Requirement: MEETS_ANY ManagedByFirewallManager: false ResourceArn: arn:aws:wafv2:us-east-1:XXXXXXXXXXXX:global/webacl/test_webacl/701xxxxx-xxxx-xxxx-xxxx-d60exxxxxxxx
get-logging-configuration
の出力をベースに以下のようにEXCLUDED_AS_COUNT
条件を加えて設定ファイルを作成します。
$ vi logging.yaml LoggingConfiguration: LogDestinationConfigs: - arn:aws:logs:us-east-1:XXXXXXXXXXXX:log-group:aws-waf-logs-test-webacl LoggingFilter: DefaultBehavior: DROP Filters: - Behavior: KEEP Conditions: - ActionCondition: Action: BLOCK - ActionCondition: Action: COUNT - ActionCondition: Action: EXCLUDED_AS_COUNT Requirement: MEETS_ANY ManagedByFirewallManager: false ResourceArn: arn:aws:wafv2:us-east-1:XXXXXXXXXXXX:global/webacl/test_webacl/701xxxxx-xxxx-xxxx-xxxx-d60exxxxxxxx
設定ファイルが準備できましたら、put-logging-configuration
で設定ファイルを渡してログフィルターの設定が完了します。
$ aws wafv2 put-logging-configuration --cli-input-yaml file://logging.yaml --region=us-east-1 LoggingConfiguration: LogDestinationConfigs: - arn:aws:logs:us-east-1:XXXXXXXXXXXX:log-group:aws-waf-logs-test-webacl LoggingFilter: DefaultBehavior: DROP Filters: - Behavior: KEEP Conditions: - ActionCondition: Action: BLOCK - ActionCondition: Action: COUNT - ActionCondition: Action: EXCLUDED_AS_COUNT Requirement: MEETS_ANY ManagedByFirewallManager: false ResourceArn: arn:aws:wafv2:us-east-1:XXXXXXXXXXXX:global/webacl/test_webacl/701xxxxx-xxxx-xxxx-xxxx-d60exxxxxxxx
これでマネージドルールによってCOUNTされたすべてのログ出力が拾えるようになります!
まとめ
- AWS WAFのマネージドルールでカウントされたログは
EXCLUDED_AS_COUNT
として記録されるものもあります - そのため、ログフィルターの条件を
BLOCK
とCOUNT
のみ設定しているとカウントされたリクエストログを取りこぼしている可能性があります - AWS管理コンソールからはログフィルターの条件に
EXCLUDED_AS_COUNT
を選択できません EXCLUDED_AS_COUNT
をフィルタ条件に設定する場合はAWS CLIなどを使用します- そもそもコスト的な懸念がなければフィルタリングすることなく全量ログを保存しておけば安心