-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathautoSecureWAF-template.yml
More file actions
279 lines (263 loc) · 10.1 KB
/
autoSecureWAF-template.yml
File metadata and controls
279 lines (263 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
# igarcia 2020-05
# Version 1.0.0
# Automation to Secure WAFv2 (Web application Firewall)
# Gets updates from GuardDuty (must be already configured) and blocks the CIDR /24 of attackers
# This Template creates Lambda triggered by GuardDuty Findings and another Lambda scheduled for cleanup
# Resources to create: Two Lambdas, Two CloudWatch Events, IAM Role, DynamoDB Table
# Resources to create: One IPset for CloudFront and One IPset for ALB, it WILL NOT ceate the WebACLs or Rules to not incur in costs
# The AWS Account should be already using GuardDuty
# IMPORTANT: The block will occur using IPset, MANUALLY you must create a Rule referencing the IPset in a WebACL and set priority 1
# AWS WAFv2
AWSTemplateFormatVersion: 2010-09-09
Description: Template to automate security changes on WAFv2
Metadata:
AWS::CloudFormation::Interface:
ParameterGroups:
-
Label:
default: "Stack Environment"
Parameters:
- TemplateAmbiente
-
Label:
default: "AutoSecureWAF Setup"
Parameters:
- pNumberIPs
- pDaysBlock
ParameterLabels: #Define Friendly Names
TemplateAmbiente:
default: "Value for CloudFormation Resources Env Tag"
pDaysBlock:
default: "Days blocked"
pNumberIPs:
default: "Max Number of IPs blocked"
Parameters: #Default Parameters Values
TemplateAmbiente:
Type: String
Description: "Tag Env to set on CloudFormation resources"
Default: Test
MaxLength: 10
MinLength: 2
AllowedPattern: "[A-Za-z0-9]+"
ConstraintDescription: "Set a simple Tag between 2 and 10 characters long without spaces or special characters"
pDaysBlock:
Type: Number
Description: "How many days should remain the offending IPs BLOCKED"
Default: 30
MinValue: 1
MaxValue: 365
ConstraintDescription: "Please set a number between 1 and 365"
pNumberIPs:
Type: Number
Description: "Max number of IPs to keep record, will use CIDR/24 of offending IPs"
Default: 100
MinValue: 1
MaxValue: 1000
ConstraintDescription: "Please set a number between 1 and 1000, IPset limit is 10000"
Conditions: # If in us-east-1 create IPset for CloudFront
CreateCloudFrontIPset: !Equals [!Ref "AWS::Region", 'us-east-1' ]
Resources:
TemplateIPsetRegional:
Type: AWS::WAFv2::IPSet
Properties:
Name: !Join [ "-", [ "AutoSecureWAF-IPset-Block-Regional", !Ref TemplateAmbiente ] ]
Description: !Join [ "-", [ "AutoSecureWAF-IPset-Block-Regional", !Ref TemplateAmbiente ] ]
Scope: REGIONAL
IPAddressVersion: IPV4
Addresses:
- 127.0.0.1/32
TemplateIPsetGlobal:
Type: AWS::WAFv2::IPSet
Condition: CreateCloudFrontIPset
Properties:
Name: !Join [ "-", [ "AutoSecureWAF-IPset-Block-Global", !Ref TemplateAmbiente ] ]
Description: !Join [ "-", [ "AutoSecureWAF-IPset-Block-Global", !Ref TemplateAmbiente ] ]
Scope: CLOUDFRONT
IPAddressVersion: IPV4
Addresses:
- 127.0.0.1/32
TemplateRole: #Role for Lambda
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Principal:
Service:
- "lambda.amazonaws.com"
Action:
- "sts:AssumeRole"
Description: Role to execute AutoSecureWAF
Policies:
-
PolicyName: !Join [ "-", [ "PolicyLambdaExec", !Ref TemplateAmbiente ] ]
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "logs:CreateLogGroup"
- "logs:CreateLogStream"
- "logs:PutLogEvents"
Resource: "*"
-
PolicyName: !Join [ "-", [ "PolicyLambdaWAFv2", !Ref TemplateAmbiente ] ]
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "wafv2:DeleteIPSet"
- "wafv2:GetIPSet"
- "wafv2:ListIPSets"
- "wafv2:CreateIPSet"
- "wafv2:UpdateIPSet"
Resource: "*"
-
PolicyName: !Join [ "-", [ "PolicyLambdaDynamoDB", !Ref TemplateAmbiente ] ]
PolicyDocument:
Version: "2012-10-17"
Statement:
-
Effect: "Allow"
Action:
- "dynamodb:BatchWriteItem"
- "dynamodb:PutItem"
- "dynamodb:DescribeTable"
- "dynamodb:DeleteItem"
- "dynamodb:GetItem"
- "dynamodb:Scan"
- "dynamodb:Query"
- "dynamodb:UpdateItem"
- "dynamodb:UpdateTable"
Resource: !Join [ "" , [ "arn:aws:dynamodb:*:*:table/", !Join [ "-", [ "AutoSecureWAFTable", !Ref TemplateAmbiente ] ] ] ]
RoleName: !Join [ "-", [ "RoleforAutoSecureWAF", !Ref TemplateAmbiente ] ]
Tags:
- Key: Env
Value: !Ref TemplateAmbiente
TemplateDynamoDBtable: #Tabla para almacenar IPs de IPset
Type: AWS::DynamoDB::Table
Properties:
AttributeDefinitions:
-
AttributeName: pk
AttributeType: S
BillingMode: PAY_PER_REQUEST
KeySchema:
-
AttributeName: pk
KeyType: HASH
TableName: !Join [ "-", [ "AutoSecureWAFTable", !Ref TemplateAmbiente ] ]
Tags:
-
Key: Env
Value: !Ref TemplateAmbiente
TemplateLambdaCleaner: #Lambda to Clean Up IPset
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Join [ "-", [ "higher-artifacts", !Ref "AWS::Region" ] ]
S3Key: "solutions/autosecurewaf-cleaner.zip"
Description: Clean up teh IPsets after the block period
Environment:
Variables:
ENVIRONMENT: !Ref TemplateAmbiente
REGION: !Ref "AWS::Region"
BLOCKDAYS: !Ref pDaysBlock
IPSETIDR: !Ref TemplateIPsetRegional
IPSETIDG: !If [ CreateCloudFrontIPset , !Ref TemplateIPsetGlobal, !Ref "AWS::Region"]
DDBTABLE: !Join [ "-", [ "AutoSecureWAFTable", !Ref TemplateAmbiente ] ]
FunctionName: !Join [ "-", [ "AutoSecureWAFLambda-cleaner", !Ref TemplateAmbiente ] ]
Role: !GetAtt TemplateRole.Arn
Timeout: 800
Handler: autosecurewaf-cleaner.lambda_handler
Runtime: python3.8
MemorySize: 256
Tags:
-
Key: Env
Value: !Ref TemplateAmbiente
TemplateEventLambdaCleaner: #Event to invoke Lambda Cleaner
Type: AWS::Events::Rule
Properties:
Description: Invoke Lambda for AutoSecureWAF Clean Up
Name: !Join [ "-", [ "AutoSecureWAF-cleanerEvent", !Ref TemplateAmbiente ] ]
ScheduleExpression: "rate(1 day)"
State: ENABLED
Targets:
-
Arn: !GetAtt TemplateLambdaCleaner.Arn
Id: !Join [ "-", [!Ref TemplateAmbiente, "AutoSecureWAFLambda-cleaner" ] ]
TemplatePermisoEventLambdaCleaner: #Relaciona permisos del Event con Lambda Cleaner
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt TemplateLambdaCleaner.Arn
Action: "lambda:InvokeFunction"
Principal: events.amazonaws.com
SourceArn: !GetAtt TemplateEventLambdaCleaner.Arn
TemplateLambda: #Lambda to Modify IPset
Type: AWS::Lambda::Function
Properties:
Code:
S3Bucket: !Join [ "-", [ "higher-artifacts", !Ref "AWS::Region" ] ]
S3Key: "solutions/autosecurewaf.zip"
Description: Updates IPsets with bad actors IPs from GuardDuty findings
Environment:
Variables:
ENVIRONMENT: !Ref TemplateAmbiente
REGION: !Ref "AWS::Region"
MAXIPS: !Ref pNumberIPs
IPSETIDR: !Ref TemplateIPsetRegional
IPSETIDG: !If [ CreateCloudFrontIPset , !Ref TemplateIPsetGlobal, !Ref "AWS::Region"]
DDBTABLE: !Join [ "-", [ "AutoSecureWAFTable", !Ref TemplateAmbiente ] ]
FunctionName: !Join [ "-", [ "AutoSecureWAFLambda", !Ref TemplateAmbiente ] ]
Role: !GetAtt TemplateRole.Arn
Timeout: 800
Handler: autosecurewaf.lambda_handler
Runtime: python3.8
MemorySize: 256
Tags:
-
Key: Env
Value: !Ref TemplateAmbiente
TemplateEventLambda: #Event to invoke Lambda
Type: AWS::Events::Rule
Properties:
Description: Invoke Lambda for AutoSecureWAF adding IPs to IPsets
Name: !Join [ "-", [ "AutoSecureWAFEvent", !Ref TemplateAmbiente ] ]
EventPattern: { "source": [ "aws.guardduty" ], "detail-type": [ "GuardDuty Finding" ], "detail": { "type": [ "Recon:EC2/PortProbeUnprotectedPort", "UnauthorizedAccess:EC2/SSHBruteForce", "UnauthorizedAccess:EC2/RDPBruteForce" ] } }
State: ENABLED
Targets:
-
Arn: !GetAtt TemplateLambda.Arn
Id: !Join [ "-", [!Ref TemplateAmbiente, "AutoSecureWAFLambda" ] ]
TemplatePermisoEventLambda: #Relaciona permisos del Event con Lambda
Type: AWS::Lambda::Permission
Properties:
FunctionName: !GetAtt TemplateLambda.Arn
Action: "lambda:InvokeFunction"
Principal: events.amazonaws.com
SourceArn: !GetAtt TemplateEventLambda.Arn
Outputs: #Outputs of the Template
IPsettoUseRegional:
Description: IPset to use in Regional WebACL Rule
Value: !Ref TemplateIPsetRegional
IPsettoUseGlobal:
Description: IPset to use in Global WebACL Rule
Value: !If [ CreateCloudFrontIPset , !Ref TemplateIPsetGlobal, "To be created"]
IPsToKeep:
Description: Max number of offendings IPs (CIDR/24) to keep in IPset
Value: !Ref pNumberIPs
DaysBlocked:
Description: Number of days to keep the IPs in IPset
Value: !Ref pDaysBlock
Note:
Description: Note
Value: For regions outside us-east-1, the IPset for CloudFormation will be created after the first Finding or in 1 day
Remember:
Description: Manual Action
Value: Go and create a WebACL and a BLOCK Rule referencing the IPset, for CloudFormation see if IPset is already created or wait 24 hours to automatic creation