ZAICOでは、Android・iOS・Rubyエンジニアを絶賛募集中です! 詳しくは、採用ページをご覧ください。
わふわふぅ〜。こんにちは、ZAICO開発チームインフラ担当の大内です。
SaaSなどのWebサービスを提供している場合、WAF(Web Application Firewall)を導入して不正アクセスや悪意ある攻撃を検知・遮断してWebアプリケーションを守るということは一般的にやられていることかと思います。
WAF導入後の運用についてはどうでしょうか?
WAFも万能ではなく、正常なアクセスを誤ってBlockすることもあるかと思います。
そういう場合は通知などで気づく必要がありますよね。
今回はそれに対応した仕組みを実装したのでご紹介したいと思います。
WAF導入の概要
WAFを導入してやりたいことは以下のことでした。
- 不正アクセスや悪意ある攻撃は検知・遮断(遮断した通知はいらない)
- 正常なアクセスを誤って遮断した場合には通知
従来の通知の仕組み(後述)では上記2つとも実現は出来ていませんでした。
それらを解消したく新しく通知の仕組みを実装しました。
通知の仕組みの概要
WAF導入後の通知の仕組みとして、CloudWatchのメトリクスを使い、短期間でのBlock数が一定以上だったらSlackに通知するという仕組みは実装してあり、通知が来るたびにWAFのログを調査していましたが、それにはデメリットもありそのデメリットを解消すべく新しく実装し直しました。
概要図
従来の仕組み概要
- WAFのログ(Allow/Block/Count)をCloudWatchLogsに蓄積
- CloudWatchでWAFのメトリクスを使い、短期間でのBlock数が一定以上だったらSNS+Chatbot経由でSlackに通知
従来の仕組みを実装していた背景
WAF導入後に誤検知の通知を工数を掛けずに実装したいと考えていたため、従来の仕組みで実装していました。
従来の仕組みのデメリット
工数を掛けずに実装し運用した結果、以下のデメリットが発生しました。
- CloudWatchLogsの料金が高い
- 悪意ある攻撃をBlockした通知は来る(これはいらない(ノイズ))
- 誤ってBlockした正常なアクセス数が少ないと通知が来ない(こっちがほしい)
- Blockしたログの調査に運用コストが掛かる
新しい通知の仕組み
新しい通知の仕組み概要
- WAFのログをKinesis Data Streamに流す
- Kinesis Data StreamからS3に流す前にLambdaを使ってレコードの変換/転換
従来の仕組みのデメリットを解消すべく、Kinesis Data Stream+Lambda+S3で新たに作りました。
肝になるのはLambdaです。このLambdaが全てと言っても過言ではないです。
Lambdaでやっていること
簡単に言うと、Kinesisから渡されたアクセスログを見て、Blockしたアクセスをいくつもの条件によって不正なアクセスかどうかを判定し、Slackに通知する/しないを判断しています。
Lambdaのコードはクラスメソッドさんの記事にあるコードをベースにさせてもらっています。
以下が条件判定の例です。
- ヘッダーのhostが弊社サービスのドメインかどうか(弊社サービスのドメインでなければ不正アクセスと判定)
- BlockしたアクセスのRuleIdがNoUserAgent_HEADERやUserAgent_BadBots_HEADERなどだったら不正アクセスと判定
- URIが弊社サービスにないURIだったら通知除外対象と判定
新しい通知の仕組みのメリット
- CloudWatchLogsに直接保存しなくなったので、コストが下がった
- 通知のノイズが減った
- 今までわからなかった正常なアクセスを誤ってBlockしていた場合でも気付けるようになった
- WAFのログ調査の手間が減った
新しい通知の仕組みを実装しての所感
Lambdaの実装に手こずりましたが、ノイズとログ調査に対応する運用コストが減り、今まで誤ってBlockしていた可能性のある正常なアクセスにも気づくことができるようになったので、これは実装して良かったと感じています。
ビバ、WAF!
その他
新たしい仕組みにしてからログ解析も手を加えていますが、それはまた別の機会に紹介できたらと思います。
ではでは。