AWS WAFのログがAmazon S3バケットに保存されない場合、確認すべき項目3点

2023.08.16

はじめに

AWS WAFは、セキュリティ、可用性、パフォーマンスの脅威となる様々な脆弱性や危険から Web サイトやアプリケーションを守るためのサービスです。

WAFのログ保存機能を利用すれば、攻撃の分析などが可能です。

私の場合、以下の図のように、WAFのログをS3バケットに保存する設定を行いましたが、ログが保存されないことがあったため、確認するポイントを3つ説明します。

今回は、東京リージョンのApplication Load Balancer(ALB)にWAFを適用し、ログをS3バケットに保存するケースです。

1. AWS KMS カスタマーマネージドキー

S3バケットのサーバー側の暗号化に、Amazon S3 マネージドキーを利用する場合(SSE-S3)、特に設定は不要です。

ただし、AWS KMSのカスタマーマネージドキーを利用する場合(SSE-KMS)、WAFにカスタマーマネージドキーを使用する許可を与える必要があります。

カスタマーマネージドキーのキーポリシーを編集し、下記のポリシーを追加します。

{
    "Sid": "Allow AWS WAF to use the key",
    "Effect": "Allow",
    "Principal": {
        "Service": [
            "delivery.logs.amazonaws.com"
        ]
    },
    "Action": "kms:GenerateDataKey*",
    "Resource": "*"
}

私の場合、この設定ができておらず、ログ保存ができませんでした。

2. S3バケットポリシー

S3バケットにWAFのログを保存するためには、S3のバケットポリシーでログを保存する許可設定が必要です。

WAFの設定でログ保存先のS3バケットを指定すると、自動的にS3バケットポリシーが設定されますが、設定されていない場合、以下をバケットポリシーに追加しましょう。

下記は、ALBなどのリージョンサービスにWAFを適用している場合です

リージョンサービス

{
    "Version": "2012-10-17",
    "Id": "AWSLogDeliveryWrite20150319",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::aws-waf-logs-example-bucket/AWSLogs/アカウントID/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "aws:SourceAccount": ["アカウントID"]
                },
                "ArnLike": {
                    "aws:SourceArn": ["arn:aws:logs:ap-northeast-1:アカウントID:*"]
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::aws-waf-logs-example-bucket",
            "Condition": {
                "StringEquals": {
                "aws:SourceAccount": ["アカウントID"]
                },
                "ArnLike": {
                "aws:SourceArn": ["arn:aws:logs:ap-northeast-1:アカウントID:*"]
                }
            }
        }
    ]
}

下記は、CloudFrontのグローバルサービスにWAFを適用している場合です。

aws:SourceArnが、東京リージョンからバージニアリージョンに変わっただけです。

グローバルサービス

{
    "Version": "2012-10-17",
    "Id": "AWSLogDeliveryWrite20150319",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::aws-waf-logs-example-bucket/AWSLogs/アカウントID/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "aws:SourceAccount": ["アカウントID"]
                },
                "ArnLike": {
                    "aws:SourceArn": ["arn:aws:logs:us-east-1:アカウントID:*"]
                }
            }
        },
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::aws-waf-logs-example-bucket",
            "Condition": {
                "StringEquals": {
                "aws:SourceAccount": ["アカウントID"]
                },
                "ArnLike": {
                    "aws:SourceArn": ["arn:aws:logs:us-east-1:アカウントID:*"]
                }
            }
        }
    ]
}

下記は、CloudFrontのグローバルサービスにWAFやリージョンサービスのALBのWAFを同じS3バケット名にログ保存設定した場合のポリシーです

aws:SourceArnが、東京リージョンとバージニアリージョンの2つに追加されます。

リージョンサービスとグローバルサービス

{
    "Version": "2012-10-17",
    "Id": "AWSLogDeliveryWrite20150319",
    "Statement": [
        {
            "Sid": "AWSLogDeliveryWrite",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::aws-waf-logs-example-bucket/AWSLogs/アカウントID/*",
            "Condition": {
                "StringEquals": {
                    "s3:x-amz-acl": "bucket-owner-full-control",
                    "aws:SourceAccount": ["アカウントID"]
                },
                "ArnLike": {
                    "aws:SourceArn": [
                        "arn:aws:logs:ap-northeast-1:アカウントID:*",
                        "arn:aws:logs:us-east-1:アカウントID:*"
                    ]                }
            }
        },
        {
            "Sid": "AWSLogDeliveryAclCheck",
            "Effect": "Allow",
            "Principal": {
                "Service": "delivery.logs.amazonaws.com"
            },
            "Action": "s3:GetBucketAcl",
            "Resource": "arn:aws:s3:::aws-waf-logs-example-bucket",
            "Condition": {
                "StringEquals": {
                "aws:SourceAccount": ["アカウントID"]
                },
                "ArnLike": {
                    "aws:SourceArn": [
                        "arn:aws:logs:ap-northeast-1:アカウントID:*",
                        "arn:aws:logs:us-east-1:アカウントID:*"
                    ]                }
            }
        }
    ]
}

ログ保存先のS3バケットに、上記のバケットポリシーが適用されているか確認しましょう。

3. S3バケット名

WAFのログ保存先として、S3バケットを指定する場合、S3のバケット名は、aws-waf-logs-で始まる必要があります。

そのため、WAFのログ保存先であるS3バケット名がaws-waf-logs-で始まるバケット名か確認しましょう。

ご参考になれば幸いです。

参考