話題の記事

[アップデート] AWS WAFのログを直接CloudWatch LogsおよびS3に出力可能になりました

AWS WAFのログ出力設定がめっちゃシンプルになりました
2021.11.16

またまたドキュメントをながめていたところ、待望のアップデートを見つけたのでシェアします。

AWS WAFのWebACLトラフィックログをCloudwatch LogsまたはS3に直接出力することが可能になりました!

AWS WAFのWebACLトラフィックログ

従来は以下記事のようにKinesis Data Firehoseを介してCloudWatch LogsまたはS3に出力する必要がありました。

今回のアップデートでAWS WAFから直接CloudWatch Logs、S3に出力可能となりましたので控えめに言って最高のアップデートですね!

注意点

  • CloudWatch Logsロググループ名およびS3バケット名はaws-waf-logs-から始まる名前であること
    • Kinesis Data Firehoseも配信ストリーム名でも同じ制約がありましたが、CloudWatch Logs、S3でも適用されるようです
  • CloudWatch Logs
    • WebACLと同じリージョン、同じアカウントに作成すること
    • CloudFront用のWebACLはバージニアリージョンにロググループを作成します
  • S3バケット
    • 異なるリージョンのバケットにも出力可能
    • WebACLと異なるアカウントに出力可能(バケットポリシー、ACLを要設定)
    • AWS WAFはSSE-S3またはSSE-KMSによる暗号化をサポートします。ただし、AWS管理キーはサポートされません

やってみる

今回は検証用に作成したCloudFront用WebACLに対してログ設定します。

以下のリソースは事前に作成済みです。

  • CloudWatch Logs ロググループ(バージニア)
  • S3 バケット(バージニアおよび東京)

WebACLのログ設定(CloudWatch Logs)

AWS WAFコンソールから対象となるWeb ACLの管理画面を開きます。Logging and metricsタブから、LoggingEnableまたはEditをクリックします。

Logging destinationの選択項目にCloudWatch Logs log groupS3 bucketが追加されていますね!

まずはCloudWatch Logs log groupを設定します。プルダウンメニューにはaws-waf-logs-で始まるロググループ名のみ表示されますので選択してSaveします。

適当に対象のCloudFrontディストーションに対してリクエストを送った後、設定したCloudWatch Logs ロググループを開くと、ログが出力されていることが確認できました。簡単ですね!

CloudWatch Logsの場合、Web ACLの画面からCloudWatch Log Insightsが実行できます。

WebACLのログ分析で必要そうなクエリがあらかじめセットされているのも嬉しいですね。

WebACLのログ設定(S3)

次に、ログ設定をS3 bucketに変更してSaveします。

今回はWebACLとバケット所有者が同じアカウントでしたので、Webコンソールの操作だけで必要なバケットポリシーやACL設定は自動的に行われていますが、異なるアカウントの場合はS3側に適切な権限設定が必要となりますのでご注意ください。

ログは以下の階層に出力されます。

AWSLogs/account-id/WAFLogs/Region/web-acl-name/YYYY/MM/dd/HH/mm/account-id_waflogs_Region_web-acl-name_timestamp_hash.log.gz

適当に対象のCloudFrontディストーションに対してリクエストを送った後、設定したS3バケットを確認するとログが出力されていることが確認できました。

ログ出力例

{
	"timestamp": 1637032217785,
	"formatVersion": 1,
	"webaclId": "arn:aws:wafv2:us-east-1:xxxxxxxxxxx:global/webacl/test-webacl/95412dd7-c4b3-41a8-a17b-4d414e6c7d25",
	"terminatingRuleId": "Default_Action",
	"terminatingRuleType": "REGULAR",
	"action": "ALLOW",
	"terminatingRuleMatchDetails": [],
	"httpSourceName": "CF",
	"httpSourceId": "E1Mxxxxxxxxx",
	"ruleGroupList": [],
	"rateBasedRuleList": [],
	"nonTerminatingMatchingRules": [],
	"requestHeadersInserted": null,
	"responseCodeSent": null,
	"httpRequest": {
		"clientIp": "58.xx.1xx.xx",
		"country": "JP",
		"headers": [
			{
				"name": "host",
				"value": "cf1.marumo.classmethod.info"
			},
			{
				"name": "pragma",
				"value": "no-cache"
			},
			{
				"name": "cache-control",
				"value": "no-cache"
			},
			{
				"name": "user-agent",
				"value": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36"
			},
			{
				"name": "accept",
				"value": "image/avif,image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8"
			},
			{
				"name": "sec-gpc",
				"value": "1"
			},
			{
				"name": "sec-fetch-site",
				"value": "same-origin"
			},
			{
				"name": "sec-fetch-mode",
				"value": "no-cors"
			},
			{
				"name": "sec-fetch-dest",
				"value": "image"
			},
			{
				"name": "referer",
				"value": "https://cf1.marumo.classmethod.info/index.html"
			},
			{
				"name": "accept-encoding",
				"value": "gzip, deflate, br"
			},
			{
				"name": "accept-language",
				"value": "ja,en-US;q=0.9,en;q=0.8"
			}
		],
		"uri": "/favicon.ico",
		"args": "",
		"httpVersion": "HTTP/2.0",
		"httpMethod": "GET",
		"requestId": "ot0Q9DmAOLVOiLMUivghmNbb4AvzT0kApHUB_-CruDkjAL1G3Nwm_Q=="
	}
}

確認は以上です!

まとめ

  • これまでログ出力にはKinesis Data Firehoseが必須でしたが、直接CloudWatch LogsまたはS3に出力可能になりました
  • 出力先の命名規則はaws-waf-logs-から始まる必要があります
  • CloudWatch LogsはWebACLと同じリージョン、同じアカウントに出力可能(CloudFront用はバージニアリージョン)
  • CloudWatch Logsの利用時はCloudWatch Log InsightsもWebACLの管理画面から利用可能
  • S3はWebACLと異なるリージョン、異なるアカウントに出力可能

参考