WordPressのログを解析する~構成編~

今、閲覧頂いているハックノートはWAFのルールなどを用いて不正アクセスの対策を取っています。
そのWAFでブロックしたものを解析してみようと思います。
実際にどのようなアタックがあって、WAFでブロック出来ているかは後日別の記事にします。

今回ブロックを解析するために以下のような構成で行います

最終的に下記のようなログをテキストファイルにすることが出来ます。

+---------------------------------------------------+
terminatingRuleId:block-rule-name
action:BLOCK
clientIp:123.123.123.123
country:JP
headers:{'name': 'user-agent', 'value': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'}
uri:/
httpVersion:HTTP/2.0
httpMethod:GET
+---------------------------------------------------+


+---------------------------------------------------+
terminatingRuleId:block-rule-name
action:BLOCK
clientIp:12.12.12.123
country:JP
headers:{'name': 'user-agent', 'value': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36'}
uri:/
httpVersion:HTTP/2.0
httpMethod:GET
+---------------------------------------------------+

*一部改変しています

必要なAWSサービス

今回行う設定で必要なのは図でも示しましたが、以下の通りです。

  • EC2
  • CloudFront
  • AWS WAF
  • Amazon kinesis
  • CloudWatch
  • Lambda
  • S3

仕組み

EC2 + CloudFrontの構成でWordPressが動いています。
5分に1回の頻度でS3にgzip形式でログを保存しています(Amazon kinesisで設定) CloudFrontにはAWS WAFを適用して怪しいアクセスをブロックするように設定されています。
CloudWatchでAWS WAFでのブロックルールに当てはまったアクセスがきたら、アラート状態にします。
アラート状態になったらLambdaを実行させます。
Lambdaでは次のような処理をしています

  1. S3バケットに保存された最新のアクセスログを取得します
  2. 取得したアクセスログはgzipで圧縮されているので、解凍します
  3. 解凍されたデータは[ ],がないなど、完璧なjson形式ではないので無理やりjson形式にします
  4. jsonデータから必要な情報を抜き出し、ブロックログのみを抽出します。
  5. ブロックログがあればS3に保存し、無ければなにもしません
  6. 5分待ちます(次の見出しで解説)
  7. 4.5をもう一度行います

なぜ5分待つ必要があるのか

このLambda関数はアラートが発生したタイミングでの最新ログの解析を始めます。
それによってどんな不都合があるかというと、ブロックをした時点では ログが保存されていない可能性があります
なので、CloudWatchでアラートになったタイミングと、更に5分待ったタイミングの2回実行します。
ログの保存間隔が5分なので、5分間隔で2回行えばほぼ確実にログを取ることが出来ます。

Lambdaコード

(python勉強中なのでコードの汚さには目をつむってください…)

このコードで抽出でどのルールに引っかかったのか、相手のIP、国、どのURIにアクセスしてきたかなどがわかります。 実際にWAFでどのくらいのブロックが出来ているかは後日の記事をお待ちください!