download cloudtrail logs from an s3 bucket
usage: get_trails.py [-h] --profile PROFILE --bucket BUCKET --prefix PREFIX --account ACCOUNT --region REGION [--from FROM_S] [--to TO_S] [--target_dir TARGET_DIR]
download cloudtrail logs from s3
optional arguments:
-h, --help show this help message and exit
--profile PROFILE the aws named profile to use
--bucket BUCKET s3 bucket name
--prefix PREFIX s3 bucket name
--account ACCOUNT aws account
can be specified multiple times
--region REGION aws region
can be specified multiple times
--from FROM_S start date
default: 'one day ago'
--to TO_S end date
default: 'now'
--target_dir TARGET_DIR
destination directory
default: ./trails/
example date strings:
--from 'one day ago' --to 'now'
--from 'two weeks ago' --to 'one week ago'
--from '2019-10-05' --to '2019-10-19'
--from 'today'
example:
➜ python get_trails.py \
--profile my-profile-name \
--bucket my-log-bucket \
--prefix cloudtrail \
--account 0----------1 \
--region ap-southeast-2
--from today
2020-06-12 10:11:34,502 [INFO] Started
2020-06-12 10:11:34,503 [INFO] profile: my-profile-name
2020-06-12 10:11:34,504 [INFO] bucket: my-log-bucket
2020-06-12 10:11:34,504 [INFO] prefix: cloudtrail
2020-06-12 10:11:34,504 [INFO] account: ['0----------1']
2020-06-12 10:11:34,504 [INFO] region: ['ap-southeast-2']
2020-06-12 10:11:34,504 [INFO] from_s: today
2020-06-12 10:11:34,504 [INFO] to_s: now
2020-06-12 10:11:34,504 [INFO] target_dir: trails
2020-06-12 10:11:34,522 [INFO] Found credentials in shared credentials file: ~/.aws/credentials
2020-06-12 10:11:34,681 [INFO] parsed start date: 2020-06-12 10:11:34.679348+10:00
2020-06-12 10:11:34,681 [INFO] parsed end date: 2020-06-12 10:11:34.681210+10:00
2020-06-12 10:11:34,681 [INFO] found 1 prefixes for download
2020-06-12 10:11:35,810 [INFO] downloading my-log-bucket/cloudtrail/AWSLogs/0----------1/CloudTrail/ap-southeast-2/2020/06/12/0----------1_CloudTrail_ap-southeast-2_20200612T0000Z_Mrtk9CuacsNJFMDN.json.gz
2020-06-12 10:11:36,110 [INFO] downloading my-log-bucket/cloudtrail/AWSLogs/0----------1/CloudTrail/ap-southeast-2/2020/06/12/0----------1_CloudTrail_ap-southeast-2_20200612T0000Z_T97GdFxLajY9plMw.json.gz
2020-06-12 10:11:36,204 [INFO] downloading my-log-bucket/cloudtrail/AWSLogs/0----------1/CloudTrail/ap-southeast-2/2020/06/12/0----------1_CloudTrail_ap-southeast-2_20200612T0000Z_eVbWYjmzjZr8ciQi.json.gz
2020-06-12 10:11:36,396 [INFO] downloading my-log-bucket/cloudtrail/AWSLogs/0----------1/CloudTrail/ap-southeast-2/2020/06/12/0----------1_CloudTrail_ap-southeast-2_20200612T0005Z_gQjb9bzIk0FTv90I.json.gz
2020-06-12 10:11:36,529 [INFO] downloading my-log-bucket/cloudtrail/AWSLogs/0----------1/CloudTrail/ap-southeast-2/2020/06/12/0----------1_CloudTrail_ap-southeast-2_20200612T0010Z_baG8yxnKZIMsSHlb.json.gz
2020-06-12 10:11:36,650 [INFO] downloading my-log-bucket/cloudtrail/AWSLogs/0----------1/CloudTrail/ap-southeast-2/2020/06/12/0----------1_CloudTrail_ap-southeast-2_20200612T0010Z_c7LucC37E8gpybbu.json.gz
2020-06-12 10:11:36,758 [INFO] downloading my-log-bucket/cloudtrail/AWSLogs/0----------1/CloudTrail/ap-southeast-2/2020/06/12/0----------1_CloudTrail_ap-southeast-2_20200612T0015Z_hIxKnEGs7AlX0LZo.json.gz
query cloudtrail logs in target directory using jq syntax
usage: parse_trails.py [-h] [--query QUERY] [--target_dir TARGET_DIR] [--splunk] [--print]
query cloudtrail logs in target directory using jq syntax
optional arguments:
-h, --help show this help message and exit
--query QUERY jq query to run against found trails
--target_dir TARGET_DIR
directory to look for trails
default: ./trails/
--splunk send result to splunk
--print print matching events to console
default action is to display a count of matching events per file
this utility expects cloudtrail logs to be gzipped (no need to unzip logs downloaded from s3)
if using --splunk the SPLUNK_TOKEN and SPLUNK_ENDPOINT envvar must be set. eg:
export SPLUNK_TOKEN='XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
export SPLUNK_ENDPOINT='https://hec-input.splunkcloud.com:443/services/collector/event
example: default
➜ python parse_trails.py --query '.Records[] |select(.errorCode != null) | select(.userIdentity.accessKeyId=="MYACCESSKEYID-----01")'
2020-06-12 15:22:26,837 [INFO] query: .Records[] |select(.errorCode != null) | select(.userIdentity.accessKeyId=="MYACCESSKEYID-----01")
2020-06-12 15:22:26,837 [INFO] target_dir: trails
2020-06-12 15:22:26,837 [INFO] splunk: False
2020-06-12 15:22:26,837 [INFO] print: False
2020-06-12 15:22:26,839 [INFO] found 208 files to query
2020-06-12 15:23:00,526 [INFO] found 1 matching events in 0----------1_CloudTrail_ap-southeast-2_20200612T0335Z_3bkWdyXX2VbIPmPV.json.gz
example: display matching events
➜ python parse_trails.py --query '.Records[] |select(.errorCode != null) | select(.userIdentity.accessKeyId=="MYACCESSKEYID-----01")' --print
2020-06-12 15:23:07,077 [INFO] query: .Records[] |select(.errorCode != null) | select(.userIdentity.accessKeyId=="MYACCESSKEYID-----01")
2020-06-12 15:23:07,077 [INFO] target_dir: trails
2020-06-12 15:23:07,077 [INFO] splunk: False
2020-06-12 15:23:07,077 [INFO] print: True
2020-06-12 15:23:07,079 [INFO] found 208 files to query
2020-06-12 15:23:42,865 [INFO] found 1 matching events in 0----------1_CloudTrail_ap-southeast-2_20200612T0335Z_3bkWdyXX2VbIPmPV.json.gz
{"eventVersion": "1.07", "userIdentity": {"type": "AssumedRole", "principalId": "MYACCESSKEYID-----02:AutoScaling-UpdateDesiredCapacity", "arn": "arn:aws:sts::0----------1:assumed-role/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable/AutoScaling-UpdateDesiredCapacity", "accountId": "0----------1", "accessKeyId": "MYACCESSKEYID-----01", "sessionContext": {"sessionIssuer": {"type": "Role", "principalId": "MYACCESSKEYID-----02", "arn": "arn:aws:iam::0----------1:role/aws-service-role/dynamodb.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_DynamoDBTable", "accountId": "0----------1", "userName": "AWSServiceRoleForApplicationAutoScaling_DynamoDBTable"}, "attributes": {"creationDate": "2020-06-12T03:23:43Z", "mfaAuthenticated": "false"}}, "invokedBy": "dynamodb.application-autoscaling.amazonaws.com"}, "eventTime": "2020-06-12T03:32:22Z", "eventSource": "dynamodb.amazonaws.com", "eventName": "UpdateTable", "awsRegion": "ap-southeast-2", "sourceIPAddress": "dynamodb.application-autoscaling.amazonaws.com", "userAgent": "dynamodb.application-autoscaling.amazonaws.com", "errorCode": "LimitExceededException", "errorMessage": "Subscriber limit exceeded: Provisioned throughput decreases are limited within a given UTC day. After the first 4 decreases, each subsequent decrease in the same UTC day can be performed at most once every 3600 seconds. Number of decreases today: 6. Last decrease at Friday, June 12, 2020 at 3:23:45 AM Coordinated Universal Time. Next decrease can be made at Friday, June 12, 2020 at 4:23:45 AM Coordinated Universal Time", "requestParameters": {"tableName": "listings-out-of-order-dynamodb-prod", "globalSecondaryIndexUpdates": [{"update": {"indexName": "gsi-listings-out-of-order-sourceid", "provisionedThroughput": {"readCapacityUnits": 1, "writeCapacityUnits": 5}}}]}, "responseElements": null, "requestID": "1--------------------------------------------------G", "eventID": "363f05d5-XXXX-XXXX-XXXX-bb6d82be5d1f", "readOnly": false, "resources": [{"accountId": "0----------1", "type": "AWS::DynamoDB::Table", "ARN": "arn:aws:dynamodb:ap-southeast-2:0----------1:table/listings-out-of-order-dynamodb-prod"}], "eventType": "AwsApiCall", "apiVersion": "2012-08-10", "managementEvent": true, "recipientAccountId": "0----------1", "eventCategory": "Management"}
example: push results to splunk
➜ python parse_trails.py --query '.Records[] |select(.errorCode != null) | select(.userIdentity.accessKeyId=="MYACCESSKEYID-----01")' --splunk
2020-06-12 15:30:08,263 [INFO] query: .Records[] |select(.errorCode != null) | select(.userIdentity.accessKeyId=="MYACCESSKEYID-----01")
2020-06-12 15:30:08,263 [INFO] target_dir: trails
2020-06-12 15:30:08,263 [INFO] splunk: True
2020-06-12 15:30:08,263 [INFO] print: False
2020-06-12 15:30:08,266 [INFO] found 208 files to query
2020-06-12 15:30:42,249 [INFO] found 1 matching events in 0----------1_CloudTrail_ap-southeast-2_20200612T0335Z_3bkWdyXX2VbIPmPV.json.gz
2020-06-12 15:30:42,454 [INFO] splunk: 363f05d5-XXXX-XXXX-XXXX-bb6d82be5d1f [HTTP 200]