AWS WAFのWeb ACL(保護パック)でCloudWatch Logsにログを出力している場合はコスト削減のためにも、運用負荷軽減のためにも新しいコンソールを使用する方が良いと感じた件
AWSマネジメントコンソールでWeb ACLを開くたびに実行されるTop Insightsセクションの表示にかかるコストが気になる
こんにちは、のんピ(@non____97)です。
皆さんはAWSマネジメントコンソールでWeb ACLを開くたびに実行されるTop Insightsセクションの表示にかかるコストが気になったことはありますか? 私はあります。
Traffic Overview ダッシュボードに表示されるTop Insights セクションを用いることで、URIパスやクライアントIPなどトラフィックのより詳細な情報を確認することが可能です。こちらはWeb ACLのログをCloudWatch Logsに出力している場合に使用可能です。
こちらのTop Insightsセクションの情報は裏側でCloudWatch Logs Insightsが実行されることによって表示されます。
Top InsightsセクションにはThe top insights section includes richer visualizations based on your CloudWatch logs. Loading this section incurs additional CloudWatch query costs. For more information on these costs, see CloudWatch pricing . For more information on security insights visualizations, see the AWS WAF Developer Guide
という注意書きがあることからCloudWatch Logs Insightsの課金が発生することが分かります。
Top InsightsセクションはTraffice overflowダッシュボードに記載されています。
Traffice overflowダッシュボードはAWSマネジメントコンソールからWeb ACLを開く場合に最初に遷移するページです。つまりはWeb ACLのルールやログの設定を確認したいだけであっても、Top Insightsセクションが読み込まれ、裏側でCloudWatch Logs Insightsが実行されてしまいます。
CloudWatch Logs Insightsはスキャンしたデータ量によって課金が発生します。全てのログを出力する設定 かつ 大量のトラフィックを捌いているWebACLにおいては課金が気になってくるところです。
では、AWS re:Inforce 2025にて発表されたコンソールの場合はどうでしょう。
構成がガラッと変わったのであれば、嬉しいです。
実際に確認してみます。
いきなりまとめ
- AWS re:Inforce 2025にて発表されたコンソールではTop Insightsセクション表示時にコストがかかることがより分かりやすくなった
- 表示する際には確認のポップアップが出るように
- そもそも、ルールやログなど他設定を確認/変更する際に、ダッシュボードを経由しなくともよくなったため、無用にTop Insightsのコストがかかってしまう事態を減らしやすくなった
- 3時間よりも広い期間やルール、終了アクションを変更した場合は明示的にリロードが要求されるように
- 表示する際には確認のポップアップが出るように
- AWS re:Inforce 2025にて発表されたコンソールではログエクスプローラーが使用できる
- GUIで簡単にログの絞り込みができる
- CloudWatch Logsのフィールドインデックスを有効活用しよう
従来のコンソールの場合
初回アクセス
まずは従来のコンソールの場合です。
Web ACLにアクセスするとTraffic overview
タブを開いています。こちらにTop Insightsセクションがあります。
既に過去にオープンしていたため、URIパスなどの情報が表示されていますね。
この時のCloudWatch Logs Insightsの実行履歴を確認すると、AWSマネジメントコンソールからWeb ACLにアクセスしたタイミングでCloud Watch Logs Insightsが実行されています。
これは気になりますね。
期間と終了アクションを変更した上で再度アクセス
期間と終了アクションを変更した上で再度アクセスをします。
デフォルトの期間は3時間で、終了アクションは以下全てのものが選択されています。
- Allowed
- Blocked
- Captcha
- Challenge
Top InsightsセクションのCloudWatch Logs Insightsのクエリは以下記事で紹介しているとおり、終了アクションでフィルタリングをしています。
そのため、CloudWatch Logsロググループのフィールドインデックスで終了アクションaction
に対していインデックスを張ることでスキャン量を減らし、コスト削減をすることです。
つまりは、Blocked
のみなど、一部の終了アクションを選択しておけば裏側で実行されるCloudWatch Logs Insightsのコスト影響を抑えることができそうです。
今回は期間を1日で終了アクションをAllowed
とBlocked
のみにしました。
この状態で別ページに遷移してから再度アクセスをします。
期間と終了アクションが維持できていますね。
裏側ではCloudWatch Logs Insightsの実行が行われていました。
それでは、一度このセッションからサインアウトした後に再度アクセスをします。
すると、デフォルトの期間は3時間で、全ての終了アクションを選択した状態になっていました。
どうやら、こちらのフィルタリングはセッション単位でリセットされてしまうようです。
そのため、期間や終了アクションを絞っておいて、再度アクセスした際のCloudWatch Logs Insightsにかかることを削減する方法は取れなさそうです。
Top Insightsセクションを畳んでから再度アクセス
Top Insightsセクションを畳んでから再度アクセスした場合はどうでしょうか。
Top Insightsセクションを畳んでから再度アクセスします。
この時、CloudWatch Logs Insightsの実行履歴を確認しましたが、何も実行されていないようです。
そのため、CloudWatch Logs Insightsのコストが気になる場合は、Top Insightsセクションを畳んでおけば良さそうです。
一度このセッションからサインアウトしてから再度アクセスをします。
閉じたままですね。
CloudWatch Logs Insightsの実行履歴からも実行されていないことを確認できました。
他、以下アクセスをしましたたがTop Insightsセクションは閉じたままでした
- 一度サインアウトして、ブラウザのキャッシュを削除した上で再度アクセス
- 別のIAMロールにスイッチロールした状態でアクセス
- シークレットブラウザからアクセス
これらのパターンからデフォルトではTop Insightsセクションは閉じた状態のようですね。
CloudWatch Logsにログを出力する = Top Insightsセクションの表示で毎回コストがかかるという訳ではなさそうです。
AWS re:Inforce 2025にて発表されたコンソールの場合
初回アクセス
続いて、AWS re:Inforce 2025にて発表されたコンソールの場合です。
以前はWeb ACL(保護パック)があるリージョンごとにセレクトメニューから選択していましたが、横断して確認できるようになりました。私は好きです。
Top Insightsセクションは各保護パック横のダッシュボードを表示
をクリックした先で確認できます。
Load Top Insights
と、より分かりやすくTop Insightsセクションを表示するのかをユーザーに求めるようになりました。追加料金が適用されます
という文言も黄色でアピールしてくれていますね。
Load Top Insights
をクリックすると、追加コストがかかります
と表示されました。親切設計ですね。
確認
をクリックすると、Top Insightsの各種情報が表示されました。
他パターンでのアクセス
毎回スクリーンショットを貼るのもアレなので、各パターンごとの結果を以下にまとめます。
アクセスパターン | Top Insightsセクションの状態 |
---|---|
リロード | 表示 |
別画面に遷移してから再度アクセス | 表示 |
一度サインアウトしてから再度アクセス | 表示 |
別のIAMロールにスイッチロールしてアクセス | 未表示 |
シークレットブラウザからアクセス | 未表示 |
あるユーザーが調査のために期間を長めに設定した上でTop Insightsセクションを眺めている最中に、別のユーザーがダッシュボードにアクセスしてもLoad Top Insights
をクリックしない限り裏側でCloudWatch Logs Insightsは実行されなさそうですね。
また、期間や終了アクションについては従来のコンソールと同じく、サインアウトをするとリセットされました。そもそも現状ではサインアウトすると毎回従来のコンソールが表示されています。
フィルタリング条件を変更した際に明示的なリロードが要求されるようになった
他、新しいコンソールでは、終了アクション、ルールなどのフィルタリング条件を変更した場合に明示的なリロードを行わなければTop Insightsセクションの情報が更新されないという点も良いと感じました。
従来は終了アクションを変更すると、すぐさまTop Insightsセクションが更新されていました。特に終了アクションは複数同時に選択をしたり、外すことができないため、地味にコストがかかるところです。
具体的には終了アクションに対するフィルタリングを
- Allowed
- Blocked
- Captcha
- Challenge
という状態から
- Captcha
- Challenge
に変更する場合は以下のように2回Top Insightsセクションの読み込みが走ってしまいます。
- Allowed を外すタイミング
- Blocked を外すタイミング
ルールや終了アクションを変更した場合、新しいコンソールでは、Hide Top Insights
横のリロードボタンを押さなければTop Insightsセクションの情報は更新されません。そもそも従来のコンソールではルールでフィルタリングすることができなかったので、非常にありがたいです。
期間については3時間よりも広い期間を選択する場合は明示的なリロードが要求されるようです。
実際に試します。
この状態から期間を12時間、ルールをGeoBlockRule
で設定します。
すると、この状態ではまだTop Insightsセクションの情報は更新されていません。
Hide Top Insights
横のリロードボタンを押すと、追加コストがかかります
とポップアップが表示されます。
処理を続行すると、初めてTop Insightsのロードが始まり、情報が更新されました。
これは嬉しいアップデートです。
ちなみに、このとき裏側で実行されていたCloudWatch Logs Insightsは以下のとおりです。
fields httpRequest.clientIp, action
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| stats count(*) as cnt by httpRequest.clientIp
| sort cnt desc
| limit 100 | limit 100
stats count(*) as cnt by concat(httpSourceName, ' | ', httpSourceId) as combined_field
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| sort cnt desc
| limit 100 | limit 100
fields httpRequest.httpMethod, action
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| stats count(*) as count by httpRequest.httpMethod
| sort count desc
| limit 100 | limit 100
fields httpRequest.uri as uri, action
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| stats count(*) as cnt by uri
| sort cnt desc
| limit 100 | limit 100
fields jsonParse(@message) as json_message , action
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| unnest json_message.labels into labelsvalues
| stats count(*) as cnt by labelsvalues.name
| sort cnt desc
| limit 100 | limit 100
fields @timestamp, @message
| parse @message /\{"name":"(U|u)ser-(A|a)gent","value":"(?<userAgent>.*?)"\}/
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| stats count(*) as requestCount by userAgent
| sort requestCount desc
| limit 100 | limit 100
fields ja4Fingerprint
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| stats count(*) as cnt by ja4Fingerprint
| sort cnt desc
| limit 100 | limit 100
fields ja3Fingerprint
| parse @message '"nonTerminatingMatchingRules":[{"ruleId":"*","action"' as nonTerminatingMatchingRules
| filter strcontains(nonTerminatingMatchingRules, 'GeoBlockRule') or terminatingRuleId == "GeoBlockRule"
| filter action in ['ALLOW','BLOCK','CHALLENGE','CAPTCHA']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| stats count(*) as cnt by ja3Fingerprint
| sort cnt desc
| limit 100 | limit 100
ログエクスプローラーで簡単により詳細なログ分析が行えるようになった
Top Insightsセクションで表示されている値をクリックすると、ログエクスプローラーで表示
と表示されます。
こちらをクリックすると、選択した値に該当するログを抽出してくれます。
複数の条件でフィルタリングも可能です。
これによってGUIで簡単に通信の絞り込みを行うことが可能です。非常に便利ですね。
なお、裏側でしっかりCloudWatch Logs Insightsが実行されています。
先ほどの複数条件でフィルタリングをした時に実行されたクエリは以下のとおりです。
fields timestamp, action, httpRequest.host as host, httpRequest.uri as uri, httpRequest.httpMethod as httpMethod, httpRequest.clientIp as clientIp, httpRequest.country as country, terminatingRuleId, httpSourceName, httpSourceId, concat(httpSourceName, ' | ', httpSourceId) as resourceDetails, ja3Fingerprint, ja4Fingerprint, @message | parse @message '"name":"User-Agent","value":"*"' as userAgent
| filter action in ['BLOCK']
| filter webaclId in ['arn:aws:wafv2:us-east-1:<AWSアカウントID>:global/webacl/website/84a704a7-6965-44af-887e-d196dcd881ac']
| filter timestamp > 1757188173
| filter httpRequest.httpMethod = 'GET'
| filter httpRequest.country = 'US'
| sort timestamp desc
| limit 500 | limit 500
ログエクスプローラーを使用する場合はフィールドインデックスを有効活用してコスト削減をしたいですね。
各設定値の確認場所の整理
コンソールが新しくなるに伴い、各設定値の確認場所が気になります。
ということで、新しいコンソールにおけるWeb ACLの各設定値の確認場所の整理してみました。
項目 | 確認場所 | 備考 |
---|---|---|
Name | リソースと保護パック |
Web ACL(保護パック)の名前 |
Description | リソースと保護パック -<保護パック名> -説明 |
Web ACL(保護パック)の説明 |
Resource type | リソースと保護パック -<保護パック名> -スコープ |
Regional scope でCloudFront (Global) and Regional を選択することで画面遷移なしで全Web ACL(保護パック)の一覧を表示 |
Region | リソースと保護パック -<保護パック名> |
Web ACL(保護パック)があるリージョン |
Associated AWS resources | リソースと保護パック -<保護パック名>内の"リソース"横の表示および編集 -リソースを管理 |
Web ACL(保護パック)と関連付けるリソース |
Body size limit | リソースと保護パック -<保護パック名>内の"リソース"横の表示および編集 -本文サイズの制限 |
リクエストボディを検査する際の検査サイズの上限 |
Rules | リソースと保護パック -<保護パック名>内の"リソース"横の表示および編集 |
Web ACL(保護パック)に設定するルール |
WCUs used by your web ACL | リソースと保護パック -<保護パック名> -キャパシティ |
WCUsの使用量 |
Default action | リソースと保護パック -<保護パック名> -デフォルトアクション |
ルールにマッチしなかった場合の処理 |
CAPTCHA Immunity time | リソースと保護パック -<保護パック名> -デフォルトイミュニティ時間 内のCAPTCHA |
CAPTCHAトークンを使用できる期間 |
Challenge Immunity time | リソースと保護パック -<保護パック名> -デフォルトイミュニティ時間 内のChallenge |
Challengeトークンを使用できる期間 |
Token domain list | リソースと保護パック -<保護パック名> -トークンドメイン |
AWS WAF が受け入れるリクエストを送信しているドメイン |
Custom response bodies | リソースと保護パック -<保護パック名> -カスタムレスポンス本文 |
カスタムレスポンスボディ |
Sampled requests | リソースと保護パック -<保護パック名>内の"ログ記録の設定"横の表示および編集 -サンプルリクエスト |
ルールに一致する Web リクエストのサンプルを保持するか |
Sampled requests for web ACL default actions | リソースと保護パック -<保護パック名>内の"ログ記録の設定"横の表示および編集 -サンプルリクエスト 内の保護パックのデフォルトアクションのサンプルリクエスト |
デフォルトアクションで処理された Web リクエストのサンプルを保持するか除外を含むサンプルリクエストを有効化 でデフォルトアクション の有効化済み を切り替えることで明示的な指定が可能 |
Logging | リソースと保護パック -<保護パック名>内の"ログ記録の設定"横の表示および編集 -ログ記録 内のステータス |
ログの有効化 |
Logging destination | リソースと保護パック -<保護パック名>内の"ログ記録の設定"横の表示および編集 -ログ記録 内のログ記録送信先 |
ログの出力先となるS3バケット/CloudWatch Logs/Data Firehoseを指定 |
Redacted fields | リソースと保護パック -<保護パック名>内の"ログ記録の設定"横の表示および編集 -データ保護設定 内の保護フィールド |
以下から選択可能 - HTTP method - Query string - URI path - 任意のヘッダー |
Default log filter behavior | リソースと保護パック -<保護パック名>内の"ログ記録の設定"横の表示および編集 -データ保護設定 内のデフォルトのログフィルター動作 |
デフォルトのログ出力の挙動 |
新しいコンソールに慣れていこう
AWS WAFのWeb ACL(保護パック)でCloudWatch Logsにログを出力している場合はコスト削減のためにも、運用負荷軽減のためにも新しいコンソールを使用する方が良いということを紹介しました。
個人的にはログエクスプローラーは最高ですね。これからは新しいコンソールを積極的に使っていきます。
この記事が誰かの助けになれば幸いです。
以上、クラウド事業本部 コンサルティング部の のんピ(@non____97)でした!