|
@@ -0,0 +1,219 @@
|
|
|
|
+# Contains cloudtrail configuration for the c2 account only
|
|
|
|
+module "s3_logging_bucket" {
|
|
|
|
+ source = "../../thirdparty/terraform-aws-s3logging-bucket"
|
|
|
|
+
|
|
|
|
+ bucket_name = "xdr-cloudtrail-logs-${var.environment}-access-logs"
|
|
|
|
+ lifecycle_rules = list(
|
|
|
|
+ {
|
|
|
|
+ id = "expire-old-logs"
|
|
|
|
+ enabled = true
|
|
|
|
+ prefix = ""
|
|
|
|
+ expiration = 30
|
|
|
|
+ noncurrent_version_expiration = 30
|
|
|
|
+ abort_incomplete_multipart_upload_days = 7
|
|
|
|
+ })
|
|
|
|
+ tags = merge(var.standard_tags, var.tags)
|
|
|
|
+ versioning_enabled = true
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+module "cloudtrail_logging_bucket" {
|
|
|
|
+ source = "../../thirdparty/terraform-aws-cloudtrail-bucket"
|
|
|
|
+
|
|
|
|
+ allowed_account_ids = var.account_list
|
|
|
|
+ bucket_name = "xdr-cloudtrail-logs-${var.environment}"
|
|
|
|
+ logging_bucket = module.s3_logging_bucket.s3_bucket_name
|
|
|
|
+ region = var.aws_region
|
|
|
|
+ tags = merge(var.standard_tags, var.tags)
|
|
|
|
+ lifecycle_rules = list(
|
|
|
|
+ {
|
|
|
|
+ id = "expire-old-logs"
|
|
|
|
+ enabled = true
|
|
|
|
+ prefix = ""
|
|
|
|
+ expiration = 30
|
|
|
|
+ noncurrent_version_expiration = 30
|
|
|
|
+ abort_incomplete_multipart_upload_days = 7
|
|
|
|
+ })
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+resource "aws_s3_bucket_notification" "on_new_object" {
|
|
|
|
+ bucket = module.cloudtrail_logging_bucket.s3_bucket_name
|
|
|
|
+
|
|
|
|
+ topic {
|
|
|
|
+ topic_arn = aws_sns_topic.new_object_event.arn
|
|
|
|
+
|
|
|
|
+ events = [
|
|
|
|
+ "s3:ObjectCreated:*",
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ # TODO: Can we filter out the digests?
|
|
|
|
+ filter_suffix = ""
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+resource "aws_sns_topic" "new_object_event" {
|
|
|
|
+ name = "s3-notification-topic-${module.cloudtrail_logging_bucket.s3_bucket_name}"
|
|
|
|
+ kms_master_key_id = aws_kms_key.new_object_key.id
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+resource "aws_sns_topic_policy" "this" {
|
|
|
|
+ arn = aws_sns_topic.new_object_event.arn
|
|
|
|
+ policy = data.aws_iam_policy_document.bucket_can_publish.json
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+data "aws_iam_policy_document" "bucket_can_publish" {
|
|
|
|
+ statement {
|
|
|
|
+ actions = [
|
|
|
|
+ "SNS:Publish",
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ effect = "Allow"
|
|
|
|
+
|
|
|
|
+ condition {
|
|
|
|
+ test = "ArnLike"
|
|
|
|
+ variable = "aws:SourceArn"
|
|
|
|
+
|
|
|
|
+ values = [
|
|
|
|
+ module.cloudtrail_logging_bucket.s3_bucket_arn
|
|
|
|
+ ]
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ principals {
|
|
|
|
+ type = "AWS"
|
|
|
|
+ identifiers = ["*"]
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ resources = [
|
|
|
|
+ aws_sns_topic.new_object_event.arn
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ sid = "allowpublish"
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ statement {
|
|
|
|
+ actions = [
|
|
|
|
+ "SNS:Subscribe",
|
|
|
|
+ "SNS:Receive",
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ effect = "Allow"
|
|
|
|
+
|
|
|
|
+ principals {
|
|
|
|
+ type = "AWS"
|
|
|
|
+ identifiers = ["*"]
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ condition {
|
|
|
|
+ test = "ArnEquals"
|
|
|
|
+ values = [ aws_sqs_queue.new_s3_object.arn ]
|
|
|
|
+ variable = "aws:SourceArn"
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ resources = [
|
|
|
|
+ aws_sns_topic.new_object_event.arn
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ sid = "sid_allow_subscribe"
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+# This is the queue for splunk to subscribe to
|
|
|
|
+resource "aws_sqs_queue" "new_s3_object" {
|
|
|
|
+ name = "new-objects-for-${module.cloudtrail_logging_bucket.s3_bucket_name}"
|
|
|
|
+ visibility_timeout_seconds = 300 # wait 5 minutes before allowing a different splunk instance to process the same message
|
|
|
|
+ message_retention_seconds = 604800 # Keep a message in the queue for 7 days
|
|
|
|
+ receive_wait_time_seconds = 0 # how long to wait for a message before returning
|
|
|
|
+ redrive_policy = "{\"deadLetterTargetArn\":\"${aws_sqs_queue.dlq.arn}\",\"maxReceiveCount\":4}"
|
|
|
|
+ tags = merge(var.standard_tags, var.tags)
|
|
|
|
+ kms_master_key_id = aws_kms_key.new_object_key.id
|
|
|
|
+ kms_data_key_reuse_period_seconds = 3600
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+data "aws_iam_policy_document" "sns_topic_can_publish" {
|
|
|
|
+ statement {
|
|
|
|
+ effect = "Allow"
|
|
|
|
+
|
|
|
|
+ principals {
|
|
|
|
+ identifiers = [
|
|
|
|
+ "*",
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ type = "AWS"
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ actions = [
|
|
|
|
+ "SQS:SendMessage",
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ resources = [
|
|
|
|
+ aws_sqs_queue.new_s3_object.arn
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ condition {
|
|
|
|
+ test = "ArnEquals"
|
|
|
|
+
|
|
|
|
+ values = [
|
|
|
|
+ aws_sns_topic.new_object_event.arn
|
|
|
|
+ ]
|
|
|
|
+
|
|
|
|
+ variable = "aws:SourceArn"
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+// Dead Letter queue, use same parameters as main queue
|
|
|
|
+resource "aws_sqs_queue" "dlq" {
|
|
|
|
+ name = "new-objects-for-${module.cloudtrail_logging_bucket.s3_bucket_name}-dlq"
|
|
|
|
+ message_retention_seconds = 300
|
|
|
|
+ receive_wait_time_seconds = 0
|
|
|
|
+ tags = merge(var.standard_tags, var.tags)
|
|
|
|
+ kms_master_key_id = aws_kms_key.new_object_key.id
|
|
|
|
+ kms_data_key_reuse_period_seconds = 3600
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+resource "aws_sqs_queue_policy" "bucket_can_publish" {
|
|
|
|
+ policy = data.aws_iam_policy_document.sns_topic_can_publish.json
|
|
|
|
+ queue_url = aws_sqs_queue.new_s3_object.id
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+resource "aws_sns_topic_subscription" "bucket_change_notification_to_queue" {
|
|
|
|
+ topic_arn = aws_sns_topic.new_object_event.arn
|
|
|
|
+ protocol = "sqs"
|
|
|
|
+ endpoint = aws_sqs_queue.new_s3_object.arn
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+resource "aws_kms_key" "new_object_key" {
|
|
|
|
+ description = "Encryption of SNS and SQS queues on new S3 objects"
|
|
|
|
+ policy = data.aws_iam_policy_document.new_object_key_kms_policy.json
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+data "aws_iam_policy_document" "new_object_key_kms_policy" {
|
|
|
|
+ statement {
|
|
|
|
+ effect = "Allow"
|
|
|
|
+ principals {
|
|
|
|
+ identifiers = ["s3.amazonaws.com", "sns.amazonaws.com", "sqs.amazonaws.com"]
|
|
|
|
+ type = "Service"
|
|
|
|
+ }
|
|
|
|
+ actions = [
|
|
|
|
+ "kms:GenerateDataKey",
|
|
|
|
+ "kms:Decrypt"
|
|
|
|
+ ]
|
|
|
|
+ resources = [ "*" ]
|
|
|
|
+ }
|
|
|
|
+ # allow account to modify/manage key
|
|
|
|
+ statement {
|
|
|
|
+ effect = "Allow"
|
|
|
|
+ principals {
|
|
|
|
+ identifiers = ["arn:${var.aws_partition}:iam::${var.aws_account_id}:root"]
|
|
|
|
+ type = "AWS"
|
|
|
|
+ }
|
|
|
|
+ actions = [
|
|
|
|
+ "kms:*"
|
|
|
|
+ ]
|
|
|
|
+ resources = ["*"]
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+resource "aws_kms_alias" "new_object_key_alias" {
|
|
|
|
+ name = "alias/new_object_key"
|
|
|
|
+ target_key_id = aws_kms_key.new_object_key.key_id
|
|
|
|
+}
|