Kloudle
academy

Getting started with AWS CloudTrail to monitor for security-sensitive APIs

Riyaz Walikar
#aws#cloudsecurity#cloudtrail
Feature image

‍Background

Amazon Web Services or AWS consists of a huge collection of services that can be utilized to accomplish various tasks. To effectively manage this collection of services an SRE should be able to have visibility into the AWS account and the actions being taken in the account in the form of logs that provide details about these actions. These logs not only provide a source-of-truth and accountability for all operations performed in the account on the various services that one can use, but they are also a crucial factor that help in enhancing the security of the AWS account by allowing the monitoring of sensitive operations being performed and in the event of a security breach, to perform investigation and prevent further damage.

Introduction to AWS CloudTrail

CloudTrail is a service offered by AWS to monitor and record all actions taken within an AWS account by any IAM user, role or another AWS service. These actions are recorded as events in CloudTrail and can be used to set up monitoring of anomalous events, alerting on sensitive API calls and so forth.

AWS CloudTrail is enabled for the AWS account at the time of its creation and the history of actions is visible though Event History on the AWS Console page for CloudTrail. CloudTrail also offers the creation of a “trail” that records all actions that are performed in the account.

Setting up AWS CloudTrail for an AWS Account

Create a Trail - Using the console

  1. Log in to the AWS Console and navigate to the CloudTrail service

  2. Click on the “Create Trail” button

    Create Trail

  3. Provide a name for the trail

    name for trail

  4. Select an existing bucket or create a new one to store the CloudTrail logs

    bucket to store CloudTrail logs

  5. Enable “SSE-KMS encryption option”, choose the “New” option to create a new KMS key and give it a name or pick an existing key if required

    SSE-KMS encryption

  6. Enable “Log file validation”

  7. Enable “CloudWatch Logs”, select an existing Log Group and IAM role to write to the log group, or create new log group and/or role

    CloudWatch Logs

    CloudWatch Log

  8. Add relevant tags for the trail

    tags

  9. Click on the “Next” button

    create tags

  10. Ensure that “Management events” option is selected, you can additionally enable other options too if required

    Management events

  11. Under “API Activity” section ensure that both “Read” and “Write” options are selected and then click on “Next” button

    API Activity

  12. Verify all details entered to create the trail and lastly, click on “Create trail” button

    Create trail

Note: A trail created using the console is a multi-region trail by default.

Create a Trail - Using the AWS CLI

Prerequisites

Unlike the web console, where we were able to create supporting resources for creating a trail like S3 Bucket, Log Groups, etc., in the CLI we need to have this information before we create the trail. So before moving forward, ensure that the following information is ready:

  1. S3 Bucket’s name, where the logs would be stored with the following Bucket policy (Edit by adding the appropriate bucket name/ARN)

    {
    
        "Version": "2012-10-17",
    
        "Statement": [
    
            {
    
                "Sid": "AWSCloudTrailAclCheck20150319",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "Service": "cloudtrail.amazonaws.com"
    
                },
    
                "Action": "s3:GetBucketAcl",
    
    "Resource": "arn:aws:s3:::bucket-for-cloudtrail"
    
            },
    
            {
    
                "Sid": "AWSCloudTrailWrite20150319",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "Service": "cloudtrail.amazonaws.com"
    
                },
    
                "Action": "s3:PutObject",
    
    "Resource": "arn:aws:s3:::bucket-for-cloudtrail/AWSLogs/914397138150/*",
    
                "Condition": {
    
                    "StringEquals": {
    
                        "s3:x-amz-acl": "bucket-owner-full-control"
    
                    }
    
                }
    
            }
    
        ]
    
    }
    
  2. CloudWatch Log Group’s ARN, where the logs would be stored in addition to the S3 bucket, this log group needs to be in the same region as the trail

  3. IAM Role’s ARN, which would be used to write to the CloudWatch Log Group with the following Policy attached (Edit it and replace information such as the correct account ID, log group name, etc.)

    {
    
        "Version": "2012-10-17",
    
        "Statement": [
    
            {
    
                "Sid": "AWSCloudTrailCreateLogStream2014110",
    
                "Effect": "Allow",
    
                "Action": [
    
                    "logs:CreateLogStream"
    
                ],
    
                "Resource": [
    
                    "arn:aws:logs:us-east-1:000000000000:log-group:management-events-cloudtrail-logs:log-stream:000000000000_CloudTrail_us-east-1*"
    
                ]
    
            },
    
            {
    
                "Sid": "AWSCloudTrailPutLogEvents20141101",
    
                "Effect": "Allow",
    
                "Action": [
    
                    "logs:PutLogEvents"
    
                ],
    
                "Resource": [
    
                    "arn:aws:logs:us-east-1:000000000000:log-group:management-events-cloudtrail-logs:log-stream:000000000000_CloudTrail_us-east-1*"
    
                ]
    
            }
    
        ]
    
    }
    
    ```‍
    
  4. KMS Key’s ID, used to enable log file encryption option for the trail with the following Key Policy (Replace “000000000000” with the appropriate account ID and “REGION” with the appropriate region)

    {
    
        "Version": "2012-10-17",
    
        "Id": "Key policy created by CloudTrail",
    
        "Statement": [
    
            {
    
                "Sid": "Enable IAM User Permissions",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "AWS": [
    
                        "arn:aws:iam::000000000000:root",
    
                        "arn:aws:iam::000000000000:user/ayush"
    
                    ]
    
                },
    
                "Action": "kms:*",
    
                "Resource": "*"
    
            },
    
            {
    
                "Sid": "Allow CloudTrail to encrypt logs",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "Service": "cloudtrail.amazonaws.com"
    
                },
    
                "Action": "kms:GenerateDataKey*",
    
                "Resource": "*",
    
                "Condition": {
    
                    "StringLike": {
    
                        "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:000000000000:trail/*"
    
                    }
    
                }
    
            },
    
            {
    
                "Sid": "Allow CloudTrail to describe key",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "Service": "cloudtrail.amazonaws.com"
    
                },
    
                "Action": "kms:DescribeKey",
    
                "Resource": "*"
    
            },
    
            {
    
                "Sid": "Allow principals in the account to decrypt log files",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "AWS": "*"
    
                },
    
                "Action": [
    
                    "kms:Decrypt",
    
                    "kms:ReEncryptFrom"
    
                ],
    
                "Resource": "*",
    
                "Condition": {
    
                    "StringEquals": {
    
                        "kms:CallerAccount": "000000000000"
    
                    },
    
                    "StringLike": {
    
                        "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:000000000000:trail/*"
    
                    }
    
                }
    
            },
    
            {
    
                "Sid": "Allow alias creation during setup",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "AWS": "*"
    
                },
    
                "Action": "kms:CreateAlias",
    
                "Resource": "*",
    
                "Condition": {
    
                    "StringEquals": {
    
                        "kms:ViaService": "ec2.REGION.amazonaws.com",
    
                        "kms:CallerAccount": "000000000000"
    
                    }
    
                }
    
            },
    
            {
    
                "Sid": "Enable cross account log decryption",
    
                "Effect": "Allow",
    
                "Principal": {
    
                    "AWS": "*"
    
                },
    
                "Action": [
    
                    "kms:Decrypt",
    
                    "kms:ReEncryptFrom"
    
                ],
    
                "Resource": "*",
    
                "Condition": {
    
                    "StringEquals": {
    
                        "kms:CallerAccount": "000000000000"
    
                    },
    
                    "StringLike": {
    
                        "kms:EncryptionContext:aws:cloudtrail:arn": "arn:aws:cloudtrail:*:000000000000:trail/*"
    
                    }
    
                }
    
            }
    
        ]
    
    }
    ‍```

Creating the trail

Once the prerequisites are set up, we can perform the following steps to create a trail:

  1. Run the command by replacing all placeholder values

    aws cloudtrail create-trail --name  --s3-bucket-name  --is-multi-region-trail --enable-log-file-validation --cloud-watch-logs-log-group-arn  --cloud-watch-logs-role-arn  --kms-key-id  --tags-list Key=createdBy,Value=

aws cloudtrail create-trail

Verifying that the Trail is set up

Now that we have performed the steps to set up the trail in CloudTrail, we need to verify that it was created successfully and verify all the configurations we added.

Verify - Using the Console

To verify that the trail is created correctly with the specified options, perform the following steps:

  1. Log in to AWS Console and navigate to the CloudTrail service

  2. On the dashboard, verify that a trail exists with the name we created in the previous section (here “test-trail”)

    test trail

  3. Lastly, click on the trail to verify the remaining details that were configured

    trail details

Note: If the trail details say that logging is off, make sure to enable it as only then it would start recording events.

Verify - Using the CLI

To verify that the trail is created correctly with the specified options, run the following command:

aws cloudtrail describe-trails

aws cloudtrail describe-trails

Conclusion

CloudTrail is an important service that provides us visibility into our usage of the cloud account by maintaining a record of all actions that occurred. This information is critical to store as it serves as the single source of truth that one would check to verify any actions or the entities that performed certain actions. CloudTrail allows us to do various activities which include but are not restricted to analyzing and debug issues when our Cloud Infrastructure faces disruptions, to perform investigation in case of a security incident, and so forth.

← Back to Academy