Skip to content

Commit faf38e5

Browse files
author
Joshua Leaverton
committed
Updated to v2.3.3
1 parent 194c985 commit faf38e5

26 files changed

+1755
-175
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1414
- Fixed README file to accurately reflect script params
1515
- Upgraded from Python 3.7 to 3.8
1616
- Changed RequestThreshold min limit from 2000 to 100
17+
## [2.3.3] - 2020-05-15
18+
### Added
19+
- Implemented Athena optimization: added partitioning for CloudFront, ALB and WAF logs and Athena queries
20+
### Changed
21+
- Fixed potential DoS vector within Bad Bots X-Forward-For header

NOTICE.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
AWS WAF Security Automations
22

3-
Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
44
Licensed under the Apache License Version 2.0 (the "License"). You may not use this file except
55
in compliance with the License. A copy of the License is located at http://www.apache.org/licenses/
66
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS,
@@ -17,3 +17,4 @@ sax under the Internet Systems Consortium (ISC) license
1717
xml2js under the Massachusetts Institute of Technology (MIT) license
1818
xmlbuilder under the Massachusetts Institute of Technology (MIT) license
1919
requests under the Apache Software License
20+
freezegun under the Apache License Version 2.0

README.md

Lines changed: 26 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@ A solution that contains all AWS WAF samples developed so far - waf-reactive-bla
33

44
For the full solution overview visit [AWS WAF Security Automations](https://aws.amazon.com/answers/security/aws-waf-security-automations/).
55

6-
>Be aware that using the ***Athena log parser*** option with the HTTP Flood Protection and/or Scanner and Probe Protection rules may result in significant Athena charges. The log parser runs a scheduled query against your S3 log bucket every 5 minutes. Charges are based on the amount of logs Athena must scan as part of this query."
7-
86
## File Structure
97
This project consists of microservices that facilitate the functional areas of the solution. These microservices are deployed to a serverless environment in AWS Lambda.
108

@@ -14,8 +12,9 @@ This project consists of microservices that facilitate the functional areas of t
1412
|-access-handler/ [microservice for processing bad bots honeypot endpoint access. This AWS Lambda function intercepts the suspicious request and adds the source IP address to the AWS WAF block list]
1513
|-custom-resource/ [custom helper for CloudFormation deployment template]
1614
|-helper/ [custom helper for CloudFormation deployment dependency check and auxiliary functions]
17-
|-log-parser/ [microservice for processing access logs searching for suspicious behavior and add the corresponding source IP addresses to an AWS WAF block list]
15+
|-log_parser/ [microservice for processing access logs searching for suspicious behavior and add the corresponding source IP addresses to an AWS WAF block list]
1816
|-reputation-lists-parser/ [microservice for processing third-party IP reputation lists and add malicious IP addresses to an AWS WAF block list]
17+
|-tests/ [unit tests]
1918
```
2019

2120
## Getting Started
@@ -30,40 +29,49 @@ The following procedures assumes that all of the OS-level configuration has been
3029
The AWS WAF Security Automations solution is developed with Node.js and Python for the microservices that run in AWS Lambda. The latest version has been tested with Node.js v10.x and Python v3.8.
3130

3231
#### 02. Clone AWS WAF Security Automations repository
33-
Clone the aws-waf-security-automations GitHub repository:
32+
Clone the aws-waf-security-automations GitHub repository, then make the desired code changes
3433

3534
```
3635
git clone https://github.com/awslabs/aws-waf-security-automations.git
3736
```
3837

39-
#### 03. Declare enviroment variables:
38+
#### 03. Run unit tests
39+
Next, run unit tests to make sure added customization passes the tests
40+
41+
```
42+
cd ./deployment
43+
chmod +x ./run-unit-tests.sh
44+
./run-unit-tests.sh
45+
```
46+
47+
#### 04. Declare enviroment variables:
4048
```
41-
export TEMPLATE_OUTPUT_BUCKET=<YOUR_TEMPLATE_OUTPUT_BUCKET>
42-
export DIST_OUTPUT_BUCKET=<YOUR_DIST_OUTPUT_BUCKET>
43-
export SOLUTION_NAME="workspaces-cost-optimizer"
44-
export VERSION=<VERSION>
45-
export AWS_REGION=<AWS_REGION>
49+
export TEMPLATE_OUTPUT_BUCKET=<YOUR_TEMPLATE_OUTPUT_BUCKET> # Name for the S3 bucket where the template will be located
50+
export DIST_OUTPUT_BUCKET=<YOUR_DIST_OUTPUT_BUCKET> # Name for the S3 bucket where customized code will reside
51+
export SOLUTION_NAME="aws-waf-security-automations" # name of the solution
52+
export VERSION=<VERSION> # version number for the customized code
53+
export AWS_REGION=<AWS_REGION> # region where the distributable is deployed
4654
```
55+
# _Note:_ You must manually create two buckets in S3 called $TEMPLATE_OUTPUT_BUCKET and $DIST_OUTPUT_BUCKET-$AWS_REGION to copy the distribution. The assets in bucket should be publicly accessible. The build-s3-dist.sh script DOES NOT do this and the CloudFormation template expects/references the REGION specific bucket.
4756

48-
#### 04. Build the AWS WAF Security Automations solution for deployment:
57+
#### 05. Build the AWS WAF Security Automations solution for deployment:
4958
```
5059
chmod +x ./build-s3-dist.sh && ./build-s3-dist.sh $TEMPLATE_OUTPUT_BUCKET $DIST_OUTPUT_BUCKET $SOLUTION_NAME $VERSION
5160
```
52-
#### 05. Upload deployment assets to your Amazon S3 bucket:
53-
54-
Note that you must manually create a bucket in S3 called `$DIST_OUTPUT_BUCKET-$AWS_REGION` to copy the distribution. The build-s3-dist.sh script DOES NOT do this and the CloudFormation template expects/references the REGION specific bucket.
55-
61+
#### 06. Upload deployment assets to your Amazon S3 buckets:
5662
```
57-
aws s3 cp ./dist s3://$DIST_OUTPUT_BUCKET-$AWS_REGION/aws-waf-security-automations/latest --recursive --acl bucket-owner-full-control
63+
aws s3 cp ./deployment/global-s3-assets s3://$TEMPLATE_OUTPUT_BUCKET/aws-waf-security-automations/$VERSION --recursive --acl bucket-owner-full-control
64+
aws s3 cp ./deployment/regional-s3-assets s3://$DIST_OUTPUT_BUCKET-$AWS_REGION/aws-waf-security-automations/$VERSION --recursive --acl bucket-owner-full-control
5865
```
66+
# _Note:_ You must use proper acl and profile for the copy operation as applicable.
5967

60-
#### 06. Deploy the AWS WAF Security Automations solution:
68+
#### 07. Deploy the AWS WAF Security Automations solution:
6169
* From your designated Amazon S3 bucket where you uploaded the deployment assets, copy the link location for the aws-waf-security-automations.template.
6270
* Using AWS CloudFormation, launch the AWS WAF Security Automations solution stack using the copied Amazon S3 link for the aws-waf-security-automations.template.
6371

6472
***
6573

66-
Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
74+
Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
6775

6876
Licensed under the Apache License, Version 2.0 (the "License");
6977
you may not use this file except in compliance with the License.

deployment/aws-waf-security-automations-alb.template

Lines changed: 180 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
1+
# Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License").
44
# You may not use this file except in compliance with the License.
@@ -96,6 +96,13 @@ Conditions:
9696
- !Ref ActivateBadBotProtectionParam
9797
- 'yes'
9898

99+
AthenaLogParser: !Or
100+
- Condition: HttpFloodAthenaLogParser
101+
- Condition: ScannersProbesAthenaLogParser
102+
103+
CustomResourceLambdaAccess: !Or
104+
- Condition: ReputationListsProtectionActivated
105+
- Condition: AthenaLogParser
99106

100107
Resources:
101108
WAFWhitelistSet:
@@ -359,7 +366,7 @@ Resources:
359366
- 'athena:GetNamedQuery'
360367
- 'athena:StartQueryExecution'
361368
Resource:
362-
- !Sub 'arn:aws:athena:${AWS::Region}:${AWS::AccountId}:workgroup/*'
369+
- !Sub 'arn:aws:athena:${AWS::Region}:${AWS::AccountId}:workgroup/WAF*'
363370
# S3 Resources
364371
- Effect: Allow
365372
Action:
@@ -378,6 +385,7 @@ Resources:
378385
- Effect: Allow
379386
Action:
380387
- 'glue:GetTable'
388+
- 'glue:GetPartitions'
381389
Resource:
382390
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:catalog'
383391
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/${GlueAccessLogsDatabase}'
@@ -418,7 +426,7 @@ Resources:
418426
- 'athena:GetNamedQuery'
419427
- 'athena:StartQueryExecution'
420428
Resource:
421-
- !Sub 'arn:aws:athena:${AWS::Region}:${AWS::AccountId}:workgroup/*'
429+
- !Sub 'arn:aws:athena:${AWS::Region}:${AWS::AccountId}:workgroup/WAF*'
422430
# S3 Resources
423431
- Effect: Allow
424432
Action:
@@ -437,6 +445,7 @@ Resources:
437445
- Effect: Allow
438446
Action:
439447
- 'glue:GetTable'
448+
- 'glue:GetPartitions'
440449
Resource:
441450
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:catalog'
442451
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/${GlueAccessLogsDatabase}'
@@ -476,6 +485,164 @@ Resources:
476485
LogsAccess - permission restricted to account, region and log group name substring (LogParser);
477486
CloudWatchAccess - this actions does not support resource-level permissions
478487

488+
LambdaRolePartitionS3Logs:
489+
Type: 'AWS::IAM::Role'
490+
Condition: ScannersProbesAthenaLogParser
491+
Metadata:
492+
cfn_nag:
493+
rules_to_suppress:
494+
-
495+
id: W11
496+
reason: >-
497+
LogsAccess - permission restricted to account, region and log group name substring (MoveS3LogsForPartition)
498+
Properties:
499+
AssumeRolePolicyDocument:
500+
Statement:
501+
- Effect: Allow
502+
Principal:
503+
Service:
504+
- lambda.amazonaws.com
505+
Action:
506+
- sts:AssumeRole
507+
Path: '/'
508+
Policies:
509+
- !If
510+
- ScannersProbesAthenaLogParser
511+
- PolicyName: PartitionS3LogsAccess
512+
PolicyDocument:
513+
Statement:
514+
# S3 Resources
515+
- Effect: Allow
516+
Action:
517+
- 's3:GetObject'
518+
- 's3:DeleteObject'
519+
- 's3:PutObject'
520+
Resource:
521+
- !Sub 'arn:aws:s3:::${AppAccessLogBucket}/*'
522+
- !Ref 'AWS::NoValue'
523+
- PolicyName: LogsAccess
524+
PolicyDocument:
525+
Statement:
526+
- Effect: Allow
527+
Action:
528+
- 'logs:CreateLogGroup'
529+
- 'logs:CreateLogStream'
530+
- 'logs:PutLogEvents'
531+
Resource:
532+
- !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*MoveS3LogsForPartition*'
533+
534+
LambdaRoleAddAthenaPartitions:
535+
Type: 'AWS::IAM::Role'
536+
Condition: AthenaLogParser
537+
Metadata:
538+
cfn_nag:
539+
rules_to_suppress:
540+
-
541+
id: W11
542+
reason: >-
543+
LogsAccess - permission restricted to account, region and log group name substring (AddAthenaPartitions)
544+
Properties:
545+
AssumeRolePolicyDocument:
546+
Statement:
547+
- Effect: Allow
548+
Principal:
549+
Service:
550+
- lambda.amazonaws.com
551+
Action:
552+
- sts:AssumeRole
553+
Path: '/'
554+
Policies:
555+
- !If
556+
- ScannersProbesAthenaLogParser
557+
- PolicyName: AddAthenaPartitionsForAppAccessLog
558+
PolicyDocument:
559+
Statement:
560+
# S3 Resources
561+
- Effect: Allow
562+
Action:
563+
- 's3:GetObject'
564+
- 's3:PutObject'
565+
- 's3:GetBucketLocation'
566+
- 's3:ListBucket'
567+
- 's3:ListBucketMultipartUploads'
568+
- 's3:ListMultipartUploadParts'
569+
- 's3:AbortMultipartUpload'
570+
- 's3:CreateBucket'
571+
Resource:
572+
- !Sub 'arn:aws:s3:::${AppAccessLogBucket}/athena_results/*'
573+
- !Sub 'arn:aws:s3:::${AppAccessLogBucket}'
574+
- !Sub 'arn:aws:s3:::${AppAccessLogBucket}/*'
575+
# Athena Resources
576+
- Effect: Allow
577+
Action:
578+
- 'athena:StartQueryExecution'
579+
Resource:
580+
- !Sub 'arn:aws:athena:${AWS::Region}:${AWS::AccountId}:workgroup/WAF*'
581+
# Glue Resources
582+
- Effect: Allow
583+
Action:
584+
- 'glue:GetTable'
585+
- 'glue:GetDatabase'
586+
- 'glue:UpdateDatabase'
587+
- 'glue:CreateDatabase'
588+
- 'glue:BatchCreatePartition'
589+
Resource:
590+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:catalog'
591+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/default'
592+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/${GlueAccessLogsDatabase}'
593+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:table/${GlueAccessLogsDatabase}/${GlueAppAccessLogsTable}'
594+
- !Ref 'AWS::NoValue'
595+
- !If
596+
- HttpFloodAthenaLogParser
597+
- PolicyName: AddAthenaPartitionsForWAFLog
598+
PolicyDocument:
599+
Statement:
600+
# S3 Resources
601+
- Effect: Allow
602+
Action:
603+
- 's3:GetObject'
604+
- 's3:PutObject'
605+
- 's3:GetBucketLocation'
606+
- 's3:ListBucket'
607+
- 's3:ListBucketMultipartUploads'
608+
- 's3:ListMultipartUploadParts'
609+
- 's3:AbortMultipartUpload'
610+
- 's3:CreateBucket'
611+
Resource:
612+
- !Sub 'arn:aws:s3:::${WafLogBucket}/athena_results/*'
613+
- !Sub 'arn:aws:s3:::${WafLogBucket}'
614+
- !Sub 'arn:aws:s3:::${WafLogBucket}/*'
615+
# Athena Resources
616+
- Effect: Allow
617+
Action:
618+
- 'athena:StartQueryExecution'
619+
Resource:
620+
- !Sub 'arn:aws:athena:${AWS::Region}:${AWS::AccountId}:workgroup/WAF*'
621+
# Glue Resources
622+
- Effect: Allow
623+
Action:
624+
- 'glue:GetTable'
625+
- 'glue:GetDatabase'
626+
- 'glue:UpdateDatabase'
627+
- 'glue:CreateDatabase'
628+
- 'glue:BatchCreatePartition'
629+
Resource:
630+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:catalog'
631+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/default'
632+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:database/${GlueAccessLogsDatabase}'
633+
- !Sub 'arn:aws:glue:${AWS::Region}:${AWS::AccountId}:table/${GlueAccessLogsDatabase}/${GlueWafAccessLogsTable}'
634+
- !Ref 'AWS::NoValue'
635+
- PolicyName: LogsAccess
636+
PolicyDocument:
637+
Statement:
638+
- Effect: Allow
639+
Action:
640+
- 'logs:CreateLogGroup'
641+
- 'logs:CreateLogStream'
642+
- 'logs:PutLogEvents'
643+
Resource:
644+
- !Sub 'arn:aws:logs:${AWS::Region}:${AWS::AccountId}:log-group:/aws/lambda/*AddAthenaPartitions*'
645+
479646
LambdaRoleReputationListsParser:
480647
Type: 'AWS::IAM::Role'
481648
Condition: ReputationListsProtectionActivated
@@ -625,6 +792,7 @@ Resources:
625792
- 's3:CreateBucket'
626793
- 's3:GetBucketNotification'
627794
- 's3:PutBucketNotification'
795+
- 's3:PutEncryptionConfiguration'
628796
Resource:
629797
- !Sub 'arn:aws:s3:::${AppAccessLogBucket}'
630798
- !If
@@ -671,7 +839,7 @@ Resources:
671839
- !Sub 'arn:aws:s3:::${WafLogBucket}/${ParentStackName}-waf_log_conf.json'
672840
- !Ref 'AWS::NoValue'
673841
- !If
674-
- ReputationListsProtectionActivated
842+
- CustomResourceLambdaAccess
675843
- PolicyName: LambdaAccess
676844
PolicyDocument:
677845
Statement:
@@ -853,3 +1021,11 @@ Outputs:
8531021

8541022
LambdaRoleCustomResourceArn:
8551023
Value: !GetAtt LambdaRoleCustomResource.Arn
1024+
1025+
LambdaRolePartitionS3LogsArn:
1026+
Value: !GetAtt LambdaRolePartitionS3Logs.Arn
1027+
Condition: ScannersProbesAthenaLogParser
1028+
1029+
LambdaRoleAddAthenaPartitionsArn:
1030+
Value: !GetAtt LambdaRoleAddAthenaPartitions.Arn
1031+
Condition: AthenaLogParser

0 commit comments

Comments
 (0)