lono 4.2.1 → 4.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +3 -0
  3. data/lib/lono/version.rb +1 -1
  4. data/lono.gemspec +5 -3
  5. metadata +3 -79
  6. data/spec/fixtures/cfn.json +0 -369
  7. data/spec/fixtures/cfn/stack-events-complete.json +0 -1080
  8. data/spec/fixtures/cfn/stack-events-in-progress.json +0 -1080
  9. data/spec/fixtures/cfn/stack-events-update-rollback-complete.json +0 -1086
  10. data/spec/fixtures/lono_project/.gitignore +0 -1
  11. data/spec/fixtures/lono_project/Gemfile +0 -3
  12. data/spec/fixtures/lono_project/Guardfile +0 -12
  13. data/spec/fixtures/lono_project/app/definitions/base.rb +0 -10
  14. data/spec/fixtures/lono_project/app/definitions/base/more.rb +0 -7
  15. data/spec/fixtures/lono_project/app/definitions/development.rb +0 -1
  16. data/spec/fixtures/lono_project/app/definitions/production.rb +0 -1
  17. data/spec/fixtures/lono_project/app/helpers/custom_helper.rb +0 -5
  18. data/spec/fixtures/lono_project/app/partials/security_group.yml +0 -10
  19. data/spec/fixtures/lono_project/app/partials/user_data/bootstrap.sh +0 -11
  20. data/spec/fixtures/lono_project/app/templates/example.yml +0 -50
  21. data/spec/fixtures/lono_project/config/params/base/example.txt +0 -3
  22. data/spec/fixtures/lono_project/config/params/development/example.txt +0 -1
  23. data/spec/fixtures/lono_project/config/params/production/example.txt +0 -1
  24. data/spec/fixtures/lono_project/config/settings.yml +0 -31
  25. data/spec/fixtures/lono_project/config/variables/base.rb +0 -3
  26. data/spec/fixtures/lono_project/config/variables/development.rb +0 -1
  27. data/spec/fixtures/lono_project/config/variables/production.rb +0 -1
  28. data/spec/fixtures/params/baseonly/params/base/network.txt +0 -1
  29. data/spec/fixtures/params/envonly/params/development/network.txt +0 -1
  30. data/spec/fixtures/params/overlay/params/base/network.txt +0 -1
  31. data/spec/fixtures/params/overlay/params/development/network.txt +0 -1
  32. data/spec/fixtures/raw_templates/aws-waf-security-automations.template +0 -1575
  33. data/spec/lib/lono/cfn/status_spec.rb +0 -77
  34. data/spec/lib/lono/cfn_spec.rb +0 -38
  35. data/spec/lib/lono/cli_spec.rb +0 -44
  36. data/spec/lib/lono/completion_spec.rb +0 -17
  37. data/spec/lib/lono/inspect_spec.rb +0 -11
  38. data/spec/lib/lono/param/generator_spec.rb +0 -56
  39. data/spec/lib/lono/param_spec.rb +0 -13
  40. data/spec/lib/lono/setting_spec.rb +0 -47
  41. data/spec/lib/lono/template/dsl_spec.rb +0 -59
  42. data/spec/lib/lono/template_spec.rb +0 -21
  43. data/spec/spec_helper.rb +0 -62
@@ -1 +0,0 @@
1
- output
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gem 'lono'
@@ -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,10 +0,0 @@
1
- template "example" # simple single ec2 instance
2
-
3
- # template "parent"
4
- # template "network"
5
- # template "autoscaling" do
6
- # source "asg"
7
- # variables(
8
- # root_volume_size: "8"
9
- # )
10
- # end
@@ -1,7 +0,0 @@
1
- # more template declaration examples
2
- # This time in the base folder
3
-
4
- # simple single ec2 instance
5
- template "subfolder/example" do
6
- source "example"
7
- 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,5 +0,0 @@
1
- module CustomHelper
2
- def custom_helper
3
- "custom_helper value"
4
- end
5
- end
@@ -1,10 +0,0 @@
1
- InstanceSecurityGroup:
2
- Type: AWS::EC2::SecurityGroup
3
- Properties:
4
- GroupDescription: <%= @desc %>
5
- SecurityGroupIngress:
6
- - IpProtocol: tcp
7
- FromPort: <%= @port %>
8
- ToPort: <%= @port %>
9
- CidrIp:
10
- Ref: SSHLocation
@@ -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,3 +0,0 @@
1
- Ami=<%= @ami %>
2
- InstanceType=t2.micro
3
- KeyName=default
@@ -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,3 +0,0 @@
1
- @ami = "ami-base-main"
2
- @base_only = "base-only-test"
3
- @override_test = "overridden-by-env-specific-variable"
@@ -1 +0,0 @@
1
- @override_test = "overridden-by-development"
@@ -1 +0,0 @@
1
- @override_test = "overridden-by-production"
@@ -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
- }