1
2

More than 1 year has passed since last update.

WAFのログ有効化&ロギングフィルターで必要なログのみS3へ直接保存(Terraform)

Last updated at Posted at 2022-01-24

前書き

  • Cloud Watchなどにも直接いけます。
  • Kinesis Data Firehose??いやいやワイは直接S3にログをぶちこみたいんや!!ってお方向け。
  • WebACLのリソースは作成済みのテイで進めます。

やり方

◾️ おおまかな流れ

  1. ログ保管用バケットつくる
  2. ロギング構成用リソースを定義
  3. ロギングとバケットを紐付け
  4. ロギングフィルターを定義

◾️ 実・践

適当なバケットを作りましょう。

(※バケットポリシーはWAFのロギング時に自動でアタッチされるっぽいのでこちら用意しなくても良いっぽいです。細かい挙動はちょっとよくワカラナイ。。)

注意点として、bucket名は aws-waf-logs-のprefixで始まる必要があるらしいです。

https://docs.aws.amazon.com/ja_jp/waf/latest/developerguide/logging-s3.html

s3.tf

resource "aws_s3_bucket" "b" {
  bucket = "aws-waf-logs-hogehoge"
  acl    = "private"

  tags = {
    Name        = "My bucket"
    Environment = "Dev"
  }
}

次にロギング構成用のリソースを定義します。

waf.tf

resource "aws_wafv2_web_acl_logging_configuration" "example" {
  log_destination_configs = [aws_s3_bucket.b.arn]
  resource_arn            = aws_wafv2_web_acl.example.arn // ここは作成済みのweb aclリソースを指定するのじゃ
}

リソースタイプながいっすね笑

これでひとまず、WebACLで定義したルールにマッチしたリクエストのログが流れていくと思います。

次にロギングフィルターです。

ロギングフィルターではどのアクセスのログを取るか捨てるかを精査できます。

ちなみにロギングに関してはWAFの追加コストはかからないらしいので、S3の保存料金が上乗せされていく感じみたいです。まあでも少しでもコスト削減できますし、不要なログが増えるの邪魔なんでフィルターしたらいいんじゃないかなと思います。

https://aws.amazon.com/jp/about-aws/whats-new/2021/12/awf-waf-cloudwatch-log-s3-bucket/

先ほどのwaf.tfに追記しましょう。

resource "aws_wafv2_web_acl_logging_configuration" "example" {
  log_destination_configs = [aws_s3_bucket.b.arn]
  resource_arn            = aws_wafv2_web_acl.example.arn

    // 追加
    logging_filter {
    default_behavior = "KEEP"

    filter {
      behavior = "DROP"
      condition {
        action_condition {
          action = "ALLOW"
        }
      }
      requirement = "MEETS_ANY"
    }
  }
}

logging_filterブロックで、ログのフィルターを定義しています。
filterがログに適用するフィルター、conditionが条件です。
conditionで指定した条件にマッチしたものがbehaviorで定義されているDROPの挙動になります。(DROPなので、つまりログを保存しないという記述になります。)
また、action_conditionでactionをALLOWとしているので、WebACLで定義したルールのactionがallowのものが捨てられる対象となります。(例えばip制限のルール定義などを行なった場合などはallowを使ったりすると思いますが、その場合許可されたipからのリクエストのログを切り捨てるということになります。)
ちなみに、default_behaviorでデフォルトの挙動(KEEPなのでログを送信する)を定義しています。
あとはrequirementなのですが、これは「または」や「かつ」のような使い方に似ています。
正確には、requirementがMEETS_ALLの場合は全てのconditionに一致した場合のみフィルターが発動します。逆にMEETS_ANYの場合はどれか一つのconditionに一致すれば発動します。
なので、もうお分かりかと思いますが、conditionは一つのfilter内に複数書くことができます。

例)

resource "aws_wafv2_web_acl_logging_configuration" "example" {
  log_destination_configs = [aws_s3_bucket.b.arn]
  resource_arn            = aws_wafv2_web_acl.example.arn

  logging_filter {
    default_behavior = "KEEP"

    filter {
      behavior = "DROP"
      condition {
        action_condition {
          action = "ALLOW"
        }
      }
      // 追加
      condition {
        label_name_condition {
          label_name = "awswaf:111122223333:rulegroup:testRules:LabelNameZ" // ルールのラベルで条件を指定することもできる
        }
      }
      requirement = "MEETS_ANY"
    }
  }
}

他にも様々な組み立て方でロギングフィルターのパターンが作れるのでぜひ試してみてください。

少し中途半端ですが今回は以上です!(眠くなったので!笑)

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2