アトラスのAWS WAF通知 〜その後〜

こんにちは、L小川です。約半年ぶりの登場です。
前回ブログ「アトラスのAWS WAF通知―アップデートの変遷」では、AWS WAF通知の仕組みについてご紹介しました。今回はその続編です。

前回ブログのおさらい

AWS WAFv2の機能アップデートでWAFのログをCloudWatchLogsに出力できるようになったため、通知フローを以下のように変更しました。

  • WAF検知後、CloudWatchLogsにログが出力される
  • ログ出力をトリガにLambdaが起動し、Slack通知とGoogleスプレッドシート(以下スプレッドシート)への書き込みを行う

前回ブログでのWAF通知フロー

問題発生

上記のフローでしばらく運用していたのですが、問題が発生しました。
連続した攻撃アクセスがあった場合、出力されたログの数だけLambdaが起動し、スプレッドシートに書き出すことになります。
前回ブログでのLambdaの処理ではスプレッドシートに書き出す際の排他制御が無いため、それぞれのLambdaが同じ行に出力しようとして、スプレッドシートがは歯抜けのような状態になってしまいました。

歯抜けになったスプレッドシート

せっかくスプレッドシートに自動記入できる仕組みを構築したのに、なんとも残念な結果になりました。

解決策

スプレッドシートに一行ずつ「行の挿入・値の記入」ができるように、SQSを使ってLambdaを直列実行することにしました。
通知フローは下図のようになります。

変更後の通知フロー

CloudWatchLogsのログメッセージをSQSに送信するLambdaを新たに作成しました。
また、通知・書き出し用Lambdaの設定で「予約された同時実行」の数を1にして、Lambdaが一件ずつ実行されるようにしました。

Lambdaの同時実行数

複数サービスの場合は以下のようなフローになります。

複数サービスでの通知フロー

各サービスのWAFのログをSQS送信用Lambdaで受け取り、各サービスに対応するSQSへメッセージを送信します。
各SQSから通知・書き出し用Lambdaを実行し、Slack通知・スプレッドシートへの書き出しを行います。

上図フローの概要は以下のとおりです。

  1. 各サービスのWAFのCログがCloudWatcLogsに出力される
  2. CloudWatchLogsのサブスクリプションフィルターに設定したSQS送信用Lambdaが起動する
  3. SQS送信用Lambdaで 各サービス用のSQSへログの内容を送信する
  4. SQSから通知・書き出し用Lambdaを起動する
  5. Slack通知・スプレッドシートへの書き出し

この仕組みにしてからも連続した攻撃アクセスをWAFで検知していますが、歯抜けになることなくスプレッドシートへ記入できています。

おわりに

実際に運用してみて気づいた考慮漏れではありましたが、AWSのサービスを利用して最小限の変更でカイゼンできました!
今回のブログがどなたかのAWS WAFの構築・運用のヒントになれば幸いです。

それでは、またお会いしましょう!