Trails, Buckets, and Logs

Suffering from “Systems Autism,” I tend to automate everything I can; at least that way, I can make the same mistake multiple times, mainly if I must perform the same actions repeatedly.

The setup of Cloudtrails, the S3 bucket to receive them, and the bucket to log access to the S3 bucket is not overly challenging when done from the console for ONE setup; doing it across multiple installations is redundant. Time for that DevOps thing.

Here is a code block that might be used to do this: DO READ the code; any damage, loss of work, loss of time, etc., etc., are the READER’s fault. (YOU CHOOSE to cut and paste.)

# crawls @2022
# Variables
# WazuhTrailBucketArn 	- Arn of S3 bucket to receive Wazuh Trail
# WazuhLogBucketArn   	- Arn of S3 bucket to receive Wazuh S3 access logs
# WazuhTrailArn		- Arn of the Wazuh Trail
# WazuhTrailRoleArn	- Arn of Wazuhtrailrole
# Constants
# Wazuhtrailbucket 	- bucket to receive Wazuh trail logs
# Wazuhlogbucket   	- bucket to receive all S3 server and object logs
# Wazuhtrail		- cloudtrail name
# ======================= It Begins ===============
# Create as3 bucket to receive cloudtrails, events  and logs
aalias=`aws iam list-account-aliases --query 'AccountAliases' --output text`
echo "Creating TrailBucket : "$WazuhTrailBucketName
WazuhTrailBucketArn=$(aws s3api create-bucket --bucket $WazuhTrailBucketName --acl private)
echo "Creating LogBucket : "$WazuhLogBucketName
WazuhLogBucketArn=$(aws s3api create-bucket --bucket $WazuhLogBucketName --acl private)
# Set life cycle config
#  Lifecycle policy
aws s3api put-bucket-lifecycle-configuration --bucket $WazuhTrailBucketName --lifecycle-configuration '{"Rules":[{"Filter":{"Prefix":""},"NoncurrentVersionExpiration":{"NoncurrentDays":90},"ID":"Compliance_Retention","AbortIncompleteMultipartUpload":{"DaysAfterInitiation":7},"Transitions":[{"Days":90,"StorageClass":"GLACIER"}],"Expiration":{"Days":2555},"Status":"Enabled"}]}'
aws s3api put-bucket-lifecycle-configuration --bucket $WazuhLogBucketName --lifecycle-configuration '{"Rules":[{"Filter":{"Prefix":""},"NoncurrentVersionExpiration":{"NoncurrentDays":90},"ID":"Compliance_Retention","AbortIncompleteMultipartUpload":{"DaysAfterInitiation":7},"Transitions":[{"Days":90,"StorageClass":"GLACIER"}],"Expiration":{"Days":2555},"Status":"Enabled"}]}'
# Set the public access block acl
aws s3api put-public-access-block --bucket $WazuhTrailBucketName --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
aws s3api put-public-access-block --bucket $WazuhLogBucketName --public-access-block-configuration "BlockPublicAcls=true,IgnorePublicAcls=true,BlockPublicPolicy=true,RestrictPublicBuckets=true"
# Base Trail, Log bucket created
# Now Lets Set Object, Server level logging and Default encryption
aws s3api put-bucket-encryption --bucket $WazuhTrailBucketName --server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'
aws s3api put-bucket-encryption --bucket $WazuhLogBucketName --server-side-encryption-configuration '{"Rules": [{"ApplyServerSideEncryptionByDefault": {"SSEAlgorithm": "AES256"}}]}'
# Setup Access logging for Trails bucket to logbucket
# Grant the rights to write ...
aws s3api put-bucket-acl --bucket $WazuhLogBucketName --grant-read-acp 'URI=""' --grant-write 'URI=""'
echo "Set logging for "$WazuhTrailBucketName" to bucket "$WazuhLogBucketName
aws s3api put-bucket-logging --bucket $WazuhTrailBucketName --bucket-logging-status '{"LoggingEnabled":{"TargetPrefix":"S3logs/Wazuhtrailbucket/","TargetBucket":"'$WazuhLogBucketName'"}}'
aws s3api put-bucket-policy --bucket $WazuhTrailBucketName --policy '{"Version":"2012-10-17","Statement":[{"Sid":"AWSCloudTrailAclCheck20150319","Effect":"Allow","Principal":{"Service":""},"Action":"s3:GetBucketAcl","Resource":"arn:aws:s3:::'$WazuhTrailBucketName'"},{"Sid":"AWSCloudTrailWrite20150319","Effect":"Allow","Principal":{"Service":""},"Action":"s3:PutObject","Resource":"arn:aws:s3:::'$WazuhTrailBucketName'/AWSLogs/*","Condition":{"StringEquals":{"s3:x-amz-acl":"bucket-owner-full-control"}}}]}'
# Create the Wazuh Trail
WazuhTrailArn=$(aws cloudtrail create-trail --name Wazuhtrail --s3-bucket-name $WazuhTrailBucketName --is-multi-region-trail --enable-log-file-validation --include-global-service-events --query 'TrailARN' --output text)
# And update it to capture events (all R/W, KMS, S3, Lambda)
aws cloudtrail put-event-selectors --trail-name Wazuhtrail --event-selectors '[{"ReadWriteType": "All","IncludeManagementEvents": true,"DataResources": [{"Type":"AWS::S3::Object", "Values": ["arn:aws:s3:::"]},{"Type": "AWS::Lambda::Function","Values": ["arn:aws:lambda"]}]}]'
#  Turn on Logging.
aws cloudtrail start-logging --name WazuhTrail

I will refer the reader to my post, O.P.C. OTHER PEOPLE’S CODE.

For a quick review:

  • Lines 1-15, Basic Documentation of the Variables and constants used.
  • Lines 17-24 Create an as3 bucket to receive cloudtrails and logs and perform a basic lockdown.
  • Lines 28-30 Setup Data LifeCycle and apply to our buckets
  • Lines 30-32 Apply the Public NACLs to our buckets
  • LInes 36-37 Encrypt the buckets with KMS-SSE
  • Lines 41-45 Grant rights to write to the buckets and set the access logging
  • Line 49 Create our CloudTrail
  • Line 52 Modify the trail to capture everything we wish; other data events can be added
  • Line 56 Start Logging.

I SO appreciate the cards, letters, and comments on my posts; alas, it would seem that the cut-and-paste crew is unsatisfied with my recent posts on CloudTrails, S3, and the proper configuration of said, hence this post.