lono 4.2.1 → 4.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +3 -0
- data/lib/lono/version.rb +1 -1
- data/lono.gemspec +5 -3
- metadata +3 -79
- data/spec/fixtures/cfn.json +0 -369
- data/spec/fixtures/cfn/stack-events-complete.json +0 -1080
- data/spec/fixtures/cfn/stack-events-in-progress.json +0 -1080
- data/spec/fixtures/cfn/stack-events-update-rollback-complete.json +0 -1086
- data/spec/fixtures/lono_project/.gitignore +0 -1
- data/spec/fixtures/lono_project/Gemfile +0 -3
- data/spec/fixtures/lono_project/Guardfile +0 -12
- data/spec/fixtures/lono_project/app/definitions/base.rb +0 -10
- data/spec/fixtures/lono_project/app/definitions/base/more.rb +0 -7
- data/spec/fixtures/lono_project/app/definitions/development.rb +0 -1
- data/spec/fixtures/lono_project/app/definitions/production.rb +0 -1
- data/spec/fixtures/lono_project/app/helpers/custom_helper.rb +0 -5
- data/spec/fixtures/lono_project/app/partials/security_group.yml +0 -10
- data/spec/fixtures/lono_project/app/partials/user_data/bootstrap.sh +0 -11
- data/spec/fixtures/lono_project/app/templates/example.yml +0 -50
- data/spec/fixtures/lono_project/config/params/base/example.txt +0 -3
- data/spec/fixtures/lono_project/config/params/development/example.txt +0 -1
- data/spec/fixtures/lono_project/config/params/production/example.txt +0 -1
- data/spec/fixtures/lono_project/config/settings.yml +0 -31
- data/spec/fixtures/lono_project/config/variables/base.rb +0 -3
- data/spec/fixtures/lono_project/config/variables/development.rb +0 -1
- data/spec/fixtures/lono_project/config/variables/production.rb +0 -1
- data/spec/fixtures/params/baseonly/params/base/network.txt +0 -1
- data/spec/fixtures/params/envonly/params/development/network.txt +0 -1
- data/spec/fixtures/params/overlay/params/base/network.txt +0 -1
- data/spec/fixtures/params/overlay/params/development/network.txt +0 -1
- data/spec/fixtures/raw_templates/aws-waf-security-automations.template +0 -1575
- data/spec/lib/lono/cfn/status_spec.rb +0 -77
- data/spec/lib/lono/cfn_spec.rb +0 -38
- data/spec/lib/lono/cli_spec.rb +0 -44
- data/spec/lib/lono/completion_spec.rb +0 -17
- data/spec/lib/lono/inspect_spec.rb +0 -11
- data/spec/lib/lono/param/generator_spec.rb +0 -56
- data/spec/lib/lono/param_spec.rb +0 -13
- data/spec/lib/lono/setting_spec.rb +0 -47
- data/spec/lib/lono/template/dsl_spec.rb +0 -59
- data/spec/lib/lono/template_spec.rb +0 -21
- data/spec/spec_helper.rb +0 -62
@@ -1 +0,0 @@
|
|
1
|
-
output
|
@@ -1,12 +0,0 @@
|
|
1
|
-
# A sample Guardfile
|
2
|
-
# More info at https://github.com/guard/guard#readme
|
3
|
-
|
4
|
-
guard "lono" do
|
5
|
-
watch(%r{^config/lono.rb$})
|
6
|
-
watch(%r{^templates/.*$})
|
7
|
-
end
|
8
|
-
|
9
|
-
# Commented out due to CF rate limiting
|
10
|
-
# guard "cloudformation", templates_path: "output" do
|
11
|
-
# watch(%r{^output/.+\.yml$})
|
12
|
-
# end
|
@@ -1 +0,0 @@
|
|
1
|
-
# resources that only exist in the development environment
|
@@ -1 +0,0 @@
|
|
1
|
-
# resources that only exist in the production environment
|
@@ -1,11 +0,0 @@
|
|
1
|
-
#!/bin/bash -lexv
|
2
|
-
|
3
|
-
exec > >(tee /var/log/user-data.log|logger -t user-data -s 2>/dev/console) 2>&1
|
4
|
-
|
5
|
-
# Lono.env=<%= Lono.env %>
|
6
|
-
# override_test=<%= @override_test %>
|
7
|
-
# self=<%= self.inspect %>
|
8
|
-
|
9
|
-
cat /proc/uptime | cut -f1 -d'.' > /tmp/time-to-boot
|
10
|
-
|
11
|
-
|
@@ -1,50 +0,0 @@
|
|
1
|
-
---
|
2
|
-
AWSTemplateFormatVersion: '2010-09-09'
|
3
|
-
Description: 'AWS CloudFormation Sample Template. A fixture for testing only. @_name: <%= @_name %>'
|
4
|
-
Parameters:
|
5
|
-
KeyName:
|
6
|
-
Description: Name of an existing EC2 KeyPair for SSH. <%= custom_helper %>
|
7
|
-
Type: AWS::EC2::KeyPair::KeyName
|
8
|
-
ConstraintDescription: must be the name of an existing EC2 KeyPair.
|
9
|
-
<% if @route53 %>
|
10
|
-
HostedZoneName:
|
11
|
-
Description: The route53 HostedZoneName. For example, "mydomain.com." Don't forget the period at the end.
|
12
|
-
Type: String
|
13
|
-
Subdomain:
|
14
|
-
Description: The subdomain of the dns entry. For example, hello -> hello.mydomain.com, hello is the subdomain.
|
15
|
-
Type: String
|
16
|
-
<% end %>
|
17
|
-
Resources:
|
18
|
-
EC2Instance:
|
19
|
-
Type: AWS::EC2::Instance
|
20
|
-
Properties:
|
21
|
-
InstanceType:
|
22
|
-
Ref: InstanceType
|
23
|
-
SecurityGroups:
|
24
|
-
- Ref: InstanceSecurityGroup
|
25
|
-
KeyName:
|
26
|
-
Ref: KeyName
|
27
|
-
UserData:
|
28
|
-
Fn::Base64: !Sub |
|
29
|
-
<%= partial("user_data/bootstrap.sh", {}, indent: 10) %>
|
30
|
-
ImageId:
|
31
|
-
Fn::FindInMap:
|
32
|
-
- AWSRegionArch2AMI
|
33
|
-
- Ref: AWS::Region
|
34
|
-
- Fn::FindInMap:
|
35
|
-
- AWSInstanceType2Arch
|
36
|
-
- Ref: InstanceType
|
37
|
-
- Arch
|
38
|
-
<%= partial("security_group", desc: "Enable SSH access via port 22", port: "22") %>
|
39
|
-
<% if @route53 %>
|
40
|
-
DnsRecord:
|
41
|
-
Type: AWS::Route53::RecordSet
|
42
|
-
Properties:
|
43
|
-
HostedZoneName: !Ref 'HostedZoneName'
|
44
|
-
Comment: DNS name for my instance.
|
45
|
-
Name: !Join ['', [!Ref 'Subdomain', ., !Ref 'HostedZoneName']]
|
46
|
-
Type: CNAME
|
47
|
-
TTL: '900'
|
48
|
-
ResourceRecords:
|
49
|
-
- !GetAtt EC2Instance.PublicIp
|
50
|
-
<% end %>
|
@@ -1 +0,0 @@
|
|
1
|
-
InstanceType=t2.small
|
@@ -1 +0,0 @@
|
|
1
|
-
InstanceType=t2.large
|
@@ -1,31 +0,0 @@
|
|
1
|
-
# More info: http://lono.cloud/docs/settings/
|
2
|
-
# The base config is specially treated. It gets included the other environments automatically.
|
3
|
-
# Yaml also directly supports merging with & and <<* syntax but doing it automatically
|
4
|
-
# for a cleaner syntax.
|
5
|
-
base:
|
6
|
-
# If s3_folder is set then the generated templates and app/scripts will automatically
|
7
|
-
# be uploaded to s3.
|
8
|
-
# There are 2 formats for s3_folder:
|
9
|
-
# Format 1:
|
10
|
-
# s3_folder: mybucket/path/to/folder # simple string
|
11
|
-
# Format 2:
|
12
|
-
# s3_folder: # Hash options in order to support different AWS_PROFILEs
|
13
|
-
# default: mybucket/folder
|
14
|
-
# aws_profile1: mybucket/folder
|
15
|
-
# aws_profile2: another-bucket/storage/folder
|
16
|
-
# stack_name_suffix: random # tack on a 3 char random string at the end of the stack name
|
17
|
-
# for lono cfn create
|
18
|
-
|
19
|
-
development:
|
20
|
-
# cluster: dev
|
21
|
-
# When you have AWS_PROFILE set to one of these values, ufo will switch to the desired
|
22
|
-
# environment. This prevents you from switching AWS_PROFILE, forgetting to
|
23
|
-
# also switch UFO_ENV, and accidentally deploying to production vs development.
|
24
|
-
# aws_profiles:
|
25
|
-
# - dev_profile1
|
26
|
-
# - dev_profile2
|
27
|
-
|
28
|
-
production:
|
29
|
-
# cluster: prod
|
30
|
-
# aws_profiles:
|
31
|
-
# - prod_profile
|
@@ -1 +0,0 @@
|
|
1
|
-
@override_test = "overridden-by-development"
|
@@ -1 +0,0 @@
|
|
1
|
-
@override_test = "overridden-by-production"
|
@@ -1 +0,0 @@
|
|
1
|
-
baseonly=foo
|
@@ -1 +0,0 @@
|
|
1
|
-
envonly=bar
|
@@ -1 +0,0 @@
|
|
1
|
-
overlay=1
|
@@ -1 +0,0 @@
|
|
1
|
-
overlay=2
|
@@ -1,1575 +0,0 @@
|
|
1
|
-
{
|
2
|
-
"AWSTemplateFormatVersion": "2010-09-09",
|
3
|
-
"Description": "(SO0006-CloudFront) - AWS WAF Security Automations: This AWS CloudFormation template helps you provision the AWS WAF Security Automations stack without worrying about creating and configuring the underlying AWS infrastructure. **WARNING** This template creates an AWS Lambda function, an AWS WAF Web ACL, an Amazon S3 bucket, and an Amazon CloudWatch custom metric. You will be billed for the AWS resources used if you create a stack from this template. **NOTICE** Copyright 2016 Amazon.com, Inc. or its affiliates. All Rights Reserved. Licensed under the Amazon Software License (the License). You may not use this file except in compliance with the License. A copy of the License is located at http://aws.amazon.com/asl/ or in the license file accompanying this file. This file is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions and limitations under the License.",
|
4
|
-
"Metadata": {
|
5
|
-
"AWS::CloudFormation::Interface": {
|
6
|
-
"ParameterGroups": [{
|
7
|
-
"Label": {
|
8
|
-
"default": "Protection List"
|
9
|
-
},
|
10
|
-
"Parameters": ["SqlInjectionProtectionParam", "CrossSiteScriptingProtectionParam", "ActivateHttpFloodProtectionParam", "ActivateScansProbesProtectionParam", "ActivateReputationListsProtectionParam", "ActivateBadBotProtectionParam"]
|
11
|
-
}, {
|
12
|
-
"Label": {
|
13
|
-
"default": "Setting"
|
14
|
-
},
|
15
|
-
"Parameters": ["CloudFrontAccessLogBucket"]
|
16
|
-
}, {
|
17
|
-
"Label": {
|
18
|
-
"default": "Advanced Setting"
|
19
|
-
},
|
20
|
-
"Parameters": ["RequestThreshold", "ErrorThreshold", "WAFBlockPeriod"]
|
21
|
-
}, {
|
22
|
-
"Label": {
|
23
|
-
"default": "Anonymous Metrics Request"
|
24
|
-
},
|
25
|
-
"Parameters": ["SendAnonymousUsageData"]
|
26
|
-
}],
|
27
|
-
"ParameterLabels": {
|
28
|
-
"SqlInjectionProtectionParam": {
|
29
|
-
"default": "Activate SQL Injection Protection"
|
30
|
-
},
|
31
|
-
"CrossSiteScriptingProtectionParam": {
|
32
|
-
"default": "Activate Cross-site Scripting Protection"
|
33
|
-
},
|
34
|
-
"ActivateHttpFloodProtectionParam": {
|
35
|
-
"default": "Activate HTTP Flood Protection"
|
36
|
-
},
|
37
|
-
"ActivateScansProbesProtectionParam": {
|
38
|
-
"default": "Activate Scanner & Probe Protection"
|
39
|
-
},
|
40
|
-
"ActivateReputationListsProtectionParam": {
|
41
|
-
"default": "Activate Reputation List Protection"
|
42
|
-
},
|
43
|
-
"ActivateBadBotProtectionParam": {
|
44
|
-
"default": "Activate Bad Bot Protection"
|
45
|
-
},
|
46
|
-
"CloudFrontAccessLogBucket": {
|
47
|
-
"default": "CloudFront Access Log Bucket Name"
|
48
|
-
},
|
49
|
-
"SendAnonymousUsageData": {
|
50
|
-
"default": "Send Anonymous Usage Data"
|
51
|
-
},
|
52
|
-
"RequestThreshold": {
|
53
|
-
"default": "Request Threshold"
|
54
|
-
},
|
55
|
-
"ErrorThreshold": {
|
56
|
-
"default": "Error Threshold"
|
57
|
-
},
|
58
|
-
"WAFBlockPeriod": {
|
59
|
-
"default": "WAF Block Period"
|
60
|
-
}
|
61
|
-
}
|
62
|
-
}
|
63
|
-
},
|
64
|
-
|
65
|
-
|
66
|
-
"Parameters": {
|
67
|
-
"SqlInjectionProtectionParam": {
|
68
|
-
"Type": "String",
|
69
|
-
"Default": "yes",
|
70
|
-
"AllowedValues": ["yes", "no"],
|
71
|
-
"Description": "Choose yes to enable the component designed to block common SQL injection attacks."
|
72
|
-
},
|
73
|
-
"CrossSiteScriptingProtectionParam": {
|
74
|
-
"Type": "String",
|
75
|
-
"Default": "yes",
|
76
|
-
"AllowedValues": ["yes", "no"],
|
77
|
-
"Description": "Choose yes to enable the component designed to block common XSS attacks."
|
78
|
-
},
|
79
|
-
"ActivateHttpFloodProtectionParam": {
|
80
|
-
"Type": "String",
|
81
|
-
"Default": "yes",
|
82
|
-
"AllowedValues": ["yes", "no"],
|
83
|
-
"Description": "Choose yes to enable the component designed to block HTTP flood attacks."
|
84
|
-
},
|
85
|
-
"ActivateScansProbesProtectionParam": {
|
86
|
-
"Type": "String",
|
87
|
-
"Default": "yes",
|
88
|
-
"AllowedValues": ["yes", "no"],
|
89
|
-
"Description": "Choose yes to enable the component designed to block scanners and probes."
|
90
|
-
},
|
91
|
-
"ActivateReputationListsProtectionParam": {
|
92
|
-
"Type": "String",
|
93
|
-
"Default": "yes",
|
94
|
-
"AllowedValues": ["yes", "no"],
|
95
|
-
"Description": "Choose yes to block requests from IP addresses on third-party reputation lists (supported lists: spamhaus, torproject, and emergingthreats)."
|
96
|
-
},
|
97
|
-
"ActivateBadBotProtectionParam": {
|
98
|
-
"Type": "String",
|
99
|
-
"Default": "yes",
|
100
|
-
"AllowedValues": ["yes", "no"],
|
101
|
-
"Description": "Choose yes to enable the component designed to block bad bots and content scrapers."
|
102
|
-
},
|
103
|
-
"CloudFrontAccessLogBucket": {
|
104
|
-
"Type": "String",
|
105
|
-
"Default": "",
|
106
|
-
"AllowedPattern": "(^$|^([a-z]|(\\d(?!\\d{0,2}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})))([a-z\\d]|(\\.(?!(\\.|-)))|(-(?!\\.))){1,61}[a-z\\d]$)",
|
107
|
-
"Description": "Enter a name for the Amazon S3 bucket where you want to store Amazon CloudFront access logs. This can be the name of either an existing S3 bucket, or a new bucket that the template will create during stack launch (if it does not find a matching bucket name). The solution will modify the bucket’s notification configuration to trigger the Log Parser AWS Lambda function whenever a new log file is saved in this bucket. More about bucket name restriction here: http://amzn.to/1p1YlU5"
|
108
|
-
},
|
109
|
-
"SendAnonymousUsageData": {
|
110
|
-
"Type": "String",
|
111
|
-
"Default": "yes",
|
112
|
-
"AllowedValues": ["yes", "no"],
|
113
|
-
"Description": "Send anonymous data to AWS to help us understand solution usage across our customer base as a whole. To opt out of this feature, select No."
|
114
|
-
},
|
115
|
-
"RequestThreshold": {
|
116
|
-
"Type": "Number",
|
117
|
-
"Default": "400",
|
118
|
-
"Description": "If you chose yes for the Activate HTTP Flood Protection parameter, enter the maximum acceptable requests per minute per IP address. If you chose to deactivate this protection, ignore this parameter."
|
119
|
-
},
|
120
|
-
"ErrorThreshold": {
|
121
|
-
"Type": "Number",
|
122
|
-
"Default": "50",
|
123
|
-
"Description": "If you chose yes for the Activate Scanners & Probes Protection parameter, enter the maximum acceptable bad requests per minute per IP. If you chose to deactivate Scanners & Probes protection, ignore this parameter."
|
124
|
-
},
|
125
|
-
"WAFBlockPeriod": {
|
126
|
-
"Type": "Number",
|
127
|
-
"Default": "240",
|
128
|
-
"Description": "If you chose yes for the Activate HTTP Flood Protection or Activate Scanners & Probes Protection parameters, enter the period (in minutes) to block applicable IP addresses. If you chose to deactivate both types of protection, ignore this parameter."
|
129
|
-
}
|
130
|
-
},
|
131
|
-
|
132
|
-
|
133
|
-
"Conditions": {
|
134
|
-
"SqlInjectionProtectionActivated": {
|
135
|
-
"Fn::Equals": [{
|
136
|
-
"Ref": "SqlInjectionProtectionParam"
|
137
|
-
}, "yes"]
|
138
|
-
},
|
139
|
-
"CrossSiteScriptingProtectionActivated": {
|
140
|
-
"Fn::Equals": [{
|
141
|
-
"Ref": "CrossSiteScriptingProtectionParam"
|
142
|
-
}, "yes"]
|
143
|
-
},
|
144
|
-
"HttpFloodProtectionActivated": {
|
145
|
-
"Fn::Equals": [{
|
146
|
-
"Ref": "ActivateHttpFloodProtectionParam"
|
147
|
-
}, "yes"]
|
148
|
-
},
|
149
|
-
"ScansProbesProtectionActivated": {
|
150
|
-
"Fn::Equals": [{
|
151
|
-
"Ref": "ActivateScansProbesProtectionParam"
|
152
|
-
}, "yes"]
|
153
|
-
},
|
154
|
-
"ReputationListsProtectionActivated": {
|
155
|
-
"Fn::Equals": [{
|
156
|
-
"Ref": "ActivateReputationListsProtectionParam"
|
157
|
-
}, "yes"]
|
158
|
-
},
|
159
|
-
"BadBotProtectionActivated": {
|
160
|
-
"Fn::Equals": [{
|
161
|
-
"Ref": "ActivateBadBotProtectionParam"
|
162
|
-
}, "yes"]
|
163
|
-
},
|
164
|
-
"LogParserActivated": {
|
165
|
-
"Fn::Or": [{
|
166
|
-
"Condition": "HttpFloodProtectionActivated"
|
167
|
-
}, {
|
168
|
-
"Condition": "ScansProbesProtectionActivated"
|
169
|
-
}]
|
170
|
-
},
|
171
|
-
"CreateWebACL": {
|
172
|
-
"Fn::Or": [{
|
173
|
-
"Condition": "SqlInjectionProtectionActivated"
|
174
|
-
}, {
|
175
|
-
"Condition": "CrossSiteScriptingProtectionActivated"
|
176
|
-
}, {
|
177
|
-
"Condition": "LogParserActivated"
|
178
|
-
}, {
|
179
|
-
"Condition": "ReputationListsProtectionActivated"
|
180
|
-
}, {
|
181
|
-
"Condition": "BadBotProtectionActivated"
|
182
|
-
}]
|
183
|
-
}
|
184
|
-
},
|
185
|
-
"Resources": {
|
186
|
-
"WAFWhitelistSet": {
|
187
|
-
"Type": "AWS::WAF::IPSet",
|
188
|
-
"Condition": "CreateWebACL",
|
189
|
-
"Properties": {
|
190
|
-
"Name": {
|
191
|
-
"Fn::Join": [" - ", [{
|
192
|
-
"Ref": "AWS::StackName"
|
193
|
-
}, "Whitelist Set"]]
|
194
|
-
}
|
195
|
-
}
|
196
|
-
},
|
197
|
-
"WAFBlacklistSet": {
|
198
|
-
"Type": "AWS::WAF::IPSet",
|
199
|
-
"Condition": "LogParserActivated",
|
200
|
-
"Properties": {
|
201
|
-
"Name": {
|
202
|
-
"Fn::Join": [" - ", [{
|
203
|
-
"Ref": "AWS::StackName"
|
204
|
-
}, "Blacklist Set"]]
|
205
|
-
}
|
206
|
-
}
|
207
|
-
},
|
208
|
-
"WAFAutoBlockSet": {
|
209
|
-
"Type": "AWS::WAF::IPSet",
|
210
|
-
"Condition": "LogParserActivated",
|
211
|
-
"Properties": {
|
212
|
-
"Name": {
|
213
|
-
"Fn::Join": [" - ", [{
|
214
|
-
"Ref": "AWS::StackName"
|
215
|
-
}, "Auto Block Set"]]
|
216
|
-
}
|
217
|
-
}
|
218
|
-
},
|
219
|
-
"WAFReputationListsSet1": {
|
220
|
-
"Type": "AWS::WAF::IPSet",
|
221
|
-
"Condition": "ReputationListsProtectionActivated",
|
222
|
-
"Properties": {
|
223
|
-
"Name": {
|
224
|
-
"Fn::Join": [" - ", [{
|
225
|
-
"Ref": "AWS::StackName"
|
226
|
-
}, "IP Reputation Lists Set #1"]]
|
227
|
-
}
|
228
|
-
}
|
229
|
-
},
|
230
|
-
"WAFReputationListsSet2": {
|
231
|
-
"Type": "AWS::WAF::IPSet",
|
232
|
-
"Condition": "ReputationListsProtectionActivated",
|
233
|
-
"Properties": {
|
234
|
-
"Name": {
|
235
|
-
"Fn::Join": [" - ", [{
|
236
|
-
"Ref": "AWS::StackName"
|
237
|
-
}, "IP Reputation Lists Set #2"]]
|
238
|
-
}
|
239
|
-
}
|
240
|
-
},
|
241
|
-
"WAFBadBotSet": {
|
242
|
-
"Type": "AWS::WAF::IPSet",
|
243
|
-
"Condition": "BadBotProtectionActivated",
|
244
|
-
"Properties": {
|
245
|
-
"Name": {
|
246
|
-
"Fn::Join": [" - ", [{
|
247
|
-
"Ref": "AWS::StackName"
|
248
|
-
}, "IP Bad Bot Set"]]
|
249
|
-
}
|
250
|
-
}
|
251
|
-
},
|
252
|
-
"WAFSqlInjectionDetection": {
|
253
|
-
"Type": "AWS::WAF::SqlInjectionMatchSet",
|
254
|
-
"Condition": "SqlInjectionProtectionActivated",
|
255
|
-
"Properties": {
|
256
|
-
"Name": {
|
257
|
-
"Fn::Join": [" - ", [{
|
258
|
-
"Ref": "AWS::StackName"
|
259
|
-
}, "SQL injection Detection"]]
|
260
|
-
},
|
261
|
-
"SqlInjectionMatchTuples": [{
|
262
|
-
"FieldToMatch": {
|
263
|
-
"Type": "QUERY_STRING"
|
264
|
-
},
|
265
|
-
"TextTransformation": "URL_DECODE"
|
266
|
-
}, {
|
267
|
-
"FieldToMatch": {
|
268
|
-
"Type": "QUERY_STRING"
|
269
|
-
},
|
270
|
-
"TextTransformation": "HTML_ENTITY_DECODE"
|
271
|
-
}, {
|
272
|
-
"FieldToMatch": {
|
273
|
-
"Type": "BODY"
|
274
|
-
},
|
275
|
-
"TextTransformation": "URL_DECODE"
|
276
|
-
}, {
|
277
|
-
"FieldToMatch": {
|
278
|
-
"Type": "BODY"
|
279
|
-
},
|
280
|
-
"TextTransformation": "HTML_ENTITY_DECODE"
|
281
|
-
}, {
|
282
|
-
"FieldToMatch": {
|
283
|
-
"Type": "URI"
|
284
|
-
},
|
285
|
-
"TextTransformation": "URL_DECODE"
|
286
|
-
}, {
|
287
|
-
"FieldToMatch": {
|
288
|
-
"Type": "URI"
|
289
|
-
},
|
290
|
-
"TextTransformation": "HTML_ENTITY_DECODE"
|
291
|
-
}]
|
292
|
-
}
|
293
|
-
},
|
294
|
-
"WAFXssDetection": {
|
295
|
-
"Type": "AWS::WAF::XssMatchSet",
|
296
|
-
"Condition": "CrossSiteScriptingProtectionActivated",
|
297
|
-
"Properties": {
|
298
|
-
"Name": {
|
299
|
-
"Fn::Join": [" - ", [{
|
300
|
-
"Ref": "AWS::StackName"
|
301
|
-
}, "XSS Detection Detection"]]
|
302
|
-
},
|
303
|
-
"XssMatchTuples": [{
|
304
|
-
"FieldToMatch": {
|
305
|
-
"Type": "QUERY_STRING"
|
306
|
-
},
|
307
|
-
"TextTransformation": "URL_DECODE"
|
308
|
-
}, {
|
309
|
-
"FieldToMatch": {
|
310
|
-
"Type": "QUERY_STRING"
|
311
|
-
},
|
312
|
-
"TextTransformation": "HTML_ENTITY_DECODE"
|
313
|
-
}, {
|
314
|
-
"FieldToMatch": {
|
315
|
-
"Type": "BODY"
|
316
|
-
},
|
317
|
-
"TextTransformation": "URL_DECODE"
|
318
|
-
}, {
|
319
|
-
"FieldToMatch": {
|
320
|
-
"Type": "BODY"
|
321
|
-
},
|
322
|
-
"TextTransformation": "HTML_ENTITY_DECODE"
|
323
|
-
}, {
|
324
|
-
"FieldToMatch": {
|
325
|
-
"Type": "URI"
|
326
|
-
},
|
327
|
-
"TextTransformation": "URL_DECODE"
|
328
|
-
}, {
|
329
|
-
"FieldToMatch": {
|
330
|
-
"Type": "URI"
|
331
|
-
},
|
332
|
-
"TextTransformation": "HTML_ENTITY_DECODE"
|
333
|
-
}]
|
334
|
-
}
|
335
|
-
},
|
336
|
-
"WAFWhitelistRule": {
|
337
|
-
"Type": "AWS::WAF::Rule",
|
338
|
-
"Condition": "CreateWebACL",
|
339
|
-
"DependsOn": "WAFWhitelistSet",
|
340
|
-
"Properties": {
|
341
|
-
"Name": {
|
342
|
-
"Fn::Join": [" - ", [{
|
343
|
-
"Ref": "AWS::StackName"
|
344
|
-
}, "Whitelist Rule"]]
|
345
|
-
},
|
346
|
-
"MetricName": "SecurityAutomationsWhitelistRule",
|
347
|
-
"Predicates": [{
|
348
|
-
"DataId": {
|
349
|
-
"Ref": "WAFWhitelistSet"
|
350
|
-
},
|
351
|
-
"Negated": false,
|
352
|
-
"Type": "IPMatch"
|
353
|
-
}]
|
354
|
-
}
|
355
|
-
},
|
356
|
-
"WAFBlacklistRule": {
|
357
|
-
"Type": "AWS::WAF::Rule",
|
358
|
-
"Condition": "LogParserActivated",
|
359
|
-
"DependsOn": "WAFBlacklistSet",
|
360
|
-
"Properties": {
|
361
|
-
"Name": {
|
362
|
-
"Fn::Join": [" - ", [{
|
363
|
-
"Ref": "AWS::StackName"
|
364
|
-
}, "Blacklist Rule"]]
|
365
|
-
},
|
366
|
-
"MetricName": "SecurityAutomationsBlacklistRule",
|
367
|
-
"Predicates": [{
|
368
|
-
"DataId": {
|
369
|
-
"Ref": "WAFBlacklistSet"
|
370
|
-
},
|
371
|
-
"Negated": false,
|
372
|
-
"Type": "IPMatch"
|
373
|
-
}]
|
374
|
-
}
|
375
|
-
},
|
376
|
-
"WAFAutoBlockRule": {
|
377
|
-
"Type": "AWS::WAF::Rule",
|
378
|
-
"Condition": "LogParserActivated",
|
379
|
-
"DependsOn": "WAFAutoBlockSet",
|
380
|
-
"Properties": {
|
381
|
-
"Name": {
|
382
|
-
"Fn::Join": [" - ", [{
|
383
|
-
"Ref": "AWS::StackName"
|
384
|
-
}, "Auto Block Rule"]]
|
385
|
-
},
|
386
|
-
"MetricName": "SecurityAutomationsAutoBlockRule",
|
387
|
-
"Predicates": [{
|
388
|
-
"DataId": {
|
389
|
-
"Ref": "WAFAutoBlockSet"
|
390
|
-
},
|
391
|
-
"Negated": false,
|
392
|
-
"Type": "IPMatch"
|
393
|
-
}]
|
394
|
-
}
|
395
|
-
},
|
396
|
-
"WAFIPReputationListsRule1": {
|
397
|
-
"Type": "AWS::WAF::Rule",
|
398
|
-
"Condition": "ReputationListsProtectionActivated",
|
399
|
-
"DependsOn": "WAFReputationListsSet1",
|
400
|
-
"Properties": {
|
401
|
-
"Name": {
|
402
|
-
"Fn::Join": [" - ", [{
|
403
|
-
"Ref": "AWS::StackName"
|
404
|
-
}, "WAF IP Reputation Lists Rule #1"]]
|
405
|
-
},
|
406
|
-
"MetricName": "SecurityAutomationsIPReputationListsRule1",
|
407
|
-
"Predicates": [{
|
408
|
-
"DataId": {
|
409
|
-
"Ref": "WAFReputationListsSet1"
|
410
|
-
},
|
411
|
-
"Type": "IPMatch",
|
412
|
-
"Negated": "false"
|
413
|
-
}]
|
414
|
-
}
|
415
|
-
},
|
416
|
-
"WAFIPReputationListsRule2": {
|
417
|
-
"Type": "AWS::WAF::Rule",
|
418
|
-
"Condition": "ReputationListsProtectionActivated",
|
419
|
-
"DependsOn": "WAFReputationListsSet2",
|
420
|
-
"Properties": {
|
421
|
-
"Name": {
|
422
|
-
"Fn::Join": [" - ", [{
|
423
|
-
"Ref": "AWS::StackName"
|
424
|
-
}, "WAF IP Reputation Lists Rule #2"]]
|
425
|
-
},
|
426
|
-
"MetricName": "SecurityAutomationsIPReputationListsRule2",
|
427
|
-
"Predicates": [{
|
428
|
-
"DataId": {
|
429
|
-
"Ref": "WAFReputationListsSet2"
|
430
|
-
},
|
431
|
-
"Type": "IPMatch",
|
432
|
-
"Negated": "false"
|
433
|
-
}]
|
434
|
-
}
|
435
|
-
},
|
436
|
-
"WAFBadBotRule": {
|
437
|
-
"Type": "AWS::WAF::Rule",
|
438
|
-
"Condition": "BadBotProtectionActivated",
|
439
|
-
"DependsOn": "WAFBadBotSet",
|
440
|
-
"Properties": {
|
441
|
-
"Name": {
|
442
|
-
"Fn::Join": [" - ", [{
|
443
|
-
"Ref": "AWS::StackName"
|
444
|
-
}, "Bad Bot Rule"]]
|
445
|
-
},
|
446
|
-
"MetricName": "SecurityAutomationsBadBotRule",
|
447
|
-
"Predicates": [{
|
448
|
-
"DataId": {
|
449
|
-
"Ref": "WAFBadBotSet"
|
450
|
-
},
|
451
|
-
"Type": "IPMatch",
|
452
|
-
"Negated": "false"
|
453
|
-
}]
|
454
|
-
}
|
455
|
-
},
|
456
|
-
"WAFSqlInjectionRule": {
|
457
|
-
"Type": "AWS::WAF::Rule",
|
458
|
-
"Condition": "SqlInjectionProtectionActivated",
|
459
|
-
"DependsOn": "WAFSqlInjectionDetection",
|
460
|
-
"Properties": {
|
461
|
-
"Name": {
|
462
|
-
"Fn::Join": [" - ", [{
|
463
|
-
"Ref": "AWS::StackName"
|
464
|
-
}, "SQL Injection Rule"]]
|
465
|
-
},
|
466
|
-
"MetricName": "SecurityAutomationsSqlInjectionRule",
|
467
|
-
"Predicates": [{
|
468
|
-
"DataId": {
|
469
|
-
"Ref": "WAFSqlInjectionDetection"
|
470
|
-
},
|
471
|
-
"Negated": false,
|
472
|
-
"Type": "SqlInjectionMatch"
|
473
|
-
}]
|
474
|
-
}
|
475
|
-
},
|
476
|
-
"WAFXssRule": {
|
477
|
-
"Type": "AWS::WAF::Rule",
|
478
|
-
"Condition": "CrossSiteScriptingProtectionActivated",
|
479
|
-
"DependsOn": "WAFXssDetection",
|
480
|
-
"Properties": {
|
481
|
-
"Name": {
|
482
|
-
"Fn::Join": [" - ", [{
|
483
|
-
"Ref": "AWS::StackName"
|
484
|
-
}, "XSS Rule"]]
|
485
|
-
},
|
486
|
-
"MetricName": "SecurityAutomationsXssRule",
|
487
|
-
"Predicates": [{
|
488
|
-
"DataId": {
|
489
|
-
"Ref": "WAFXssDetection"
|
490
|
-
},
|
491
|
-
"Negated": false,
|
492
|
-
"Type": "XssMatch"
|
493
|
-
}]
|
494
|
-
}
|
495
|
-
},
|
496
|
-
"WAFWebACL": {
|
497
|
-
"Type": "AWS::WAF::WebACL",
|
498
|
-
"Condition": "CreateWebACL",
|
499
|
-
"DependsOn": ["WAFWhitelistRule"],
|
500
|
-
"Properties": {
|
501
|
-
"Name": {
|
502
|
-
"Ref": "AWS::StackName"
|
503
|
-
},
|
504
|
-
"DefaultAction": {
|
505
|
-
"Type": "ALLOW"
|
506
|
-
},
|
507
|
-
"MetricName": "SecurityAutomationsMaliciousRequesters",
|
508
|
-
"Rules": [{
|
509
|
-
"Action": {
|
510
|
-
"Type": "ALLOW"
|
511
|
-
},
|
512
|
-
"Priority": 10,
|
513
|
-
"RuleId": {
|
514
|
-
"Ref": "WAFWhitelistRule"
|
515
|
-
}
|
516
|
-
}]
|
517
|
-
}
|
518
|
-
},
|
519
|
-
"LambdaRoleLogParser": {
|
520
|
-
"Type": "AWS::IAM::Role",
|
521
|
-
"Condition": "LogParserActivated",
|
522
|
-
"Properties": {
|
523
|
-
"AssumeRolePolicyDocument": {
|
524
|
-
"Version": "2012-10-17",
|
525
|
-
"Statement": [{
|
526
|
-
"Effect": "Allow",
|
527
|
-
"Principal": {
|
528
|
-
"Service": ["lambda.amazonaws.com"]
|
529
|
-
},
|
530
|
-
"Action": ["sts:AssumeRole"]
|
531
|
-
}]
|
532
|
-
},
|
533
|
-
"Path": "/",
|
534
|
-
"Policies": [{
|
535
|
-
"PolicyName": "S3Access",
|
536
|
-
"PolicyDocument": {
|
537
|
-
"Version": "2012-10-17",
|
538
|
-
"Statement": [{
|
539
|
-
"Effect": "Allow",
|
540
|
-
"Action": "s3:GetObject",
|
541
|
-
"Resource": {
|
542
|
-
"Fn::Join": ["", ["arn:aws:s3:::", {
|
543
|
-
"Ref": "CloudFrontAccessLogBucket"
|
544
|
-
}, "/*"]]
|
545
|
-
}
|
546
|
-
}]
|
547
|
-
}
|
548
|
-
}, {
|
549
|
-
"PolicyName": "S3AccessPut",
|
550
|
-
"PolicyDocument": {
|
551
|
-
"Version": "2012-10-17",
|
552
|
-
"Statement": [{
|
553
|
-
"Effect": "Allow",
|
554
|
-
"Action": "s3:PutObject",
|
555
|
-
"Resource": {
|
556
|
-
"Fn::Join": ["", ["arn:aws:s3:::", {
|
557
|
-
"Ref": "CloudFrontAccessLogBucket"
|
558
|
-
}, "/aws-waf-security-automations-current-blocked-ips.json"]]
|
559
|
-
}
|
560
|
-
}]
|
561
|
-
}
|
562
|
-
}, {
|
563
|
-
"PolicyName": "WAFGetChangeToken",
|
564
|
-
"PolicyDocument": {
|
565
|
-
"Statement": [{
|
566
|
-
"Effect": "Allow",
|
567
|
-
"Action": "waf:GetChangeToken",
|
568
|
-
"Resource": "*"
|
569
|
-
}]
|
570
|
-
}
|
571
|
-
}, {
|
572
|
-
"PolicyName": "WAFGetAndUpdateIPSet",
|
573
|
-
"PolicyDocument": {
|
574
|
-
"Statement": [{
|
575
|
-
"Effect": "Allow",
|
576
|
-
"Action": [
|
577
|
-
"waf:GetIPSet",
|
578
|
-
"waf:UpdateIPSet"
|
579
|
-
],
|
580
|
-
"Resource": [{
|
581
|
-
"Fn::Join": [
|
582
|
-
"", [
|
583
|
-
"arn:aws:waf::", {
|
584
|
-
"Ref": "AWS::AccountId"
|
585
|
-
},
|
586
|
-
":ipset/", {
|
587
|
-
"Ref": "WAFBlacklistSet"
|
588
|
-
}
|
589
|
-
]
|
590
|
-
]
|
591
|
-
}, {
|
592
|
-
"Fn::Join": [
|
593
|
-
"", [
|
594
|
-
"arn:aws:waf::", {
|
595
|
-
"Ref": "AWS::AccountId"
|
596
|
-
},
|
597
|
-
":ipset/", {
|
598
|
-
"Ref": "WAFAutoBlockSet"
|
599
|
-
}
|
600
|
-
]
|
601
|
-
]
|
602
|
-
}]
|
603
|
-
}]
|
604
|
-
}
|
605
|
-
}, {
|
606
|
-
"PolicyName": "LogsAccess",
|
607
|
-
"PolicyDocument": {
|
608
|
-
"Version": "2012-10-17",
|
609
|
-
"Statement": [{
|
610
|
-
"Effect": "Allow",
|
611
|
-
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
|
612
|
-
"Resource": { "Fn::Join" : [":", ["arn:aws:logs",{"Ref" : "AWS::Region"},{ "Ref" : "AWS::AccountId" }, "log-group:/aws/lambda/*" ]]}
|
613
|
-
}]
|
614
|
-
}
|
615
|
-
}, {
|
616
|
-
"PolicyName": "CloudWatchAccess",
|
617
|
-
"PolicyDocument": {
|
618
|
-
"Version": "2012-10-17",
|
619
|
-
"Statement": [{
|
620
|
-
"Effect": "Allow",
|
621
|
-
"Action": "cloudwatch:GetMetricStatistics",
|
622
|
-
"Resource": "*"
|
623
|
-
}]
|
624
|
-
}
|
625
|
-
}]
|
626
|
-
}
|
627
|
-
},
|
628
|
-
"LambdaWAFLogParserFunction": {
|
629
|
-
"Type": "AWS::Lambda::Function",
|
630
|
-
"Condition": "LogParserActivated",
|
631
|
-
"DependsOn": ["LambdaRoleLogParser", "WAFBlacklistSet", "WAFAutoBlockSet"],
|
632
|
-
"Properties": {
|
633
|
-
"Description": {
|
634
|
-
"Fn::Join": ["", [
|
635
|
-
"This function parses CloudFront access logs to identify suspicious behavior, such as an abnormal amount of requests or errors. It then blocks those IP addresses for a customer-defined period of time. Parameters: ", {
|
636
|
-
"Ref": "RequestThreshold"
|
637
|
-
},
|
638
|
-
",", {
|
639
|
-
"Ref": "ErrorThreshold"
|
640
|
-
},
|
641
|
-
",", {
|
642
|
-
"Ref": "WAFBlockPeriod"
|
643
|
-
},
|
644
|
-
"."
|
645
|
-
]]
|
646
|
-
},
|
647
|
-
"Handler": "log-parser.lambda_handler",
|
648
|
-
"Role": {
|
649
|
-
"Fn::GetAtt": ["LambdaRoleLogParser", "Arn"]
|
650
|
-
},
|
651
|
-
"Code": {
|
652
|
-
"S3Bucket": {
|
653
|
-
"Fn::Join": ["-", [
|
654
|
-
"solutions", {
|
655
|
-
"Ref": "AWS::Region"
|
656
|
-
}
|
657
|
-
]]
|
658
|
-
},
|
659
|
-
"S3Key": "aws-waf-security-automations/v2/log-parser.zip"
|
660
|
-
},
|
661
|
-
"Environment": {
|
662
|
-
"Variables": {
|
663
|
-
"OUTPUT_BUCKET": {
|
664
|
-
"Ref": "CloudFrontAccessLogBucket"
|
665
|
-
},
|
666
|
-
"IP_SET_ID_BLACKLIST": {
|
667
|
-
"Ref": "WAFBlacklistSet"
|
668
|
-
},
|
669
|
-
"IP_SET_ID_AUTO_BLOCK": {
|
670
|
-
"Ref": "WAFAutoBlockSet"
|
671
|
-
},
|
672
|
-
"BLACKLIST_BLOCK_PERIOD": {
|
673
|
-
"Ref": "WAFBlockPeriod"
|
674
|
-
},
|
675
|
-
"REQUEST_PER_MINUTE_LIMIT": {
|
676
|
-
"Ref": "RequestThreshold"
|
677
|
-
},
|
678
|
-
"ERROR_PER_MINUTE_LIMIT": {
|
679
|
-
"Ref": "ErrorThreshold"
|
680
|
-
},
|
681
|
-
"SEND_ANONYMOUS_USAGE_DATA": {
|
682
|
-
"Ref": "SendAnonymousUsageData"
|
683
|
-
},
|
684
|
-
"UUID": {
|
685
|
-
"Fn::GetAtt": ["CreateUniqueID", "UUID"]
|
686
|
-
},
|
687
|
-
"LIMIT_IP_ADDRESS_RANGES_PER_IP_MATCH_CONDITION": "10000",
|
688
|
-
"MAX_AGE_TO_UPDATE": "30",
|
689
|
-
"REGION": {
|
690
|
-
"Ref": "AWS::Region"
|
691
|
-
},
|
692
|
-
"LOG_TYPE": "cloudfront"
|
693
|
-
}
|
694
|
-
},
|
695
|
-
"Runtime": "python2.7",
|
696
|
-
"MemorySize": "512",
|
697
|
-
"Timeout": "300"
|
698
|
-
}
|
699
|
-
},
|
700
|
-
"LambdaInvokePermissionLogParser": {
|
701
|
-
"Type": "AWS::Lambda::Permission",
|
702
|
-
"Condition": "LogParserActivated",
|
703
|
-
"DependsOn": "LambdaWAFLogParserFunction",
|
704
|
-
"Properties": {
|
705
|
-
"FunctionName": {
|
706
|
-
"Fn::GetAtt": ["LambdaWAFLogParserFunction", "Arn"]
|
707
|
-
},
|
708
|
-
"Action": "lambda:*",
|
709
|
-
"Principal": "s3.amazonaws.com",
|
710
|
-
"SourceAccount": {
|
711
|
-
"Ref": "AWS::AccountId"
|
712
|
-
}
|
713
|
-
}
|
714
|
-
},
|
715
|
-
"LambdaRoleReputationListsParser": {
|
716
|
-
"Type": "AWS::IAM::Role",
|
717
|
-
"Condition": "ReputationListsProtectionActivated",
|
718
|
-
"Properties": {
|
719
|
-
"AssumeRolePolicyDocument": {
|
720
|
-
"Statement": [{
|
721
|
-
"Effect": "Allow",
|
722
|
-
"Principal": {
|
723
|
-
"Service": [
|
724
|
-
"lambda.amazonaws.com"
|
725
|
-
]
|
726
|
-
},
|
727
|
-
"Action": "sts:AssumeRole"
|
728
|
-
}]
|
729
|
-
},
|
730
|
-
"Policies": [{
|
731
|
-
"PolicyName": "CloudWatchLogs",
|
732
|
-
"PolicyDocument": {
|
733
|
-
"Statement": [{
|
734
|
-
"Effect": "Allow",
|
735
|
-
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
|
736
|
-
"Resource": { "Fn::Join" : [":", ["arn:aws:logs",{"Ref" : "AWS::Region"},{ "Ref" : "AWS::AccountId" }, "log-group:/aws/lambda/*" ]]}
|
737
|
-
}]
|
738
|
-
}
|
739
|
-
}, {
|
740
|
-
"PolicyName": "WAFGetChangeToken",
|
741
|
-
"PolicyDocument": {
|
742
|
-
"Statement": [{
|
743
|
-
"Effect": "Allow",
|
744
|
-
"Action": "waf:GetChangeToken",
|
745
|
-
"Resource": "*"
|
746
|
-
}]
|
747
|
-
}
|
748
|
-
}, {
|
749
|
-
"PolicyName": "WAFGetAndUpdateIPSet",
|
750
|
-
"PolicyDocument": {
|
751
|
-
"Statement": [{
|
752
|
-
"Effect": "Allow",
|
753
|
-
"Action": [
|
754
|
-
"waf:GetIPSet",
|
755
|
-
"waf:UpdateIPSet"
|
756
|
-
],
|
757
|
-
"Resource": [{
|
758
|
-
"Fn::Join": [
|
759
|
-
"", [
|
760
|
-
"arn:aws:waf::", {
|
761
|
-
"Ref": "AWS::AccountId"
|
762
|
-
},
|
763
|
-
":ipset/", {
|
764
|
-
"Ref": "WAFReputationListsSet1"
|
765
|
-
}
|
766
|
-
]
|
767
|
-
]
|
768
|
-
}, {
|
769
|
-
"Fn::Join": [
|
770
|
-
"", [
|
771
|
-
"arn:aws:waf::", {
|
772
|
-
"Ref": "AWS::AccountId"
|
773
|
-
},
|
774
|
-
":ipset/", {
|
775
|
-
"Ref": "WAFReputationListsSet2"
|
776
|
-
}
|
777
|
-
]
|
778
|
-
]
|
779
|
-
}]
|
780
|
-
}]
|
781
|
-
}
|
782
|
-
}, {
|
783
|
-
"PolicyName": "CloudFormationAccess",
|
784
|
-
"PolicyDocument": {
|
785
|
-
"Version": "2012-10-17",
|
786
|
-
"Statement": [{
|
787
|
-
"Effect": "Allow",
|
788
|
-
"Action": "cloudformation:DescribeStacks",
|
789
|
-
"Resource": {
|
790
|
-
"Fn::Join": [
|
791
|
-
"", [
|
792
|
-
"arn:aws:cloudformation:", {
|
793
|
-
"Ref": "AWS::Region"
|
794
|
-
},
|
795
|
-
":", {
|
796
|
-
"Ref": "AWS::AccountId"
|
797
|
-
},
|
798
|
-
":stack/", {
|
799
|
-
"Ref": "AWS::StackName"
|
800
|
-
},
|
801
|
-
"/*"
|
802
|
-
]
|
803
|
-
]
|
804
|
-
}
|
805
|
-
}]
|
806
|
-
}
|
807
|
-
}, {
|
808
|
-
"PolicyName": "CloudWatchAccess",
|
809
|
-
"PolicyDocument": {
|
810
|
-
"Version": "2012-10-17",
|
811
|
-
"Statement": [{
|
812
|
-
"Effect": "Allow",
|
813
|
-
"Action": "cloudwatch:GetMetricStatistics",
|
814
|
-
"Resource": "*"
|
815
|
-
}]
|
816
|
-
}
|
817
|
-
}]
|
818
|
-
}
|
819
|
-
},
|
820
|
-
"LambdaWAFReputationListsParserFunction": {
|
821
|
-
"Type": "AWS::Lambda::Function",
|
822
|
-
"Condition": "ReputationListsProtectionActivated",
|
823
|
-
"DependsOn": "LambdaRoleReputationListsParser",
|
824
|
-
"Properties": {
|
825
|
-
"Description": "This lambda function checks third-party IP reputation lists hourly for new IP ranges to block. These lists include the Spamhaus Dont Route Or Peer (DROP) and Extended Drop (EDROP) lists, the Proofpoint Emerging Threats IP list, and the Tor exit node list.",
|
826
|
-
"Handler": "reputation-lists-parser.handler",
|
827
|
-
"Role": {
|
828
|
-
"Fn::GetAtt": [
|
829
|
-
"LambdaRoleReputationListsParser",
|
830
|
-
"Arn"
|
831
|
-
]
|
832
|
-
},
|
833
|
-
"Code": {
|
834
|
-
"S3Bucket": {
|
835
|
-
"Fn::Join": ["-", [
|
836
|
-
"solutions", {
|
837
|
-
"Ref": "AWS::Region"
|
838
|
-
}
|
839
|
-
]]
|
840
|
-
},
|
841
|
-
"S3Key": "aws-waf-security-automations/v3/reputation-lists-parser.zip"
|
842
|
-
},
|
843
|
-
"Runtime": "nodejs6.10",
|
844
|
-
"MemorySize": "128",
|
845
|
-
"Timeout": "300"
|
846
|
-
}
|
847
|
-
},
|
848
|
-
"LambdaWAFReputationListsParserEventsRule": {
|
849
|
-
"Type": "AWS::Events::Rule",
|
850
|
-
"Condition": "ReputationListsProtectionActivated",
|
851
|
-
"DependsOn": ["LambdaWAFReputationListsParserFunction", "WAFReputationListsSet1", "WAFReputationListsSet2"],
|
852
|
-
"Properties": {
|
853
|
-
"Description": "Security Automations - WAF Reputation Lists",
|
854
|
-
"ScheduleExpression": "rate(1 hour)",
|
855
|
-
"Targets": [{
|
856
|
-
"Arn": {
|
857
|
-
"Fn::GetAtt": [
|
858
|
-
"LambdaWAFReputationListsParserFunction",
|
859
|
-
"Arn"
|
860
|
-
]
|
861
|
-
},
|
862
|
-
"Id": "LambdaWAFReputationListsParserFunction",
|
863
|
-
"Input": {
|
864
|
-
"Fn::Join": [
|
865
|
-
"", [
|
866
|
-
"{\"lists\":",
|
867
|
-
"[{\"url\":\"https://www.spamhaus.org/drop/drop.txt\"},{\"url\":\"https://check.torproject.org/exit-addresses\",\"prefix\":\"ExitAddress \"},{\"url\":\"https://rules.emergingthreats.net/fwrules/emerging-Block-IPs.txt\"}]",
|
868
|
-
",\"logType\":\"cloudfront\"",
|
869
|
-
",\"region\":\"", {
|
870
|
-
"Ref": "AWS::Region"
|
871
|
-
}, "\",",
|
872
|
-
"\"ipSetIds\": [",
|
873
|
-
"\"", {
|
874
|
-
"Ref": "WAFReputationListsSet1"
|
875
|
-
},
|
876
|
-
"\",",
|
877
|
-
"\"", {
|
878
|
-
"Ref": "WAFReputationListsSet2"
|
879
|
-
},
|
880
|
-
"\"",
|
881
|
-
"]}"
|
882
|
-
]
|
883
|
-
]
|
884
|
-
}
|
885
|
-
}]
|
886
|
-
}
|
887
|
-
},
|
888
|
-
"LambdaInvokePermissionReputationListsParser": {
|
889
|
-
"Type": "AWS::Lambda::Permission",
|
890
|
-
"Condition": "ReputationListsProtectionActivated",
|
891
|
-
"DependsOn": ["LambdaWAFReputationListsParserFunction", "LambdaWAFReputationListsParserEventsRule"],
|
892
|
-
"Properties": {
|
893
|
-
"FunctionName": {
|
894
|
-
"Ref": "LambdaWAFReputationListsParserFunction"
|
895
|
-
},
|
896
|
-
"Action": "lambda:InvokeFunction",
|
897
|
-
"Principal": "events.amazonaws.com",
|
898
|
-
"SourceArn": {
|
899
|
-
"Fn::GetAtt": [
|
900
|
-
"LambdaWAFReputationListsParserEventsRule",
|
901
|
-
"Arn"
|
902
|
-
]
|
903
|
-
}
|
904
|
-
}
|
905
|
-
},
|
906
|
-
"LambdaRoleBadBot": {
|
907
|
-
"Type": "AWS::IAM::Role",
|
908
|
-
"Condition": "BadBotProtectionActivated",
|
909
|
-
"Properties": {
|
910
|
-
"AssumeRolePolicyDocument": {
|
911
|
-
"Version": "2012-10-17",
|
912
|
-
"Statement": [{
|
913
|
-
"Effect": "Allow",
|
914
|
-
"Principal": {
|
915
|
-
"Service": ["lambda.amazonaws.com"]
|
916
|
-
},
|
917
|
-
"Action": ["sts:AssumeRole"]
|
918
|
-
}]
|
919
|
-
},
|
920
|
-
"Path": "/",
|
921
|
-
"Policies": [{
|
922
|
-
"PolicyName": "WAFGetChangeToken",
|
923
|
-
"PolicyDocument": {
|
924
|
-
"Statement": [{
|
925
|
-
"Effect": "Allow",
|
926
|
-
"Action": "waf:GetChangeToken",
|
927
|
-
"Resource": "*"
|
928
|
-
}]
|
929
|
-
}
|
930
|
-
}, {
|
931
|
-
"PolicyName": "WAFGetAndUpdateIPSet",
|
932
|
-
"PolicyDocument": {
|
933
|
-
"Statement": [{
|
934
|
-
"Effect": "Allow",
|
935
|
-
"Action": [
|
936
|
-
"waf:GetIPSet",
|
937
|
-
"waf:UpdateIPSet"
|
938
|
-
],
|
939
|
-
"Resource": {
|
940
|
-
"Fn::Join": [
|
941
|
-
"", [
|
942
|
-
"arn:aws:waf::", {
|
943
|
-
"Ref": "AWS::AccountId"
|
944
|
-
},
|
945
|
-
":ipset/", {
|
946
|
-
"Ref": "WAFBadBotSet"
|
947
|
-
}
|
948
|
-
]
|
949
|
-
]
|
950
|
-
}
|
951
|
-
}]
|
952
|
-
}
|
953
|
-
}, {
|
954
|
-
"PolicyName": "LogsAccess",
|
955
|
-
"PolicyDocument": {
|
956
|
-
"Version": "2012-10-17",
|
957
|
-
"Statement": [{
|
958
|
-
"Effect": "Allow",
|
959
|
-
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
|
960
|
-
"Resource": { "Fn::Join" : [":", ["arn:aws:logs",{"Ref" : "AWS::Region"},{ "Ref" : "AWS::AccountId" }, "log-group:/aws/lambda/*" ]]}
|
961
|
-
}]
|
962
|
-
}
|
963
|
-
}, {
|
964
|
-
"PolicyName": "CloudFormationAccess",
|
965
|
-
"PolicyDocument": {
|
966
|
-
"Version": "2012-10-17",
|
967
|
-
"Statement": [{
|
968
|
-
"Effect": "Allow",
|
969
|
-
"Action": "cloudformation:DescribeStacks",
|
970
|
-
"Resource": {
|
971
|
-
"Fn::Join": [
|
972
|
-
"", [
|
973
|
-
"arn:aws:cloudformation:", {
|
974
|
-
"Ref": "AWS::Region"
|
975
|
-
},
|
976
|
-
":", {
|
977
|
-
"Ref": "AWS::AccountId"
|
978
|
-
},
|
979
|
-
":stack/", {
|
980
|
-
"Ref": "AWS::StackName"
|
981
|
-
},
|
982
|
-
"/*"
|
983
|
-
]
|
984
|
-
]
|
985
|
-
}
|
986
|
-
}]
|
987
|
-
}
|
988
|
-
}, {
|
989
|
-
"PolicyName": "CloudWatchAccess",
|
990
|
-
"PolicyDocument": {
|
991
|
-
"Version": "2012-10-17",
|
992
|
-
"Statement": [{
|
993
|
-
"Effect": "Allow",
|
994
|
-
"Action": "cloudwatch:GetMetricStatistics",
|
995
|
-
"Resource": "*"
|
996
|
-
}]
|
997
|
-
}
|
998
|
-
}]
|
999
|
-
}
|
1000
|
-
},
|
1001
|
-
"LambdaWAFBadBotParserFunction": {
|
1002
|
-
"Type": "AWS::Lambda::Function",
|
1003
|
-
"Condition": "BadBotProtectionActivated",
|
1004
|
-
"DependsOn": "LambdaRoleBadBot",
|
1005
|
-
"Properties": {
|
1006
|
-
"Description": "This lambda function will intercepts and inspects trap endpoint requests to extract its IP address, and then add it to an AWS WAF block list.",
|
1007
|
-
"Handler": "access-handler.lambda_handler",
|
1008
|
-
"Role": {
|
1009
|
-
"Fn::GetAtt": ["LambdaRoleBadBot", "Arn"]
|
1010
|
-
},
|
1011
|
-
"Code": {
|
1012
|
-
"S3Bucket": {
|
1013
|
-
"Fn::Join": ["-", [
|
1014
|
-
"solutions", {
|
1015
|
-
"Ref": "AWS::Region"
|
1016
|
-
}
|
1017
|
-
]]
|
1018
|
-
},
|
1019
|
-
"S3Key": "aws-waf-security-automations/v2/access-handler.zip"
|
1020
|
-
},
|
1021
|
-
"Environment": {
|
1022
|
-
"Variables": {
|
1023
|
-
"IP_SET_ID_BAD_BOT": {
|
1024
|
-
"Ref": "WAFBadBotSet"
|
1025
|
-
},
|
1026
|
-
"SEND_ANONYMOUS_USAGE_DATA": {
|
1027
|
-
"Ref": "SendAnonymousUsageData"
|
1028
|
-
},
|
1029
|
-
"UUID": {
|
1030
|
-
"Fn::GetAtt": ["CreateUniqueID", "UUID"]
|
1031
|
-
},
|
1032
|
-
"REGION": {
|
1033
|
-
"Ref": "AWS::Region"
|
1034
|
-
},
|
1035
|
-
"LOG_TYPE": "cloudfront"
|
1036
|
-
}
|
1037
|
-
},
|
1038
|
-
"Runtime": "python2.7",
|
1039
|
-
"MemorySize": "128",
|
1040
|
-
"Timeout": "300"
|
1041
|
-
}
|
1042
|
-
},
|
1043
|
-
"LambdaInvokePermissionBadBot": {
|
1044
|
-
"Type": "AWS::Lambda::Permission",
|
1045
|
-
"Condition": "BadBotProtectionActivated",
|
1046
|
-
"DependsOn": "LambdaWAFBadBotParserFunction",
|
1047
|
-
"Properties": {
|
1048
|
-
"FunctionName": {
|
1049
|
-
"Fn::GetAtt": ["LambdaWAFBadBotParserFunction", "Arn"]
|
1050
|
-
},
|
1051
|
-
"Action": "lambda:*",
|
1052
|
-
"Principal": "apigateway.amazonaws.com"
|
1053
|
-
}
|
1054
|
-
},
|
1055
|
-
"ApiGatewayBadBot": {
|
1056
|
-
"Type": "AWS::ApiGateway::RestApi",
|
1057
|
-
"Condition": "BadBotProtectionActivated",
|
1058
|
-
"Properties": {
|
1059
|
-
"Name": "Security Automations - WAF Bad Bot API",
|
1060
|
-
"Description": "API created by AWS WAF Security Automations CloudFormation template. This endpoint will be used to capture bad bots."
|
1061
|
-
}
|
1062
|
-
},
|
1063
|
-
"ApiGatewayBadBotResource": {
|
1064
|
-
"Type": "AWS::ApiGateway::Resource",
|
1065
|
-
"Properties": {
|
1066
|
-
"RestApiId": {
|
1067
|
-
"Ref": "ApiGatewayBadBot"
|
1068
|
-
},
|
1069
|
-
"ParentId": {
|
1070
|
-
"Fn::GetAtt": ["ApiGatewayBadBot", "RootResourceId"]
|
1071
|
-
},
|
1072
|
-
"PathPart": "{proxy+}"
|
1073
|
-
}
|
1074
|
-
},
|
1075
|
-
"ApiGatewayBadBotMethodRoot": {
|
1076
|
-
"Type": "AWS::ApiGateway::Method",
|
1077
|
-
"Condition": "BadBotProtectionActivated",
|
1078
|
-
"DependsOn": ["LambdaWAFBadBotParserFunction", "LambdaInvokePermissionBadBot", "ApiGatewayBadBot"],
|
1079
|
-
"Properties": {
|
1080
|
-
"RestApiId": {
|
1081
|
-
"Ref": "ApiGatewayBadBot"
|
1082
|
-
},
|
1083
|
-
"ResourceId": {
|
1084
|
-
"Fn::GetAtt": ["ApiGatewayBadBot", "RootResourceId"]
|
1085
|
-
},
|
1086
|
-
"HttpMethod": "ANY",
|
1087
|
-
"AuthorizationType": "NONE",
|
1088
|
-
"RequestParameters": {
|
1089
|
-
"method.request.header.X-Forwarded-For": false
|
1090
|
-
},
|
1091
|
-
"Integration": {
|
1092
|
-
"Type": "AWS_PROXY",
|
1093
|
-
"IntegrationHttpMethod": "POST",
|
1094
|
-
"Uri": {
|
1095
|
-
"Fn::Join": ["", [
|
1096
|
-
"arn:aws:apigateway:", {
|
1097
|
-
"Ref": "AWS::Region"
|
1098
|
-
},
|
1099
|
-
":lambda:path/2015-03-31/functions/", {
|
1100
|
-
"Fn::GetAtt": ["LambdaWAFBadBotParserFunction", "Arn"]
|
1101
|
-
},
|
1102
|
-
"/invocations"
|
1103
|
-
]]
|
1104
|
-
}
|
1105
|
-
}
|
1106
|
-
}
|
1107
|
-
},
|
1108
|
-
"ApiGatewayBadBotMethod": {
|
1109
|
-
"Type": "AWS::ApiGateway::Method",
|
1110
|
-
"Condition": "BadBotProtectionActivated",
|
1111
|
-
"DependsOn": ["LambdaWAFBadBotParserFunction", "LambdaInvokePermissionBadBot", "ApiGatewayBadBot"],
|
1112
|
-
"Properties": {
|
1113
|
-
"RestApiId": {
|
1114
|
-
"Ref": "ApiGatewayBadBot"
|
1115
|
-
},
|
1116
|
-
"ResourceId": {
|
1117
|
-
"Ref": "ApiGatewayBadBotResource"
|
1118
|
-
},
|
1119
|
-
"HttpMethod": "ANY",
|
1120
|
-
"AuthorizationType": "NONE",
|
1121
|
-
"RequestParameters": {
|
1122
|
-
"method.request.header.X-Forwarded-For": false
|
1123
|
-
},
|
1124
|
-
"Integration": {
|
1125
|
-
"Type": "AWS_PROXY",
|
1126
|
-
"IntegrationHttpMethod": "POST",
|
1127
|
-
"Uri": {
|
1128
|
-
"Fn::Join": ["", [
|
1129
|
-
"arn:aws:apigateway:", {
|
1130
|
-
"Ref": "AWS::Region"
|
1131
|
-
},
|
1132
|
-
":lambda:path/2015-03-31/functions/", {
|
1133
|
-
"Fn::GetAtt": ["LambdaWAFBadBotParserFunction", "Arn"]
|
1134
|
-
},
|
1135
|
-
"/invocations"
|
1136
|
-
]]
|
1137
|
-
}
|
1138
|
-
}
|
1139
|
-
}
|
1140
|
-
},
|
1141
|
-
"ApiGatewayBadBotDeployment": {
|
1142
|
-
"Type": "AWS::ApiGateway::Deployment",
|
1143
|
-
"Condition": "BadBotProtectionActivated",
|
1144
|
-
"DependsOn": "ApiGatewayBadBotMethod",
|
1145
|
-
"Properties": {
|
1146
|
-
"RestApiId": {
|
1147
|
-
"Ref": "ApiGatewayBadBot"
|
1148
|
-
},
|
1149
|
-
"Description": "CloudFormation Deployment Stage",
|
1150
|
-
"StageName": "CFDeploymentStage"
|
1151
|
-
}
|
1152
|
-
},
|
1153
|
-
"ApiGatewayBadBotStage": {
|
1154
|
-
"Type": "AWS::ApiGateway::Stage",
|
1155
|
-
"Condition": "BadBotProtectionActivated",
|
1156
|
-
"DependsOn": "ApiGatewayBadBotDeployment",
|
1157
|
-
"Properties": {
|
1158
|
-
"DeploymentId": {
|
1159
|
-
"Ref": "ApiGatewayBadBotDeployment"
|
1160
|
-
},
|
1161
|
-
"Description": "Production Stage",
|
1162
|
-
"RestApiId": {
|
1163
|
-
"Ref": "ApiGatewayBadBot"
|
1164
|
-
},
|
1165
|
-
"StageName": "ProdStage"
|
1166
|
-
}
|
1167
|
-
},
|
1168
|
-
"LambdaRoleCustomResource": {
|
1169
|
-
"Type": "AWS::IAM::Role",
|
1170
|
-
"Condition": "CreateWebACL",
|
1171
|
-
"DependsOn": "WAFWebACL",
|
1172
|
-
"Properties": {
|
1173
|
-
"AssumeRolePolicyDocument": {
|
1174
|
-
"Version": "2012-10-17",
|
1175
|
-
"Statement": [{
|
1176
|
-
"Effect": "Allow",
|
1177
|
-
"Principal": {
|
1178
|
-
"Service": ["lambda.amazonaws.com"]
|
1179
|
-
},
|
1180
|
-
"Action": ["sts:AssumeRole"]
|
1181
|
-
}]
|
1182
|
-
},
|
1183
|
-
"Path": "/",
|
1184
|
-
"Policies": [{
|
1185
|
-
"PolicyName": "S3Access",
|
1186
|
-
"PolicyDocument": {
|
1187
|
-
"Version": "2012-10-17",
|
1188
|
-
"Statement": [{
|
1189
|
-
"Effect": "Allow",
|
1190
|
-
"Action": [
|
1191
|
-
"s3:CreateBucket",
|
1192
|
-
"s3:GetBucketLocation",
|
1193
|
-
"s3:GetBucketNotification",
|
1194
|
-
"s3:GetObject",
|
1195
|
-
"s3:ListBucket",
|
1196
|
-
"s3:PutBucketNotification"
|
1197
|
-
],
|
1198
|
-
"Resource": {
|
1199
|
-
"Fn::Join": ["", ["arn:aws:s3:::", {
|
1200
|
-
"Ref": "CloudFrontAccessLogBucket"
|
1201
|
-
}]]
|
1202
|
-
}
|
1203
|
-
}]
|
1204
|
-
}
|
1205
|
-
}, {
|
1206
|
-
"PolicyName": "LambdaAccess",
|
1207
|
-
"PolicyDocument": {
|
1208
|
-
"Version": "2012-10-17",
|
1209
|
-
"Statement": [{
|
1210
|
-
"Effect": "Allow",
|
1211
|
-
"Action": "lambda:InvokeFunction",
|
1212
|
-
"Resource": {
|
1213
|
-
"Fn::Join": ["", ["arn:aws:lambda:", {
|
1214
|
-
"Ref": "AWS::Region"
|
1215
|
-
},
|
1216
|
-
":", {
|
1217
|
-
"Ref": "AWS::AccountId"
|
1218
|
-
},
|
1219
|
-
":function:", {
|
1220
|
-
"Ref": "AWS::StackName"
|
1221
|
-
},
|
1222
|
-
"-LambdaWAFReputationLists*"
|
1223
|
-
]]
|
1224
|
-
}
|
1225
|
-
}]
|
1226
|
-
}
|
1227
|
-
}, {
|
1228
|
-
"PolicyName": "WAFAccess",
|
1229
|
-
"PolicyDocument": {
|
1230
|
-
"Version": "2012-10-17",
|
1231
|
-
"Statement": [{
|
1232
|
-
"Effect": "Allow",
|
1233
|
-
"Action": [
|
1234
|
-
"waf:GetWebACL",
|
1235
|
-
"waf:UpdateWebACL"
|
1236
|
-
],
|
1237
|
-
"Resource": {
|
1238
|
-
"Fn::Join": ["", ["arn:aws:waf::", {
|
1239
|
-
"Ref": "AWS::AccountId"
|
1240
|
-
},
|
1241
|
-
":webacl/", {
|
1242
|
-
"Ref": "WAFWebACL"
|
1243
|
-
}
|
1244
|
-
]]
|
1245
|
-
}
|
1246
|
-
}]
|
1247
|
-
}
|
1248
|
-
}, {
|
1249
|
-
"PolicyName": "WAFRuleAccess",
|
1250
|
-
"PolicyDocument": {
|
1251
|
-
"Version": "2012-10-17",
|
1252
|
-
"Statement": [{
|
1253
|
-
"Effect": "Allow",
|
1254
|
-
"Action": "waf:GetRule",
|
1255
|
-
"Resource": {
|
1256
|
-
"Fn::Join": ["", ["arn:aws:waf::", {
|
1257
|
-
"Ref": "AWS::AccountId"
|
1258
|
-
},
|
1259
|
-
":rule/*"
|
1260
|
-
]]
|
1261
|
-
}
|
1262
|
-
}]
|
1263
|
-
}
|
1264
|
-
}, {
|
1265
|
-
"PolicyName": "CloudFormationAccess",
|
1266
|
-
"PolicyDocument": {
|
1267
|
-
"Version": "2012-10-17",
|
1268
|
-
"Statement": [{
|
1269
|
-
"Effect": "Allow",
|
1270
|
-
"Action": "cloudformation:DescribeStacks",
|
1271
|
-
"Resource": {
|
1272
|
-
"Fn::Join": [
|
1273
|
-
"", [
|
1274
|
-
"arn:aws:cloudformation:", {
|
1275
|
-
"Ref": "AWS::Region"
|
1276
|
-
},
|
1277
|
-
":", {
|
1278
|
-
"Ref": "AWS::AccountId"
|
1279
|
-
},
|
1280
|
-
":stack/", {
|
1281
|
-
"Ref": "AWS::StackName"
|
1282
|
-
},
|
1283
|
-
"/*"
|
1284
|
-
]
|
1285
|
-
]
|
1286
|
-
}
|
1287
|
-
}]
|
1288
|
-
}
|
1289
|
-
}, {
|
1290
|
-
"PolicyName": "WAFGetChangeToken",
|
1291
|
-
"PolicyDocument": {
|
1292
|
-
"Statement": [{
|
1293
|
-
"Effect": "Allow",
|
1294
|
-
"Action": "waf:GetChangeToken",
|
1295
|
-
"Resource": "*"
|
1296
|
-
}]
|
1297
|
-
}
|
1298
|
-
}, {
|
1299
|
-
"PolicyName": "LogsAccess",
|
1300
|
-
"PolicyDocument": {
|
1301
|
-
"Version": "2012-10-17",
|
1302
|
-
"Statement": [{
|
1303
|
-
"Effect": "Allow",
|
1304
|
-
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
|
1305
|
-
"Resource": { "Fn::Join" : [":", ["arn:aws:logs",{"Ref" : "AWS::Region"},{ "Ref" : "AWS::AccountId" }, "log-group:/aws/lambda/*" ]]}
|
1306
|
-
}]
|
1307
|
-
}
|
1308
|
-
}]
|
1309
|
-
}
|
1310
|
-
},
|
1311
|
-
"LambdaWAFCustomResourceFunction": {
|
1312
|
-
"Type": "AWS::Lambda::Function",
|
1313
|
-
"Condition": "CreateWebACL",
|
1314
|
-
"DependsOn": "LambdaRoleCustomResource",
|
1315
|
-
"Properties": {
|
1316
|
-
"Description": {
|
1317
|
-
"Fn::Join": ["", [
|
1318
|
-
"This lambda function configures the Web ACL rules based on the features enabled in the CloudFormation template. Parameters: ", {
|
1319
|
-
"Ref": "SendAnonymousUsageData"
|
1320
|
-
},
|
1321
|
-
"."
|
1322
|
-
]]
|
1323
|
-
},
|
1324
|
-
"Handler": "custom-resource.lambda_handler",
|
1325
|
-
"Role": {
|
1326
|
-
"Fn::GetAtt": ["LambdaRoleCustomResource", "Arn"]
|
1327
|
-
},
|
1328
|
-
"Code": {
|
1329
|
-
"S3Bucket": {
|
1330
|
-
"Fn::Join": ["-", [
|
1331
|
-
"solutions", {
|
1332
|
-
"Ref": "AWS::Region"
|
1333
|
-
}
|
1334
|
-
]]
|
1335
|
-
},
|
1336
|
-
"S3Key": "aws-waf-security-automations/v3/custom-resource.zip"
|
1337
|
-
},
|
1338
|
-
"Runtime": "python2.7",
|
1339
|
-
"MemorySize": "128",
|
1340
|
-
"Timeout": "300"
|
1341
|
-
}
|
1342
|
-
},
|
1343
|
-
"WafWebAclRuleControler": {
|
1344
|
-
"Type": "Custom::WafWebAclRuleControler",
|
1345
|
-
"Condition": "CreateWebACL",
|
1346
|
-
"DependsOn": ["LambdaWAFCustomResourceFunction", "WAFWebACL"],
|
1347
|
-
"Properties": {
|
1348
|
-
"ServiceToken": {
|
1349
|
-
"Fn::GetAtt": ["LambdaWAFCustomResourceFunction", "Arn"]
|
1350
|
-
},
|
1351
|
-
"WAFWebACL": {
|
1352
|
-
"Ref": "WAFWebACL"
|
1353
|
-
},
|
1354
|
-
"Region": {
|
1355
|
-
"Ref": "AWS::Region"
|
1356
|
-
},
|
1357
|
-
"LambdaWAFReputationListsParserFunction": {
|
1358
|
-
"Fn::If": ["ReputationListsProtectionActivated", {
|
1359
|
-
"Fn::GetAtt": ["LambdaWAFReputationListsParserFunction", "Arn"]
|
1360
|
-
}, {
|
1361
|
-
"Ref": "AWS::NoValue"
|
1362
|
-
}]
|
1363
|
-
},
|
1364
|
-
"WAFReputationListsSet1": {
|
1365
|
-
"Fn::If": ["ReputationListsProtectionActivated", {
|
1366
|
-
"Ref": "WAFReputationListsSet1"
|
1367
|
-
}, {
|
1368
|
-
"Ref": "AWS::NoValue"
|
1369
|
-
}]
|
1370
|
-
},
|
1371
|
-
"WAFReputationListsSet2": {
|
1372
|
-
"Fn::If": ["ReputationListsProtectionActivated", {
|
1373
|
-
"Ref": "WAFReputationListsSet2"
|
1374
|
-
}, {
|
1375
|
-
"Ref": "AWS::NoValue"
|
1376
|
-
}]
|
1377
|
-
},
|
1378
|
-
"CloudFrontAccessLogBucket": {
|
1379
|
-
"Fn::If": ["LogParserActivated", {
|
1380
|
-
"Ref": "CloudFrontAccessLogBucket"
|
1381
|
-
}, {
|
1382
|
-
"Ref": "AWS::NoValue"
|
1383
|
-
}]
|
1384
|
-
},
|
1385
|
-
"LambdaWAFLogParserFunction": {
|
1386
|
-
"Fn::If": ["LogParserActivated", {
|
1387
|
-
"Fn::GetAtt": ["LambdaWAFLogParserFunction", "Arn"]
|
1388
|
-
}, {
|
1389
|
-
"Ref": "AWS::NoValue"
|
1390
|
-
}]
|
1391
|
-
},
|
1392
|
-
"WAFWhitelistRule": {
|
1393
|
-
"Fn::If": ["CreateWebACL", {
|
1394
|
-
"Ref": "WAFWhitelistRule"
|
1395
|
-
}, {
|
1396
|
-
"Ref": "AWS::NoValue"
|
1397
|
-
}]
|
1398
|
-
},
|
1399
|
-
"WAFBlacklistRule": {
|
1400
|
-
"Fn::If": ["LogParserActivated", {
|
1401
|
-
"Ref": "WAFBlacklistRule"
|
1402
|
-
}, {
|
1403
|
-
"Ref": "AWS::NoValue"
|
1404
|
-
}]
|
1405
|
-
},
|
1406
|
-
"WAFAutoBlockRule": {
|
1407
|
-
"Fn::If": ["LogParserActivated", {
|
1408
|
-
"Ref": "WAFAutoBlockRule"
|
1409
|
-
}, {
|
1410
|
-
"Ref": "AWS::NoValue"
|
1411
|
-
}]
|
1412
|
-
},
|
1413
|
-
"WAFIPReputationListsRule1": {
|
1414
|
-
"Fn::If": ["ReputationListsProtectionActivated", {
|
1415
|
-
"Ref": "WAFIPReputationListsRule1"
|
1416
|
-
}, {
|
1417
|
-
"Ref": "AWS::NoValue"
|
1418
|
-
}]
|
1419
|
-
},
|
1420
|
-
"WAFIPReputationListsRule2": {
|
1421
|
-
"Fn::If": ["ReputationListsProtectionActivated", {
|
1422
|
-
"Ref": "WAFIPReputationListsRule2"
|
1423
|
-
}, {
|
1424
|
-
"Ref": "AWS::NoValue"
|
1425
|
-
}]
|
1426
|
-
},
|
1427
|
-
"WAFBadBotRule": {
|
1428
|
-
"Fn::If": ["BadBotProtectionActivated", {
|
1429
|
-
"Ref": "WAFBadBotRule"
|
1430
|
-
}, {
|
1431
|
-
"Ref": "AWS::NoValue"
|
1432
|
-
}]
|
1433
|
-
},
|
1434
|
-
"WAFSqlInjectionRule": {
|
1435
|
-
"Fn::If": ["SqlInjectionProtectionActivated", {
|
1436
|
-
"Ref": "WAFSqlInjectionRule"
|
1437
|
-
}, {
|
1438
|
-
"Ref": "AWS::NoValue"
|
1439
|
-
}]
|
1440
|
-
},
|
1441
|
-
"WAFXssRule": {
|
1442
|
-
"Fn::If": ["CrossSiteScriptingProtectionActivated", {
|
1443
|
-
"Ref": "WAFXssRule"
|
1444
|
-
}, {
|
1445
|
-
"Ref": "AWS::NoValue"
|
1446
|
-
}]
|
1447
|
-
},
|
1448
|
-
"SqlInjectionProtection": {
|
1449
|
-
"Ref": "SqlInjectionProtectionParam"
|
1450
|
-
},
|
1451
|
-
"CrossSiteScriptingProtection": {
|
1452
|
-
"Ref": "CrossSiteScriptingProtectionParam"
|
1453
|
-
},
|
1454
|
-
"ActivateHttpFloodProtection": {
|
1455
|
-
"Ref": "ActivateHttpFloodProtectionParam"
|
1456
|
-
},
|
1457
|
-
"ActivateScansProbesProtection": {
|
1458
|
-
"Ref": "ActivateScansProbesProtectionParam"
|
1459
|
-
},
|
1460
|
-
"ActivateReputationListsProtection": {
|
1461
|
-
"Ref": "ActivateReputationListsProtectionParam"
|
1462
|
-
},
|
1463
|
-
"ActivateBadBotProtection": {
|
1464
|
-
"Ref": "ActivateBadBotProtectionParam"
|
1465
|
-
},
|
1466
|
-
"RequestThreshold": {
|
1467
|
-
"Ref": "RequestThreshold"
|
1468
|
-
},
|
1469
|
-
"ErrorThreshold": {
|
1470
|
-
"Ref": "ErrorThreshold"
|
1471
|
-
},
|
1472
|
-
"WAFBlockPeriod": {
|
1473
|
-
"Ref": "WAFBlockPeriod"
|
1474
|
-
},
|
1475
|
-
"SendAnonymousUsageData": {
|
1476
|
-
"Ref": "SendAnonymousUsageData"
|
1477
|
-
},
|
1478
|
-
"UUID": {
|
1479
|
-
"Fn::GetAtt": ["CreateUniqueID", "UUID"]
|
1480
|
-
},
|
1481
|
-
"LOG_TYPE": "cloudfront"
|
1482
|
-
}
|
1483
|
-
},
|
1484
|
-
"SolutionHelperRole": {
|
1485
|
-
"Type": "AWS::IAM::Role",
|
1486
|
-
"Properties": {
|
1487
|
-
"AssumeRolePolicyDocument": {
|
1488
|
-
"Version": "2012-10-17",
|
1489
|
-
"Statement": [{
|
1490
|
-
"Effect": "Allow",
|
1491
|
-
"Principal": {
|
1492
|
-
"Service": "lambda.amazonaws.com"
|
1493
|
-
},
|
1494
|
-
"Action": "sts:AssumeRole"
|
1495
|
-
}]
|
1496
|
-
},
|
1497
|
-
"Path": "/",
|
1498
|
-
"Policies": [{
|
1499
|
-
"PolicyName": "Solution_Helper_Permissions",
|
1500
|
-
"PolicyDocument": {
|
1501
|
-
"Version": "2012-10-17",
|
1502
|
-
"Statement": [{
|
1503
|
-
"Effect": "Allow",
|
1504
|
-
"Action": ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"],
|
1505
|
-
"Resource": { "Fn::Join" : [":", ["arn:aws:logs",{"Ref" : "AWS::Region"},{ "Ref" : "AWS::AccountId" }, "log-group:/aws/lambda/*" ]]}
|
1506
|
-
}]
|
1507
|
-
}
|
1508
|
-
}]
|
1509
|
-
}
|
1510
|
-
},
|
1511
|
-
"SolutionHelper": {
|
1512
|
-
"Type": "AWS::Lambda::Function",
|
1513
|
-
"DependsOn": "SolutionHelperRole",
|
1514
|
-
"Properties": {
|
1515
|
-
"Handler": "solution-helper.lambda_handler",
|
1516
|
-
"Role": {
|
1517
|
-
"Fn::GetAtt": [
|
1518
|
-
"SolutionHelperRole",
|
1519
|
-
"Arn"
|
1520
|
-
]
|
1521
|
-
},
|
1522
|
-
"Description": "This lambda function executes generic common tasks to support this solution.",
|
1523
|
-
"Code": {
|
1524
|
-
"S3Bucket": {
|
1525
|
-
"Fn::Join": [
|
1526
|
-
"", [
|
1527
|
-
"solutions-", {
|
1528
|
-
"Ref": "AWS::Region"
|
1529
|
-
}
|
1530
|
-
]
|
1531
|
-
]
|
1532
|
-
},
|
1533
|
-
"S3Key": "library/solution-helper/v1/solution-helper.zip"
|
1534
|
-
},
|
1535
|
-
"Runtime": "python2.7",
|
1536
|
-
"Timeout": "300"
|
1537
|
-
}
|
1538
|
-
},
|
1539
|
-
"CreateUniqueID": {
|
1540
|
-
"Type": "Custom::CreateUUID",
|
1541
|
-
"DependsOn": "SolutionHelper",
|
1542
|
-
"Properties": {
|
1543
|
-
"ServiceToken": {
|
1544
|
-
"Fn::GetAtt": [
|
1545
|
-
"SolutionHelper",
|
1546
|
-
"Arn"
|
1547
|
-
]
|
1548
|
-
},
|
1549
|
-
"Region": {
|
1550
|
-
"Ref": "AWS::Region"
|
1551
|
-
},
|
1552
|
-
"CreateUniqueID": "true"
|
1553
|
-
}
|
1554
|
-
}
|
1555
|
-
},
|
1556
|
-
"Outputs": {
|
1557
|
-
"BadBotHoneypotEndpoint": {
|
1558
|
-
"Description": "Bad Bot Honeypot Endpoint",
|
1559
|
-
"Value": {
|
1560
|
-
"Fn::Join": ["", [
|
1561
|
-
"https://", {
|
1562
|
-
"Ref": "ApiGatewayBadBot"
|
1563
|
-
},
|
1564
|
-
".execute-api.", {
|
1565
|
-
"Ref": "AWS::Region"
|
1566
|
-
},
|
1567
|
-
".amazonaws.com/", {
|
1568
|
-
"Ref": "ApiGatewayBadBotStage"
|
1569
|
-
}
|
1570
|
-
]]
|
1571
|
-
},
|
1572
|
-
"Condition": "BadBotProtectionActivated"
|
1573
|
-
}
|
1574
|
-
}
|
1575
|
-
}
|