Use the Conformity Knowledge Base AI to help improve your Cloud Posture

CloudTrail S3 Bucket

Trend Cloud One™ – Conformity is a continuous assurance tool that provides peace of mind for your cloud infrastructure, delivering over 1000 automated best practice checks.

Risk Level: Medium (should be achieved)
Rule ID: CT-014

Ensure that your Amazon CloudTrail trail is configured to use the appropriate S3 bucket in order to meet regulatory compliance requirements within your organization. Before running this rule by the Conformity engine, the designated (target) S3 bucket must be configured in the rule settings, on your Trend Cloud One™ – Conformity account console.

This rule can help you with the following compliance standards:

  • NIST4

For further details on compliance standards supported by Conformity, see here.

This rule resolution is part of the Conformity Security & Compliance tool for AWS.

Security
Sustainability

The delivery of Amazon CloudTrail log data must be tightly controlled using the S3 bucket defined specifically as the target bucket for CloudTrail trail logging data.


Audit

To determine if your Amazon CloudTrail trails are using the designated S3 buckets, perform the following actions:

Using AWS Console

01 Sign in to your Trend Cloud One™ – Conformity account, access CloudTrail Trail Bucket Name rule settings and identify the name of the S3 bucket designated to receive and store Amazon CloudTrail data (also known as target bucket).

02 Sign in to the AWS Management Console.

03 Navigate to Amazon CloudTrail console at https://console.aws.amazon.com/cloudtrail/.

04 In the navigation panel, under CloudTrail, choose Trails.

05 Click on the name (link) of the Amazon CloudTrail trail that you want to examine.

06 In the General details section, choose Edit and identify the name of the target S3 bucket, available in the Trail log bucket name box. If the name of the target (associated) S3 bucket does not match the name of the bucket identified at step no. 1, the selected Amazon CloudTrail trail does not use the designated S3 bucket as target bucket, therefore the trail configuration is not compliant.

07 Repeat steps no. 5 and 6 for each Amazon CloudTrail trail available in your AWS cloud account.

Using AWS CLI

01 Sign in to your Trend Cloud One™ – Conformity account, access CloudTrail Trail Bucket Name rule settings and identify the name of the S3 bucket designated to receive and store Amazon CloudTrail data.

02 Run list-trails command (OSX/Linux/UNIX) with custom query filters to list the names of all the Amazon CloudTrail trails created for your AWS cloud account:

aws cloudtrail list-trails
  --region us-east-1
  --query 'Trails[*].Name'

03 The command output should return an array with the requested CloudTrail trail names:

[
    "cc-main-cloud-trail",
    "cc-project5-api-trail",
    "cc-data-events-trail"
]

04 Run describe-trails command (OSX/Linux/UNIX) using the name of the Amazon CloudTrail trail that you want to examine as the identifier parameter and custom query filters to describe the name of the S3 bucket configured to store logs for the selected trail (i.e. target bucket):

aws cloudtrail describe-trails
  --region us-east-1
  --trail-name-list cc-main-cloud-trail
  --query 'trailList[*].S3BucketName'

05 The command output should return the name of the associated bucket:

[
    "cc-main-cloudtrail-logs"
]

Check the name of the target S3 bucket returned by the describe-trails command output. If the name of the target bucket does not match the name of the S3 bucket identified at step no. 1, the selected Amazon CloudTrail trail does not use the designated S3 bucket as target bucket, hence the trail configuration is not compliant.

06 Repeat steps no. 4 and 5 for each Amazon CloudTrail trail created within your AWS cloud account.

Remediation / Resolution

To reconfigure your Amazon CloudTrail trail in order to use the designated S3 bucket as a target bucket, perform the following actions:

Case A: If the S3 bucket already exists:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Use the designated S3 bucket as a target bucket",
    "Parameters": {
        "TrailName": {
            "Type": "String"
        },
        "DesignatedBucketName": {
            "Type": "String"
        },
        "S3BucketKeyPrefix": {
            "Type": "String"
        }
    },
    "Resources": {
        "Trail": {
            "Type": "AWS::CloudTrail::Trail",
            "Properties": {
                "TrailName": {
                    "Ref": "TrailName"
                },
                "S3BucketName": {
                    "Ref": "DesignatedBucketName"
                },
                "S3KeyPrefix": {
                    "Ref": "S3BucketKeyPrefix"
                },
                "IsLogging": true
            }
        }
    }
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
Description: Use the designated S3 bucket as a target bucket
Parameters:
  TrailName:
    Type: String
  DesignatedBucketName:
    Type: String
  S3BucketKeyPrefix:
    Type: String
Resources:
  Trail:
    Type: AWS::CloudTrail::Trail
    Properties:
      TrailName: !Ref 'TrailName'
      S3BucketName: !Ref 'DesignatedBucketName'
      S3KeyPrefix: !Ref 'S3BucketKeyPrefix'
      IsLogging: true

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  profile = "default"
  region  = "us-east-1"
}

data "aws_caller_identity" "current-account" {}

resource "aws_s3_bucket" "designated-s3-bucket" {

  bucket        = "cc-main-cloudtrail-bucket"
  force_destroy = true
  policy = <<POLICY
  {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "AWSCloudTrailAclCheck",
              "Effect": "Allow",
              "Principal": {
                "Service": "cloudtrail.amazonaws.com"
              },
              "Action": "s3:GetBucketAcl",
              "Resource": "arn:aws:s3:::cc-main-cloudtrail-bucket"
          },
          {
              "Sid": "AWSCloudTrailWrite",
              "Effect": "Allow",
              "Principal": {
                "Service": "cloudtrail.amazonaws.com"
              },
              "Action": "s3:PutObject",
              "Resource": "arn:aws:s3:::cc-main-cloudtrail-bucket/cc-trail-logs/AWSLogs/${data.aws_caller_identity.current-account.account_id}/*",
              "Condition": {
                  "StringEquals": {
                      "s3:x-amz-acl": "bucket-owner-full-control"
                  }
              }
          }
      ]
  }
  POLICY

}

resource "aws_cloudtrail" "cloudtrail-trail" {

  name                          = "cc-main-cloud-trail"

  # Use the designated S3 bucket as a target bucket
  s3_bucket_name                = aws_s3_bucket.designated-s3-bucket.id
  s3_key_prefix                 = "cc-trail-logs"
  enable_logging                = true

}

Case B: If the target S3 bucket does not exist:

Using AWS CloudFormation

01 CloudFormation template (JSON):

{
    "AWSTemplateFormatVersion": "2010-09-09",
    "Description": "Use a new S3 bucket as a target bucket",
    "Parameters": {
        "TrailName": {
            "Type": "String"
        }
    },
    "Resources": {
      "TargetS3Bucket": {
            "Type": "AWS::S3::Bucket",
            "Properties": {
                "BucketName": "cc-main-cloudtrail-bucket",
                "AccessControl": "Private",
                "PublicAccessBlockConfiguration": {
                "BlockPublicAcls": true,
                "IgnorePublicAcls": true,
                "BlockPublicPolicy": true,
                "RestrictPublicBuckets": true
              }
            }
        },
        "TargetS3BucketPolicy": {
            "Type": "AWS::S3::BucketPolicy",
            "Properties": {
                "Bucket": "cc-main-cloudtrail-bucket",
                "PolicyDocument": {
                   "Version": "2012-10-17",
                   "Statement": [
                      {
                          "Sid": "CloudTrailAclCheck",
                          "Effect": "Allow",
                          "Principal": {
                            "Service": "cloudtrail.amazonaws.com"
                          },
                          "Action": "s3:GetBucketAcl",
                          "Resource": "arn:aws:s3:::cc-main-cloudtrail-bucket"
                      },
                      {
                          "Sid": "AWSCloudTrailWrite",
                          "Effect": "Allow",
                          "Principal": {
                            "Service": "cloudtrail.amazonaws.com"
                          },
                          "Action": "s3:PutObject",
                          "Resource": "arn:aws:s3:::cc-main-cloudtrail-bucket/cc-trail-logs/AWSLogs/466594415815/*",
                          "Condition": {
                              "StringEquals": {
                                  "s3:x-amz-acl": "bucket-owner-full-control"
                              }
                          }
                      }
                   ]
                }
            }
        },
        "Trail": {
            "Type": "AWS::CloudTrail::Trail",
            "Properties": {
                "TrailName": {
                    "Ref": "TrailName"
                },
                "S3BucketName": "cc-main-cloudtrail-bucket",
                "S3KeyPrefix": "cc-trail-logs",
                "IsLogging": true
            }
        }
    }
}

02 CloudFormation template (YAML):

AWSTemplateFormatVersion: '2010-09-09'
Description: Use a new S3 bucket as a target bucket
Parameters:
  TrailName:
    Type: String
Resources:
  TargetS3Bucket:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: cc-main-cloudtrail-bucket
      AccessControl: Private
      PublicAccessBlockConfiguration:
        BlockPublicAcls: true
        IgnorePublicAcls: true
        BlockPublicPolicy: true
        RestrictPublicBuckets: true
  TargetS3BucketPolicy:
    Type: AWS::S3::BucketPolicy
    Properties:
      Bucket: cc-main-cloudtrail-bucket
      PolicyDocument:
        Version: '2012-10-17'
        Statement:
          - Sid: CloudTrailAclCheck
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:GetBucketAcl
            Resource: arn:aws:s3:::cc-main-cloudtrail-bucket
          - Sid: AWSCloudTrailWrite
            Effect: Allow
            Principal:
              Service: cloudtrail.amazonaws.com
            Action: s3:PutObject
            Resource: arn:aws:s3:::cc-main-cloudtrail-bucket/cc-trail-logs/AWSLogs/466594415815/*
            Condition:
              StringEquals:
                s3:x-amz-acl: bucket-owner-full-control
  Trail:
    Type: AWS::CloudTrail::Trail
    Properties:
      TrailName: !Ref 'TrailName'

Using Terraform (AWS Provider)

01 Terraform configuration file (.tf):

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 3.27"
    }
  }

  required_version = ">= 0.14.9"
}

provider "aws" {
  profile = "default"
  region  = "us-east-1"
}

data "aws_caller_identity" "current-account" {}

resource "aws_s3_bucket" "new-s3-bucket" {

  bucket        = "cc-main-cloudtrail-bucket"
  force_destroy = true
  policy = <<POLICY
  {
      "Version": "2012-10-17",
      "Statement": [
          {
              "Sid": "AWSCloudTrailAclCheck",
              "Effect": "Allow",
              "Principal": {
                "Service": "cloudtrail.amazonaws.com"
              },
              "Action": "s3:GetBucketAcl",
              "Resource": "arn:aws:s3:::cc-main-cloudtrail-bucket"
          },
          {
              "Sid": "AWSCloudTrailWrite",
              "Effect": "Allow",
              "Principal": {
                "Service": "cloudtrail.amazonaws.com"
              },
              "Action": "s3:PutObject",
              "Resource": "arn:aws:s3:::cc-main-cloudtrail-bucket/cc-trail-logs/AWSLogs/${data.aws_caller_identity.current-account.account_id}/*",
              "Condition": {
                  "StringEquals": {
                      "s3:x-amz-acl": "bucket-owner-full-control"
                  }
              }
          }
      ]
  }
  POLICY

}

resource "aws_cloudtrail" "cloudtrail-trail" {

  name                          = "cc-main-cloud-trail"

  # Use the new S3 bucket as a target bucket
  s3_bucket_name                = aws_s3_bucket.new-s3-bucket.id
  s3_key_prefix                 = "cc-trail-logs"
  enable_logging                = true

}

Using AWS Console

01 Sign in to your Trend Cloud One™ – Conformity account, access CloudTrail Trail Bucket Name rule settings and copy the name of the S3 bucket designated to receive and store Amazon CloudTrail data (also known as target bucket).

02 Sign in to the AWS Management Console.

03 Navigate to Amazon CloudTrail console at https://console.aws.amazon.com/cloudtrail/.

04 In the navigation panel, under CloudTrail, choose Trails.

05 Click on the name (link) of the Amazon CloudTrail trail that you want to reconfigure.

06 In the General details section, choose Edit and perform one of the following operations:

  1. If the target bucket already exists, select Use existing S3 bucket under Storage location, choose Browse and select the name of the S3 bucket identified at step no. 1. Click Choose to select the designated bucket. (Optional) You can also specify a prefix for the log files in the Prefix – optional box. Choose Save changes to apply the configuration changes.
  2. If the target bucket does not exist, select Create new S3 bucket under Storage location, and paste the name of the S3 bucket copied at step no. 1 in the Trail log bucket and folder box. Choose Save changes to apply the changes.

07 Repeat steps no. 5 and 6 for each Amazon CloudTrail trail that you want to reconfigure, available in your AWS cloud account.

Using AWS CLI

01 Sign in to your Trend Cloud One™ – Conformity account, access CloudTrail Trail Bucket Name rule settings and copy the name of the S3 bucket designated to receive and store Amazon CloudTrail data.

02 If the target bucket already exists, perform the following operations:

  1. Run update-trail command (OSX/Linux/UNIX) using the name of the Amazon CloudTrail trail that you want to reconfigure as the identifier parameter, to update the storage settings available for the selected trail in order to apply the designated bucket identified at step no. 1:
    aws cloudtrail update-trail
      --region us-east-1
      --name cc-main-cloud-trail
      --s3-bucket-name cc-main-trail-log-bucket
    
  2. The command output should return the metadata available for the reconfigured trail:
    {
        "IncludeGlobalServiceEvents": true,
        "IsOrganizationTrail": false,
        "Name": "cc-main-cloud-trail",
        "TrailARN": "arn:aws:cloudtrail:us-east-1:123456789012:trail/cc-main-cloud-trail",
        "LogFileValidationEnabled": true,
        "IsMultiRegionTrail": true,
        "S3BucketName": "cc-main-trail-log-bucket"
    }
    

03 If the target bucket does not exist, perform the following actions:

  1. Run create-bucket command (OSX/Linux/UNIX) to create the target Amazon S3 bucket. Use the name of the designated S3 bucket copied at step no. 1 as value for the --bucket command parameter:
    aws s3api create-bucket
      --bucket cc-main-trail-log-bucket
      --region us-east-1
      --acl private
    
  2. The command output should return the name of the newly created S3 bucket:
    {
      "Location": "/cc-main-trail-log-bucket"
    }
    
  3. Run put-public-access-block command (OSX/Linux/UNIX) to enable the S3 Public Access Block feature for the new Amazon S3 bucket (the command should not produce an output):
    aws s3api put-public-access-block
      --region us-east-1
      --bucket cc-main-trail-log-bucket
      --public-access-block-configuration BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true
    
  4. Run update-trail command (OSX/Linux/UNIX) using the name of the Amazon CloudTrail trail that you want to reconfigure as the identifier parameter, to associate the new S3 bucket (i.e. target bucket) with the selected trail:
    aws cloudtrail update-trail
      --region us-east-1
      --name cc-main-cloud-trail
      --s3-bucket-name cc-main-trail-log-bucket
    
  5. The command output should return the metadata available for the reconfigured trail:
    {
        "IncludeGlobalServiceEvents": true,
        "IsOrganizationTrail": false,
        "Name": "cc-main-cloud-trail",
        "TrailARN": "arn:aws:cloudtrail:us-east-1:123456789012:trail/cc-main-cloud-trail",
        "LogFileValidationEnabled": true,
        "IsMultiRegionTrail": true,
        "S3BucketName": "cc-main-trail-log-bucket"
    }
    

04 Repeat steps no. 2 and 3 for each Amazon CloudTrail trail that you want to reconfigure, created within your AWS cloud account.

References

Publication date Mar 4, 2019