@@ -50,6 +50,7 @@ const (
50
50
LB_NLB_TYPE string = "net"
51
51
LB_ALB_TYPE string = "app"
52
52
WAF_LOG_TYPE string = "WAFLogs"
53
+ GUARDDUTY_LOG_TYPE string = "GuardDuty"
53
54
)
54
55
55
56
var (
@@ -75,13 +76,18 @@ var (
75
76
// source: https://docs.aws.amazon.com/waf/latest/developerguide/logging-s3.html
76
77
// format: aws-waf-logs-suffix[/prefix]/AWSLogs/aws-account-id/WAFLogs/region/webacl-name/year/month/day/hour/minute/aws-account-id_waflogs_region_webacl-name_timestamp_hash.log.gz
77
78
// example: aws-waf-logs-test/AWSLogs/11111111111/WAFLogs/us-east-1/TEST-WEBACL/2021/10/28/19/50/11111111111_waflogs_us-east-1_TEST-WEBACL_20211028T1950Z_e0ca43b5.log.gz
79
+ // AWS GuardDuty
80
+ // source: https://docs.aws.amazon.com/guardduty/latest/ug/guardduty_exportfindings.html
81
+ // format: my-bucket/AWSLogs/aws-account-id/GuardDuty/region/year/month/day/random-string.jsonl.gz
82
+ // example: my-bucket/AWSLogs/123456789012/GuardDuty/us-east-1/2024/05/30/07a3f2ce-1485-3031-b842-e1f324c4a48d.jsonl.gz
78
83
defaultFilenameRegex = regexp .MustCompile (`AWSLogs\/(?P<account_id>\d+)\/(?P<type>[a-zA-Z0-9_\-]+)\/(?P<region>[\w-]+)\/(?P<year>\d+)\/(?P<month>\d+)\/(?P<day>\d+)\/\d+\_(?:elasticloadbalancing|vpcflowlogs)_(?:\w+-\w+-(?:\w+-)?\d)_(?:(?P<lb_type>app|net)\.*?)?(?P<src>[a-zA-Z0-9\-]+)` )
79
84
defaultTimestampRegex = regexp .MustCompile (`(?P<timestamp>\d+-\d+-\d+T\d+:\d+:\d+(?:\.\d+Z)?)` )
80
85
cloudtrailFilenameRegex = regexp .MustCompile (`AWSLogs\/(?P<organization_id>o-[a-z0-9]{10,32})?\/?(?P<account_id>\d+)\/(?P<type>[a-zA-Z0-9_\-]+)\/(?P<region>[\w-]+)\/(?P<year>\d+)\/(?P<month>\d+)\/(?P<day>\d+)\/\d+\_(?:CloudTrail|CloudTrail-Digest)_(?:\w+-\w+-(?:\w+-)?\d)_(?:(?:app|nlb|net)\.*?)?.+_(?P<src>[a-zA-Z0-9\-]+)` )
81
86
cloudfrontFilenameRegex = regexp .MustCompile (`(?P<prefix>.*)\/(?P<src>[A-Z0-9]+)\.(?P<year>\d+)-(?P<month>\d+)-(?P<day>\d+)-(.+)` )
82
87
cloudfrontTimestampRegex = regexp .MustCompile (`(?P<timestamp>\d+-\d+-\d+\s\d+:\d+:\d+)` )
83
88
wafFilenameRegex = regexp .MustCompile (`AWSLogs\/(?P<account_id>\d+)\/(?P<type>WAFLogs)\/(?P<region>[\w-]+)\/(?P<src>[\w-]+)\/(?P<year>\d+)\/(?P<month>\d+)\/(?P<day>\d+)\/(?P<hour>\d+)\/(?P<minute>\d+)\/\d+\_waflogs\_[\w-]+_[\w-]+_\d+T\d+Z_\w+` )
84
89
wafTimestampRegex = regexp .MustCompile (`"timestamp":\s*(?P<timestamp>\d+),` )
90
+ guarddutyFilenameRegex = regexp .MustCompile (`AWSLogs\/(?P<account_id>\d+)\/(?P<type>GuardDuty)\/(?P<region>[\w-]+)\/(?P<year>\d+)\/(?P<month>\d+)\/(?P<day>\d+)\/.+` )
85
91
parsers = map [string ]parserConfig {
86
92
FLOW_LOG_TYPE : {
87
93
logTypeLabel : "s3_vpc_flow" ,
@@ -122,6 +128,14 @@ var (
122
128
timestampRegex : wafTimestampRegex ,
123
129
timestampType : "unix" ,
124
130
},
131
+ GUARDDUTY_LOG_TYPE : {
132
+ logTypeLabel : "s3_guardduty" ,
133
+ filenameRegex : guarddutyFilenameRegex ,
134
+ ownerLabelKey : "account_id" ,
135
+ timestampFormat : time .RFC3339 ,
136
+ timestampRegex : defaultTimestampRegex ,
137
+ timestampType : "string" ,
138
+ },
125
139
}
126
140
)
127
141
@@ -165,7 +179,7 @@ func parseS3Log(ctx context.Context, b *batch, labels map[string]string, obj io.
165
179
ls = applyLabels (ls )
166
180
167
181
// extract the timestamp of the nested event and sends the rest as raw json
168
- if labels ["type" ] == CLOUDTRAIL_LOG_TYPE {
182
+ if labels ["type" ] == CLOUDTRAIL_LOG_TYPE || labels [ "type" ] == GUARDDUTY_LOG_TYPE {
169
183
records := make (chan Record )
170
184
jsonStream := NewJSONStream (records )
171
185
go jsonStream .Start (gzreader , parser .skipHeaderCount )
0 commit comments