├── LICENSE
├── README.md
└── SID402Workshop
├── 1_MonitoringSecEvents
├── README.md
├── images
│ ├── .gitkeep
│ ├── Account_Number.png
│ ├── CreateAlarm.png
│ ├── CreateAlarmOrig.png
│ ├── DeploytoAWS.png
│ ├── NACL_Addition.png
│ ├── RegionNote.png
│ ├── SettingValues.png
│ ├── SettingValuesOrig.png
│ └── diagramm1.png
├── scripts
│ └── .gitkeep
└── templates
│ ├── AutomatingSecurityEvents.json
│ ├── AutomatingSecurityEvents_StudentPolicy.json
│ └── CloudWatch_Alarms_for_CloudTrail_API_Activity.json
├── 2_ImplementSecWithIoT
├── README.md
├── images
│ ├── .gitkeep
│ ├── diagramm2.png
│ ├── image10.png
│ ├── image11.png
│ ├── image12.png
│ ├── image13.png
│ ├── image14.png
│ ├── image15.png
│ ├── image2.png
│ ├── image3.png
│ ├── image4.png
│ ├── image5-rev2.png
│ ├── image5.png
│ ├── image6.png
│ ├── image7.png
│ ├── image8.png
│ └── image9.png
├── scripts
│ ├── .gitkeep
│ ├── IoT_Security_Lab_Connect_Device.json
│ └── IoT_Security_Lab_VPC.yaml
└── templates
│ ├── .gitkeep
│ └── IoT_Security_Lab_VPC.yaml
├── 3_AutoSecRemediation
├── README.md
├── images
│ ├── .gitkeep
│ ├── diagramm3.png
│ ├── image1.png
│ ├── image11.png
│ ├── image12.png
│ ├── image3.png
│ ├── image4.png
│ ├── image5.png
│ ├── image6.png
│ ├── image7.png
│ ├── image8.png
│ └── image9.png
├── lambda
│ ├── awsconfig_lambda_security_group.py
│ └── awsconfig_lambda_security_group.py.zip
├── scripts
│ └── .gitkeep
└── templates
│ └── MonitoringSGwithAWSConfigStudentPolicy.json
└── README.md
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of
4 | this software and associated documentation files (the "Software"), to deal in
5 | the Software without restriction, including without limitation the rights to
6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
7 | the Software, and to permit persons to whom the Software is furnished to do so.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
10 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
11 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
12 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
14 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | **Odyssey:** _A long and eventful or adventurous journey or experience._
4 |
5 |
6 |
7 | This repository contains a collection of interactive content designed to demonstrate various security capabilities and controls on the AWS platform. Each Odyssey is composed of a series of modules that provide a security focused hands-on experience with AWS services including Amazon EC2, Amazon VPC, Amazon S3, AWS Lambda, Amazon VPC, AWS IoT, AWS CloudWatch and AWS CloudTrail.
8 |
9 | # Workshops
10 |
11 | - [**re:Invent 2017 - SID-402 - Implementing Security Controls in the World of Internet, Big Data, IoT and E-Commerce Platforms**](SID402Workshop) - This workshop will give participants the opportunity to take a security focused journey across various AWS services and implement automated controls along the way. You will learn how to apply AWS security controls to services such as Amazon EC2, Amazon S3, AWS Lambda, and Amazon VPC. In short, you will learn how to use the cloud to protect the cloud.
12 |
13 | We will talk about how to:
14 |
15 | - Adopt a workload-centric approach to your security strategy.
16 | - Address security issues in an cost-effective manner.
17 | - Automate your security responses to promote maturity and auditability.
18 |
19 |
20 |
21 | ## License
22 | Licensed under the MIT-0 License.
23 |
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/README.md:
--------------------------------------------------------------------------------
1 | ## re:Invent 2017 - SID402
2 |
3 | # Module 1 - Monitoring Security Events in AWS
4 |
5 | ### Introduction
6 |
7 | You have taken a lead security engineering role in helping IthaCorp improve the security posture in their AWS environment. As you work through the Security Enhancement Project, you implement a series of detective controls to improve visibility into various AWS activities.
8 |
9 | In this module, your task is to set up automatic notifications for a number of security related events in AWS. The module walks you through how to use the AWS Management Console and AWS CloudFormation to create Amazon CloudWatch alarms that is triggered when an AWS API call is made that may be of interest for security professionals.
10 |
11 | The module walks you through the process of creating alerts for one such event using AWS Console. Steps for the rest of the events have been automated in a CloudFormation template, which is provided to you. The module makes use of a number of AWS services namely AWS Identity and Access Management (IAM), AWS CloudTrail, AWS CloudWatch Alarms, AWS CloudFormation and others.
12 |
13 | ### Architecture Overview
14 |
15 | 
16 |
17 | ### Topics Covered
18 |
19 | After completing this module, you should be able to automate notifications for any of the below use cases:
20 | - Amazon S3 Bucket Activity
21 | - Security Group Configuration Changes
22 | - Network Access Control List (ACL) Changes
23 | - Network Gateway Changes
24 | - Amazon Virtual Private Cloud (VPC) Changes
25 | - Amazon EC2 Instance Changes
26 | - CloudTrail Changes
27 | - Console Sign-In Failures
28 | - Authorization Failures
29 | - IAM Policy Changes
30 |
31 | ### Prerequisites
32 |
33 | This module is targeted for IT security focused individuals who are interested in learning about automating security related events on AWS. You will need an AWS account with administrators access.
34 |
35 | To successfully complete this module, you should be familiar with AWS services including Amazon EC2, S3, VPC etc. and have a basic understanding of security groups, Network Access Control List (NACL), IAM Policies etc. You should be comfortable logging into and using the AWS Management Console and have familiarity with AWS Identity and Access Management (IAM).
36 |
37 | ### 1. Choose a Region
38 |
39 | **Tip** The AWS region name is always listed in the upper-right corner of the AWS Management Console, in the navigation bar.
40 |
41 | 
42 |
43 | Make a note of the AWS *region name*, for example, *Ireland (eu-west-1)*. For more information about regions, see: [AWS Regions and Endpoints](http://docs.aws.amazon.com/general/latest/gr/rande.html)
44 |
45 | ### 2. Complete Initial Environment Configuration
46 |
47 | In this section, you will perform configuration in the console for CloudTrail logging, CloudWatch Logs and a CloudWatch Alarm.
48 |
49 | ___Complete all the steps below unless they are marked "optional". Use arrow to expand sections marked with "(expand for details)".___
50 |
51 |
52 |
53 | 2.1. Create a CloudTrail with the Console (expand for details)
54 |
55 |
56 |
57 | - __2.1.0.__ ___IMPORTANT NOTE: YOU MAY BE TEMPTED TO USE A UNITED STATES REGION, PLEASE USE ONE OF THE REGIONS WE LIST ABOVE IN STEP 1!___
58 |
59 | - __2.1.1.__ In the AWS Management Console, Under Management Tools, Select **CloudTrail**.
60 |
61 | - __2.1.2.__ Click on **Trails** from the pane in left and click **Create trail** button.
62 |
63 | - __2.1.3.__ In the **Trail name** box, type a name for your trail such as "myCloudTrail".
64 |
65 | - __2.1.4.__ For **Apply trail to all regions?**, choose **Yes** to receive log files from all regions.
66 |
67 | - __2.1.5.__ For **Read/Write events**, choose **All**.
68 |
69 | - __2.1.6.__ For **Data Events**, do not select any buckets.
70 |
71 | - __2.1.7.__ For **Create a new S3 bucket?**, choose **Yes** to create a new bucket.
72 |
73 | - __2.1.8.__ In the **S3 bucket** field, type a name for the bucket you want to designate for log file storage such as **"myxxxxcloudtrailbucket"** substituting something unique for **xxxx**.
74 |
75 | - __2.1.9.__ Click **Create**.
The new trail will appear on the **Trails** page, which shows your trails from all regions.
76 |
77 |
78 |
79 | 2.2. Create a Log Group (expand for details)
80 |
81 |
82 |
83 | CloudTrail uses a CloudWatch Logs log group as a delivery endpoint for log events. We will create a new log group.
84 |
85 | To specify a log group using the console:
86 |
87 | - __2.2.1.__ In the AWS Management Console, Under Management Tools, Select **CloudTrail**.
88 |
89 | - __2.2.2.__ Click on **Trails** from the pane in left. Choose the name of the trail that you have created "myCloudTrail". We'll configure this trail to deliver logs to the log group that we are going to create.
90 |
91 | - __2.2.3.__ Expand **CloudWatch Logs** section and click **Configure**.
92 |
93 | - __2.2.4.__ In the **New or existing log group** box, keep the DefaultLogGroup or type a log group name (For example myTestLogGroup) to organize CloudTrail events for you to review using CloudWatch Logs, and then choose **Continue**.
94 |
95 | - __2.2.5.__ Expand **View Details** and look at the **Role Name** box. Expand **View Policy Document**. The default role policy contains the permissions required for creating a CloudWatch Logs log stream in a log group that you specify and for delivering CloudTrail events to that log stream.
96 |
97 | - __2.2.6.__ Choose **Allow**. When you are finished with these steps in the console, the CloudTrail trail will be set up to use the log group and role you specified to send events to CloudWatch Logs. If the trail you configured to use CloudWatch Logs receives log files across regions, events from all regions will be sent to the CloudWatch Logs log group that you specified.
98 |
99 |
100 |
101 | 2.3. Create a Metric Filter (Let's do it manually - expand for details)
102 |
103 |
104 |
105 | - __2.3.1.__ In the AWS Management Console, Under Management Tools, Select **CloudWatch**
106 |
107 | - __2.3.2.__ In the navigation pane on left, click **Logs**.
108 |
109 | - __2.3.3.__ In the list of log groups, select the radio button next to the log group that you created for CloudTrail log events.
110 |
111 | - __2.3.4.__ Click **Create Metric Filter**.
112 |
113 | - __2.3.5.__ On the **Define Logs Metric Filter** screen, type the following in text box **Filter Pattern**:
114 |
115 | { ($.eventSource = s3.amazonaws.com) && (($.eventName = PutBucketAcl) || ($.eventName = PutBucketPolicy) || ($.eventName = PutBucketCors) || ($.eventName = PutBucketLifecycle) || ($.eventName = PutBucketReplication) || ($.eventName = DeleteBucketPolicy) || ($.eventName = DeleteBucketCors) || ($.eventName = DeleteBucketLifecycle) || ($.eventName = DeleteBucketReplication)) }
116 |
117 | **Note:** Review this filter pattern and take a note of this. Notice that a number of S3 bucket specific events are captured. Revisit this filter pattern when you are ready to test Amazon S3 bucket activity in steps provided below in this module. Steps are provided for testing one such events but you may want to test additional filters.
118 |
119 | - __2.3.6.__ Click **Assign Metric**, and then on the Create Metric Filter and Assign a Metric screen, in the Filter Name box, delete existing text and enter **S3BucketActivity**
120 |
121 | - __2.3.7.__ Under Metric Details, in the **Metric Namespace** box, delete existing text and enter **CloudTrailMetrics**.
122 |
123 | - __2.3.8.__ In the **Metric Name** field, enter **S3BucketActivityEventCount**.
124 |
125 | - __2.3.9.__ Click **Show advanced metric settings** , then click **Metric Value**, and then ensure that the value is **1**.
126 |
127 | - __2.3.10.__ Click **Create Filter**.
128 |
129 |
130 |
131 | 2.4. Create an Alarm for the Metric Filter we just created (Let's do it manually - expand for details)
132 |
133 |
134 | These steps are a continuation of the previous steps for creating a metric filter.
135 |
136 | - __2.4.1.__ You will notice a summary of the filter that has been created with message similar to **Your filter S3BucketActivity has been created**. On the **Filters for Log_Group_Name** page, next to the **S3BucketActivity** filter name, click **Create Alarm**.
137 |
138 | - __2.4.2.__ On the **Create Alarm** page, provide the following values
139 | Name: **S3 Bucket Activity**
140 | Whenever S3BucketActivityEventCount is **>=** 1 for **1** consecutive period(s).
141 |
142 | - __2.4.3.__ For the **Period** value, select **1 Minute**.
143 |
144 | - __2.4.4.__ In the **Treat missing data as:** box, Click **good (not breaching threshold)**.
145 |
146 | - __2.4.5.__ In the **Actions** box, Click **New list** for **Send notification to:**, provide a topic name such as **NotifyMe** and provide your email address. Refer to diagrams below. **NOTE: Some companies filter subscription confirmation messages. We suggest you use a personal e-mail address.**
147 |
148 |
149 |
150 | 
151 |
152 |
153 |
154 | 
155 |
156 |
157 |
158 | - __2.4.6.__ When you are done, click **Create Alarm**.
159 |
160 | - __2.4.7.__ You will receive an email from **AWS Notification** at the email address provided in the **Email list**. Click on **Confirm subscription** link provided in the email. **NOTE: You must click on Confirm Subscription before you proceed further!**
161 |
162 | - __2.4.8.__ Click on **View Alarm**.
163 |
164 |
165 | ### 3. Create Security Alarms Using AWS CloudFormation
166 |
167 | In the previous steps you have learnt how to create a metric filter in CloudWatch and how to create an alarm for the metric via the AWS console. Creation of metric filters and corresponding alarms for the remaining security events described in the overview section has been automated for you using AWS CloudFormation template. Follow the steps below:
168 |
169 | ##### Launch the CloudFormation Stack in the preferred region:
170 |
171 | ___Hold the "Control" key while clicking and open the launch link in a new tab___
172 |
173 | Region| Launch
174 | ------|-----
175 | Ireland (eu-west-1) | [](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?stackName=SID402-CWLforCloudTrailAPIActivity&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/CloudWatch_Alarms_for_CloudTrail_API_Activity.json)
176 | London (eu-west-2) | [](https://console.aws.amazon.com/cloudformation/home?region=eu-west-2#/stacks/new?stackName=SID402-CWLforCloudTrailAPIActivity&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/CloudWatch_Alarms_for_CloudTrail_API_Activity.json)
177 | Singapore (ap-southeast-1) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-1#/stacks/new?stackName=SID402-CWLforCloudTrailAPIActivity&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/CloudWatch_Alarms_for_CloudTrail_API_Activity.json)
178 | Sydney (ap-southeast-2) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?stackName=SID402-CWLforCloudTrailAPIActivity&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/CloudWatch_Alarms_for_CloudTrail_API_Activity.json)
179 | Tokyo (ap-northeast-1) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?stackName=SID402-CWLforCloudTrailAPIActivity&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/CloudWatch_Alarms_for_CloudTrail_API_Activity.json)
180 | Seoul (ap-northeast-2) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?stackName=SID402-CWLforCloudTrailAPIActivity&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/CloudWatch_Alarms_for_CloudTrail_API_Activity.json)
181 |
182 | **Note:** Review the contents of the template to understand the metric filter and alarm creation via CloudFormation.
183 |
184 | __3.1.__ On the Select Template screen, click **Next**.
185 |
186 | __3.2.__ On the **Specify Details** page, provide the email address where you want to receive notifications, and the enter name of the log group name that you used when you configured CloudTrail log file delivery to CloudWatch Logs.
187 |
188 | __3.3.__ Click **Next**.
189 |
190 | __3.4.__ On the **Options** page, you can create tags or configure other advanced options. These are not required for this module.
191 |
192 | __3.5.__ Click **Next**.
193 |
194 | __3.6.__ Click **Create**. The stack will be created in a few minutes.
195 |
196 | __3.7.__ If not already selected, select your stack by clicking on the check box to the left of your stack.
197 |
198 | __3.8.__ Click on the **Events** tab and refresh periodically to monitor the creation of your stack.
199 |
200 | __3.9.__ The CloudFormation template also creates a SNS topic for you to get update on other email address provided by you in previous steps. You will receive an email from **AWS Notification**, Click on **Confirm subscription** link provided in the email.
201 |
202 | **_Note:_** _Before proceeding, make sure that you receive the SNS **AWS Notification** email confirmation and follow the **Confirm subscription** link provided in the email._
203 |
204 | When AWS CloudFormation is finished creating the stack, the status will show CREATE_COMPLETE. This CloudFormation stack has created a number of security metric filters and related alarms for you. We'll test these events in the subsequent steps.
205 |
206 | ### 4. And that's it. We are all set and now the fun part!! Let's generate some events and see what happens
207 |
208 | We'll create a number of security events in this section of the module. The resources such as a VPC, Subnets, Security Groups, EC2 Instance, IAM Policy etc. The module covers a number of different events. We are providing a CloudFormation script that creates some resources like networking components (VPC, Subnet, NACL,Security Group etc.), S3 bucket, IAM entities, EC2 instance etc. Manual Steps for a limited number of events are also provided in this section. Feel free to test remaining security events in the time left for the module.
209 | **Note:** - It may take up to 15 minutes to receive the alarm in the CloudWatch console and email. You are advised to continue going through the steps below while waiting for an alarm to appear.
210 |
211 | __4.1.__ Test Multiple Events with a CloudFormation Stack
212 |
213 | ___Launch the CloudFormation Stack in the same region you chose in step 3.___
214 |
215 | ___Hold the "Control" key while clicking and open the launch link in a new tab.___
216 |
217 | Region| Launch
218 | ------|-----
219 | Ireland (eu-west-1) | [](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?stackName=SID402-AutomatingSecurityEvents&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/AutomatingSecurityEvents.json)
220 | London (eu-west-2) | [](https://console.aws.amazon.com/cloudformation/home?region=eu-west-2#/stacks/new?stackName=SID402-AutomatingSecurityEvents&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/AutomatingSecurityEvents.json)
221 | Singapore (ap-southeast-1) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-1#/stacks/new?stackName=SID402-AutomatingSecurityEvents&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/AutomatingSecurityEvents.json)
222 | Sydney (ap-southeast-2) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?stackName=SID402-AutomatingSecurityEvents&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/AutomatingSecurityEvents.json)
223 | Tokyo (ap-northeast-1) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?stackName=SID402-AutomatingSecurityEvents&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/AutomatingSecurityEvents.json)
224 | Seoul (ap-northeast-2) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?stackName=SID402-AutomatingSecurityEvents&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/templates/AutomatingSecurityEvents.json)
225 |
226 | - __4.1.1__ On the Select Template screen, click **Next**.
227 | - __4.1.2__ Click Next.
228 | - __4.1.3__ On the Options page, you can create tags or configure other advanced options. These are not required for this module.
229 | - __4.1.4__ Click **Next**.
230 | - __4.1.5__ Select **I acknowledge that AWS CloudFormation might create IAM resources.** and click **Create**. The stack will be created in a few minutes.
231 | - __4.1.6__ If not already selected, select your stack by clicking on the check box to the left of your stack.
232 | - __4.1.7__ Click on the Events tab and refresh periodically to monitor the creation of your stack.
233 |
234 |
235 | #### 4.2. Test Amazon S3 bucket Activity
236 | - __4.2.1__ In the AWS Management Console, under **Storage**, select **S3**.
237 |
238 | - __4.2.2__ Select the bucket **securityautomationtestbucketxxxx** and click on **Permissions** tab.
239 |
240 | - __4.2.3__ Under **Public access**, click the radio button **Everyone** and in the pop up box, select few permissions like **List Objects** or **Read bucket permission**. Do **not** allow **Write** permissions for **Everyone**.
241 |
242 | - __4.2.4__ Click **Save**
243 |
244 | - __4.2.5__ You will receive an Alarm **S3 bucket Activity** via email.
245 | **Note:** - If you have not received email notification, navigate to AWS Console, Services, CloudWatch and click on **Alarms**. If this shows **Config Status** as **Pending confirmation** then that means you have not yet confirmed SNS subscription yet. Refer to your email and subscribe to notifications from this module.
246 |
247 | - __4.2.6__ You can also view the status of Alarm via AWS CloudWatch console. Navigate to AWS Console, Services, Cloudwatch and click on **Alarms**. You can also see the history of an alarm from the **History** tab in the bottom pane.
248 |
249 | #### 4.3. Test Security Group Configuration changes
250 |
251 | - __4.3.1__ In the AWS Management Console, on the **Services** menu, click **EC2**.
252 |
253 | - __4.3.2__ Click on **Security Groups** under **NETWORK & SECURITY** section from the left pane.
254 |
255 | - __4.3.3__ Select **SID402-AutomatingSecurityEvents-InstanceSecurityGroup** from the list and click on **Inbound** tab on the bottom pane.
256 |
257 | - __4.3.4__ click **Edit**.
258 |
259 | - __4.3.5__ Click **Add Rule**. A new row is created.
260 |
261 | - __4.3.6__ Select **Type** of rule from the list, specify a port range (for example 8080 or 49152-50000) and a CIDR range for new inbound rule. Set Source to 0.0.0.0/0 if you are not sure.
262 |
263 | - __4.3.7__ Click **save**
264 |
265 | - __4.3.8__ You will receive an Alarm **CloudTrailSecurityGroupChanges** via email.
266 |
267 | - __4.3.9__ You can also view the status of Alarm via AWS CloudWatch console.
268 |
269 | #### 4.4. Test EC2 Instance Changes
270 |
271 | - __4.4.1__ In the AWS Management Console, on the **Services** menu, click **EC2**.
272 |
273 | - __4.4.2__ Select SecurityTest EC2 instance by clicking on **Instances** In the navigation pane and click on **Actions** button at the top
274 |
275 | - __4.4.3__ Click on **Instance State** and then **Stop**. A Pop-up window for confirmation appears, click **Yes, Stop**.
276 |
277 | - __4.4.4__ You will receive an Alarm **CloudTrailEC2InstanceChanges** via email.
278 |
279 | - __4.4.5__ You can also view the status of Alarm via AWS CloudWatch console.
280 |
281 | #### 4.5. Test IAM Policy Changes
282 |
283 | - __4.5.1__ In the AWS Management Console, on the **Services** menu, click **IAM**.
284 |
285 | - __4.5.2__ Click on **Policies** on the left pane.
286 |
287 | - __4.5.3__ Click **Create Policy**.
288 |
289 | - __4.5.4__ **In the Service section**, click “Choose a Service” under the tab **Visual Editor** and select **EC2**.
290 |
291 | - __4.5.5__ In the **Actions** section, click **Select actions**, check **All EC2 actions (ec2:\*)** and collapse the section by clicking **close**.
292 |
293 | - __4.5.6__ In the **Resources section**, click to expand the section, click radio button **All resources** and click **close** to collapse the section.
294 |
295 | - __4.5.7__ Click **Review Policy** and provide your policy a name such as **Allow_all_ec2** and click **Create Policy** button below.
296 |
297 | - __4.5.8__ You will receive an Alarm **CloudTrailIAMPolicyChanges** via email.
298 |
299 | - __4.5.9__ You can also view the status of Alarm via AWS CloudWatch console.
300 |
301 |
302 | 5. Optional Test Scenarios (expand for details)
303 |
304 |
305 | The following test events are optional and should only be completed after you have completed all modules in this workshop.
306 |
307 | #### 5.1. Test Network Access Control List (NACL) Changes
308 |
309 | - __5.1.1.__ In the AWS Management Console, on the **Services** menu, click **VPC**.
310 |
311 | - __5.1.2.__ Click on **Network ACLs** from the list of Amazon VPC resources. A list of Network ACLs appears.
312 |
313 | - __5.1.3.__ Select a NACL which is associated with a Subnet, click on **Inbound Rules** or **Outbound Rules** tab and Click **Edit** from the bottom pane.
314 |
315 | - __5.1.4.__ Click on **Add another rule** button and enter the following values in the bottom row and click **Save**.
316 |
317 | 
318 |
319 | - __5.1.5.__ You will receive an Alarm **CloudTrailNetworkAclChanges** via email.
320 |
321 | - __5.1.6.__ You can also view the status of Alarm via AWS CloudWatch console.
322 |
323 | #### 5.2. Test Network Gateway Changes
324 |
325 | - __5.2.1.__ In the AWS Management Console, on the **Services** menu, click **VPC**.
326 |
327 | - __5.2.2.__ Click on **Internet Gateways** from the list of Amazon VPC resources. A list of Internet Gateway appears.
328 |
329 | - __5.2.3.__ Click on **Create Internet Gateway** button.
330 |
331 | - __5.2.4.__ Provide a **Name Tag** such as myInternetGateway and click **Yes, Create**.
332 |
333 | - __5.2.5.__ You will receive an Alarm **CloudTrailGatewayChanges** via email.
334 |
335 | - __5.2.6.__ You can also view the status of Alarm via AWS CloudWatch console.
336 |
337 | #### 5.3. Test Amazon Virtual Private Cloud (VPC) Changes
338 |
339 | - __5.3.1.__ In the AWS Management Console, on the **Services** menu, click **VPC**.
340 |
341 | - __5.3.2.__ Click on **Your VPCs** from the list of Amazon VPC resources. A list of VPC appears.
342 |
343 | - __5.3.3.__ Select a VPC and click **Actions** and than click **Edit DNS Resolution**.
344 |
345 | - __5.3.4.__ On **Edit DNS Resolution** confirmation message box, select **No** and click **Save**.
346 |
347 | - __5.3.5.__ You will receive an Alarm **CloudTrailVpcChanges** via email.
348 |
349 | - __5.3.6.__ You can also view the status of Alarm via AWS CloudWatch console.
350 |
351 | #### 5.4. Test Console Sign-In Failures
352 |
353 | - __5.4.1.__ Note down the AWS account number from the AWS Console. The number is displayed on the top right.
354 |
355 | 
356 |
357 | - __5.4.2.__ Open a new window in different browser or use a "New Incognito Window/New Private Window" feature of your browser.
358 |
359 | - __5.4.3.__ Type the following in address bar with **AWS-account-ID-or-alias** replaced by the AWS account number noted above.
360 |
361 | ```
362 | https://AWS-account-ID-or-alias.signin.aws.amazon.com/console
363 | ```
364 |
365 | - __5.4.4.__ A new sign in page appears, Type a random **User Name** and **Password**.
366 |
367 | - __5.4.5.__ Click **Sign in**. Repeat these steps for at least three times.
368 |
369 | - __5.4.6.__ You will receive a sign in failure with the message:
370 | ````
371 | Your authentication information is incorrect. Please try again
372 | ````
373 |
374 | - __5.4.7.__ You will receive an Alarm **CloudTrailConsoleSignInFailures** via email.
375 |
376 | - __5.4.8.__ You can also view the status of Alarm via AWS CloudWatch console.
377 |
378 | #### 5.5. Test Authorization Failures
379 |
380 | - __5.5.1.__ In the AWS Management Console, under **Storage** menu, select **S3**.
381 |
382 | - __5.5.2.__ Select the bucket **securityautomationtestbucketxxxx** and upload a file into this bucket.
383 |
384 | - __5.5.3.__ Click on the file you just uploaded and grap the URL from the Link.
385 |
386 | - __5.5.4.__ Try opening the URL from an Incognito browser (Private browser). You should receive an authorization ofailure. You will receive an Alarm **CloudTrailAuthorizationFailures** via email.
387 |
388 | - __5.5.5.__ You can also view the status of Alarm via AWS CloudWatch console.
389 |
390 | #### 5.6. Test CloudTrail Changes
391 |
392 | - __5.6.1.__ In the AWS Management Console, on the **Services** menu, click **CloudTrail**.
393 |
394 | - __5.6.2.__ Click **Trails** on the left pane and select the trail (myCloudTrail) that you have created in this module.
395 |
396 | - __5.6.3.__ Click on the pencil next to **Trail settings** to edit the behavior.
397 |
398 | - __5.6.4.__ For **Apply trail to all regions**, select radio button **No** and click **save**.
399 |
400 | - __5.6.5.__ You will receive an Alarm **CloudTrailChanges** via email.
401 |
402 | - __5.6.6.__ You can also view the status of Alarm via AWS CloudWatch console.
403 |
404 |
405 | ### Conclusion
406 |
407 | Congratulations! You have successfully created a Trail in AWS CloudTrail console, create a log group in CloudWatch console that receives logs from CloudTrail, created a number of metric filters and corresponding alarms for automated notifications. You have also learned how to automate the steps via AWS CloudFormation. You now know how to automate a number of Security related events in AWS such as:
408 |
409 | - Amazon S3 Bucket Activity
410 | - Security Group Configuration Changes
411 | - Network Access Control List (ACL) Changes
412 | - Network Gateway Changes
413 | - Amazon Virtual Private Cloud (VPC) Changes
414 | - Amazon EC2 Instance Changes
415 | - CloudTrail Changes
416 | - Console Sign-In Failures
417 | - Authorization Failures
418 | - IAM Policy Changes
419 |
420 | ### [Continue on to Module 2](https://github.com/awslabs/aws-security-odyssey/tree/master/SID402Workshop/2_ImplementSecWithIoT)
421 |
422 | ### Clean Up
423 | ___Complete clean up at the end of the Workshop___
424 |
425 | ### Additional Resources
426 |
427 | - For more information about AWS CloudTrail, see
428 | - For more information about Amazon CloudWatch, see
429 | - For more information about AWS CloudFormation, see
430 | - For more information about AWS Security - Network Security, refer to Whitepaper at
431 |
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/.gitkeep
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/Account_Number.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/Account_Number.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/CreateAlarm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/CreateAlarm.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/CreateAlarmOrig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/CreateAlarmOrig.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/DeploytoAWS.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/DeploytoAWS.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/NACL_Addition.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/NACL_Addition.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/RegionNote.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/RegionNote.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/SettingValues.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/SettingValues.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/SettingValuesOrig.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/SettingValuesOrig.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/images/diagramm1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/images/diagramm1.png
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/scripts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/1_MonitoringSecEvents/scripts/.gitkeep
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/templates/AutomatingSecurityEvents.json:
--------------------------------------------------------------------------------
1 |
2 | {
3 | "AWSTemplateFormatVersion" : "2010-09-09",
4 |
5 | "Description" : "AWS CloudFormation Sample Template VPC_Single_Instance_In_Subnet: Creates a VPC and add an EC2 instance with an Elastic IP address and a security group. **WARNING** This template creates an Amazon EC2 instance. You will be billed for the AWS resources used if you create a stack from this template.",
6 |
7 | "Mappings" : {
8 | "Region2Examples" : {
9 | "us-east-1" : { "Examples" : "https://s3.amazonaws.com/cloudformation-examples-us-east-1" },
10 | "us-east-2" : { "Examples" : "https://s3-us-east-2.amazonaws.com/cloudformation-examples-us-east-2" },
11 | "us-west-2" : { "Examples" : "https://s3-us-west-2.amazonaws.com/cloudformation-examples-us-west-2" },
12 | "us-west-1" : { "Examples" : "https://s3-us-west-1.amazonaws.com/cloudformation-examples-us-west-1" },
13 | "eu-west-1" : { "Examples" : "https://s3-eu-west-1.amazonaws.com/cloudformation-examples-eu-west-1" },
14 | "eu-west-2" : { "Examples" : "https://s3-eu-west-2.amazonaws.com/cloudformation-examples-eu-west-2" },
15 | "eu-central-1" : { "Examples" : "https://s3-eu-central-1.amazonaws.com/cloudformation-examples-eu-central-1" },
16 | "ap-southeast-1" : { "Examples" : "https://s3-ap-southeast-1.amazonaws.com/cloudformation-examples-ap-southeast-1" },
17 | "ap-northeast-1" : { "Examples" : "https://s3-ap-northeast-1.amazonaws.com/cloudformation-examples-ap-northeast-1" },
18 | "ap-northeast-2" : { "Examples" : "https://s3-ap-northeast-2.amazonaws.com/cloudformation-examples-ap-northeast-2" },
19 | "ap-southeast-2" : { "Examples" : "https://s3-ap-southeast-2.amazonaws.com/cloudformation-examples-ap-southeast-2" },
20 | "ap-south-1" : { "Examples" : "https://s3-ap-south-1.amazonaws.com/cloudformation-examples-ap-south-1" },
21 | "sa-east-1" : { "Examples" : "https://s3-sa-east-1.amazonaws.com/cloudformation-examples-sa-east-1" },
22 | "cn-north-1" : { "Examples" : "https://s3.cn-north-1.amazonaws.com.cn/cloudformation-examples-cn-north-1" }
23 | }
24 | ,
25 | "AWSInstanceType2Arch" : {
26 | "t1.micro" : { "Arch" : "PV64" },
27 | "t2.nano" : { "Arch" : "HVM64" },
28 | "t2.micro" : { "Arch" : "HVM64" },
29 | "t2.small" : { "Arch" : "HVM64" },
30 | "t2.medium" : { "Arch" : "HVM64" },
31 | "t2.large" : { "Arch" : "HVM64" },
32 | "m1.small" : { "Arch" : "PV64" },
33 | "m1.medium" : { "Arch" : "PV64" },
34 | "m1.large" : { "Arch" : "PV64" },
35 | "m1.xlarge" : { "Arch" : "PV64" },
36 | "m2.xlarge" : { "Arch" : "PV64" },
37 | "m2.2xlarge" : { "Arch" : "PV64" },
38 | "m2.4xlarge" : { "Arch" : "PV64" },
39 | "m3.medium" : { "Arch" : "HVM64" },
40 | "m3.large" : { "Arch" : "HVM64" },
41 | "m3.xlarge" : { "Arch" : "HVM64" },
42 | "m3.2xlarge" : { "Arch" : "HVM64" },
43 | "m4.large" : { "Arch" : "HVM64" },
44 | "m4.xlarge" : { "Arch" : "HVM64" },
45 | "m4.2xlarge" : { "Arch" : "HVM64" },
46 | "m4.4xlarge" : { "Arch" : "HVM64" },
47 | "m4.10xlarge" : { "Arch" : "HVM64" },
48 | "c1.medium" : { "Arch" : "PV64" },
49 | "c1.xlarge" : { "Arch" : "PV64" },
50 | "c3.large" : { "Arch" : "HVM64" },
51 | "c3.xlarge" : { "Arch" : "HVM64" },
52 | "c3.2xlarge" : { "Arch" : "HVM64" },
53 | "c3.4xlarge" : { "Arch" : "HVM64" },
54 | "c3.8xlarge" : { "Arch" : "HVM64" },
55 | "c4.large" : { "Arch" : "HVM64" },
56 | "c4.xlarge" : { "Arch" : "HVM64" },
57 | "c4.2xlarge" : { "Arch" : "HVM64" },
58 | "c4.4xlarge" : { "Arch" : "HVM64" },
59 | "c4.8xlarge" : { "Arch" : "HVM64" },
60 | "g2.2xlarge" : { "Arch" : "HVMG2" },
61 | "g2.8xlarge" : { "Arch" : "HVMG2" },
62 | "r3.large" : { "Arch" : "HVM64" },
63 | "r3.xlarge" : { "Arch" : "HVM64" },
64 | "r3.2xlarge" : { "Arch" : "HVM64" },
65 | "r3.4xlarge" : { "Arch" : "HVM64" },
66 | "r3.8xlarge" : { "Arch" : "HVM64" },
67 | "i2.xlarge" : { "Arch" : "HVM64" },
68 | "i2.2xlarge" : { "Arch" : "HVM64" },
69 | "i2.4xlarge" : { "Arch" : "HVM64" },
70 | "i2.8xlarge" : { "Arch" : "HVM64" },
71 | "d2.xlarge" : { "Arch" : "HVM64" },
72 | "d2.2xlarge" : { "Arch" : "HVM64" },
73 | "d2.4xlarge" : { "Arch" : "HVM64" },
74 | "d2.8xlarge" : { "Arch" : "HVM64" },
75 | "hi1.4xlarge" : { "Arch" : "HVM64" },
76 | "hs1.8xlarge" : { "Arch" : "HVM64" },
77 | "cr1.8xlarge" : { "Arch" : "HVM64" },
78 | "cc2.8xlarge" : { "Arch" : "HVM64" }
79 | },
80 |
81 | "AWSInstanceType2NATArch" : {
82 | "t1.micro" : { "Arch" : "NATPV64" },
83 | "t2.nano" : { "Arch" : "NATHVM64" },
84 | "t2.micro" : { "Arch" : "NATHVM64" },
85 | "t2.small" : { "Arch" : "NATHVM64" },
86 | "t2.medium" : { "Arch" : "NATHVM64" },
87 | "t2.large" : { "Arch" : "NATHVM64" },
88 | "m1.small" : { "Arch" : "NATPV64" },
89 | "m1.medium" : { "Arch" : "NATPV64" },
90 | "m1.large" : { "Arch" : "NATPV64" },
91 | "m1.xlarge" : { "Arch" : "NATPV64" },
92 | "m2.xlarge" : { "Arch" : "NATPV64" },
93 | "m2.2xlarge" : { "Arch" : "NATPV64" },
94 | "m2.4xlarge" : { "Arch" : "NATPV64" },
95 | "m3.medium" : { "Arch" : "NATHVM64" },
96 | "m3.large" : { "Arch" : "NATHVM64" },
97 | "m3.xlarge" : { "Arch" : "NATHVM64" },
98 | "m3.2xlarge" : { "Arch" : "NATHVM64" },
99 | "m4.large" : { "Arch" : "NATHVM64" },
100 | "m4.xlarge" : { "Arch" : "NATHVM64" },
101 | "m4.2xlarge" : { "Arch" : "NATHVM64" },
102 | "m4.4xlarge" : { "Arch" : "NATHVM64" },
103 | "m4.10xlarge" : { "Arch" : "NATHVM64" },
104 | "c1.medium" : { "Arch" : "NATPV64" },
105 | "c1.xlarge" : { "Arch" : "NATPV64" },
106 | "c3.large" : { "Arch" : "NATHVM64" },
107 | "c3.xlarge" : { "Arch" : "NATHVM64" },
108 | "c3.2xlarge" : { "Arch" : "NATHVM64" },
109 | "c3.4xlarge" : { "Arch" : "NATHVM64" },
110 | "c3.8xlarge" : { "Arch" : "NATHVM64" },
111 | "c4.large" : { "Arch" : "NATHVM64" },
112 | "c4.xlarge" : { "Arch" : "NATHVM64" },
113 | "c4.2xlarge" : { "Arch" : "NATHVM64" },
114 | "c4.4xlarge" : { "Arch" : "NATHVM64" },
115 | "c4.8xlarge" : { "Arch" : "NATHVM64" },
116 | "g2.2xlarge" : { "Arch" : "NATHVMG2" },
117 | "g2.8xlarge" : { "Arch" : "NATHVMG2" },
118 | "r3.large" : { "Arch" : "NATHVM64" },
119 | "r3.xlarge" : { "Arch" : "NATHVM64" },
120 | "r3.2xlarge" : { "Arch" : "NATHVM64" },
121 | "r3.4xlarge" : { "Arch" : "NATHVM64" },
122 | "r3.8xlarge" : { "Arch" : "NATHVM64" },
123 | "i2.xlarge" : { "Arch" : "NATHVM64" },
124 | "i2.2xlarge" : { "Arch" : "NATHVM64" },
125 | "i2.4xlarge" : { "Arch" : "NATHVM64" },
126 | "i2.8xlarge" : { "Arch" : "NATHVM64" },
127 | "d2.xlarge" : { "Arch" : "NATHVM64" },
128 | "d2.2xlarge" : { "Arch" : "NATHVM64" },
129 | "d2.4xlarge" : { "Arch" : "NATHVM64" },
130 | "d2.8xlarge" : { "Arch" : "NATHVM64" },
131 | "hi1.4xlarge" : { "Arch" : "NATHVM64" },
132 | "hs1.8xlarge" : { "Arch" : "NATHVM64" },
133 | "cr1.8xlarge" : { "Arch" : "NATHVM64" },
134 | "cc2.8xlarge" : { "Arch" : "NATHVM64" }
135 | }
136 | ,
137 | "AWSRegionArch2AMI" : {
138 | "us-east-1" : {"PV64" : "ami-2a69aa47", "HVM64" : "ami-6869aa05", "HVMG2" : "ami-2e5e9c43"},
139 | "us-east-2" : {"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-f6035893", "HVMG2" : "NOT_SUPPORTED"},
140 | "us-west-2" : {"PV64" : "ami-7f77b31f", "HVM64" : "ami-7172b611", "HVMG2" : "ami-83b770e3"},
141 | "us-west-1" : {"PV64" : "ami-a2490dc2", "HVM64" : "ami-31490d51", "HVMG2" : "ami-fd76329d"},
142 | "eu-west-1" : {"PV64" : "ami-4cdd453f", "HVM64" : "ami-f9dd458a", "HVMG2" : "ami-b9bd25ca"},
143 | "eu-west-2" : {"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-1a7f6d7e", "HVMG2" : "NOT_SUPPORTED"},
144 | "eu-central-1" : {"PV64" : "ami-6527cf0a", "HVM64" : "ami-ea26ce85", "HVMG2" : "ami-7f04ec10"},
145 | "ap-northeast-1" : {"PV64" : "ami-3e42b65f", "HVM64" : "ami-374db956", "HVMG2" : "ami-e0ee1981"},
146 | "ap-northeast-2" : {"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-2b408b45", "HVMG2" : "NOT_SUPPORTED"},
147 | "ap-southeast-1" : {"PV64" : "ami-df9e4cbc", "HVM64" : "ami-a59b49c6", "HVMG2" : "ami-0cb5676f"},
148 | "ap-southeast-2" : {"PV64" : "ami-63351d00", "HVM64" : "ami-dc361ebf", "HVMG2" : "ami-a71c34c4"},
149 | "ap-south-1" : {"PV64" : "NOT_SUPPORTED", "HVM64" : "ami-ffbdd790", "HVMG2" : "ami-f5b2d89a"},
150 | "sa-east-1" : {"PV64" : "ami-1ad34676", "HVM64" : "ami-6dd04501", "HVMG2" : "NOT_SUPPORTED"},
151 | "cn-north-1" : {"PV64" : "ami-77559f1a", "HVM64" : "ami-8e6aa0e3", "HVMG2" : "NOT_SUPPORTED"}
152 | }
153 |
154 | },
155 |
156 | "Resources" : {
157 |
158 | "LogsRole":{
159 | "Type":"AWS::IAM::Role",
160 | "Properties":{
161 | "AssumeRolePolicyDocument":{
162 | "Version":"2012-10-17",
163 | "Statement":[
164 | {
165 | "Effect":"Allow",
166 | "Principal":{
167 | "Service":[
168 | "cloudtrail.amazonaws.com"
169 | ]
170 | },
171 | "Action":[
172 | "sts:AssumeRole"
173 | ]
174 | }
175 | ]
176 | }
177 | }
178 | }
179 | ,
180 | "VPC" : {
181 | "Type" : "AWS::EC2::VPC",
182 | "Properties" : {
183 | "CidrBlock" : "10.0.0.0/16",
184 | "Tags" : [ {"Key" : "Application", "Value" : { "Ref" : "AWS::StackId"} } ]
185 | }
186 | },
187 |
188 | "Subnet" : {
189 | "Type" : "AWS::EC2::Subnet",
190 | "Properties" : {
191 | "VpcId" : { "Ref" : "VPC" },
192 | "CidrBlock" : "10.0.0.0/24",
193 | "Tags" : [ {"Key" : "Application", "Value" : { "Ref" : "AWS::StackId"} } ]
194 | }
195 | },
196 |
197 | "InternetGateway" : {
198 | "Type" : "AWS::EC2::InternetGateway",
199 | "Properties" : {
200 | "Tags" : [ {"Key" : "Application", "Value" : { "Ref" : "AWS::StackId"} } ]
201 | }
202 | },
203 |
204 | "AttachGateway" : {
205 | "Type" : "AWS::EC2::VPCGatewayAttachment",
206 | "Properties" : {
207 | "VpcId" : { "Ref" : "VPC" },
208 | "InternetGatewayId" : { "Ref" : "InternetGateway" }
209 | }
210 | },
211 |
212 | "RouteTable" : {
213 | "Type" : "AWS::EC2::RouteTable",
214 | "Properties" : {
215 | "VpcId" : {"Ref" : "VPC"},
216 | "Tags" : [ {"Key" : "Application", "Value" : { "Ref" : "AWS::StackId"} } ]
217 | }
218 | },
219 |
220 | "Route" : {
221 | "Type" : "AWS::EC2::Route",
222 | "DependsOn" : "AttachGateway",
223 | "Properties" : {
224 | "RouteTableId" : { "Ref" : "RouteTable" },
225 | "DestinationCidrBlock" : "0.0.0.0/0",
226 | "GatewayId" : { "Ref" : "InternetGateway" }
227 | }
228 | },
229 |
230 | "SubnetRouteTableAssociation" : {
231 | "Type" : "AWS::EC2::SubnetRouteTableAssociation",
232 | "Properties" : {
233 | "SubnetId" : { "Ref" : "Subnet" },
234 | "RouteTableId" : { "Ref" : "RouteTable" }
235 | }
236 | },
237 |
238 | "NetworkAcl" : {
239 | "Type" : "AWS::EC2::NetworkAcl",
240 | "Properties" : {
241 | "VpcId" : {"Ref" : "VPC"},
242 | "Tags" : [ {"Key" : "Application", "Value" : { "Ref" : "AWS::StackId"} } ]
243 | }
244 | },
245 |
246 | "InboundHTTPNetworkAclEntry" : {
247 | "Type" : "AWS::EC2::NetworkAclEntry",
248 | "Properties" : {
249 | "NetworkAclId" : {"Ref" : "NetworkAcl"},
250 | "RuleNumber" : "100",
251 | "Protocol" : "6",
252 | "RuleAction" : "allow",
253 | "Egress" : "false",
254 | "CidrBlock" : "0.0.0.0/0",
255 | "PortRange" : {"From" : "80", "To" : "80"}
256 | }
257 | },
258 |
259 | "InboundSSHNetworkAclEntry" : {
260 | "Type" : "AWS::EC2::NetworkAclEntry",
261 | "Properties" : {
262 | "NetworkAclId" : {"Ref" : "NetworkAcl"},
263 | "RuleNumber" : "101",
264 | "Protocol" : "6",
265 | "RuleAction" : "allow",
266 | "Egress" : "false",
267 | "CidrBlock" : "0.0.0.0/0",
268 | "PortRange" : {"From" : "22", "To" : "22"}
269 | }
270 | },
271 |
272 | "InboundResponsePortsNetworkAclEntry" : {
273 | "Type" : "AWS::EC2::NetworkAclEntry",
274 | "Properties" : {
275 | "NetworkAclId" : {"Ref" : "NetworkAcl"},
276 | "RuleNumber" : "102",
277 | "Protocol" : "6",
278 | "RuleAction" : "allow",
279 | "Egress" : "false",
280 | "CidrBlock" : "0.0.0.0/0",
281 | "PortRange" : {"From" : "1024", "To" : "65535"}
282 | }
283 | },
284 |
285 | "OutBoundHTTPNetworkAclEntry" : {
286 | "Type" : "AWS::EC2::NetworkAclEntry",
287 | "Properties" : {
288 | "NetworkAclId" : {"Ref" : "NetworkAcl"},
289 | "RuleNumber" : "100",
290 | "Protocol" : "6",
291 | "RuleAction" : "allow",
292 | "Egress" : "true",
293 | "CidrBlock" : "0.0.0.0/0",
294 | "PortRange" : {"From" : "80", "To" : "80"}
295 | }
296 | },
297 |
298 | "OutBoundHTTPSNetworkAclEntry" : {
299 | "Type" : "AWS::EC2::NetworkAclEntry",
300 | "Properties" : {
301 | "NetworkAclId" : {"Ref" : "NetworkAcl"},
302 | "RuleNumber" : "101",
303 | "Protocol" : "6",
304 | "RuleAction" : "allow",
305 | "Egress" : "true",
306 | "CidrBlock" : "0.0.0.0/0",
307 | "PortRange" : {"From" : "443", "To" : "443"}
308 | }
309 | },
310 |
311 | "OutBoundResponsePortsNetworkAclEntry" : {
312 | "Type" : "AWS::EC2::NetworkAclEntry",
313 | "Properties" : {
314 | "NetworkAclId" : {"Ref" : "NetworkAcl"},
315 | "RuleNumber" : "102",
316 | "Protocol" : "6",
317 | "RuleAction" : "allow",
318 | "Egress" : "true",
319 | "CidrBlock" : "0.0.0.0/0",
320 | "PortRange" : {"From" : "1024", "To" : "65535"}
321 | }
322 | },
323 |
324 | "SubnetNetworkAclAssociation" : {
325 | "Type" : "AWS::EC2::SubnetNetworkAclAssociation",
326 | "Properties" : {
327 | "SubnetId" : { "Ref" : "Subnet" },
328 | "NetworkAclId" : { "Ref" : "NetworkAcl" }
329 | }
330 | },
331 |
332 | "IPAddress" : {
333 | "Type" : "AWS::EC2::EIP",
334 | "DependsOn" : "AttachGateway",
335 | "Properties" : {
336 | "Domain" : "vpc",
337 | "InstanceId" : { "Ref" : "WebServerInstance" }
338 | }
339 | },
340 |
341 | "InstanceSecurityGroup" : {
342 | "Type" : "AWS::EC2::SecurityGroup",
343 | "Properties" : {
344 | "VpcId" : { "Ref" : "VPC" },
345 | "GroupDescription" : "Enable SSH access via port 22",
346 | "SecurityGroupIngress" : [
347 | {"IpProtocol" : "tcp", "FromPort" : "22", "ToPort" : "22", "CidrIp" : "0.0.0.0/0"},
348 | { "IpProtocol" : "tcp", "FromPort" : "80", "ToPort" : "80", "CidrIp" : "0.0.0.0/0"}
349 | ]
350 | }
351 | },
352 |
353 |
354 | "WebServerInstance" : {
355 | "Type" : "AWS::EC2::Instance",
356 | "DependsOn" : "AttachGateway",
357 | "Metadata" : {
358 | "Comment" : "Install a simple application",
359 | "AWS::CloudFormation::Init" : {
360 | "config" : {
361 | "packages" : {
362 | "yum" : {
363 | "httpd" : []
364 | }
365 | },
366 |
367 | "files" : {
368 | "/var/www/html/index.html" : {
369 | "content" : { "Fn::Join" : ["\n", [
370 | "
",
371 | "Congratulations, you have successfully launched the AWS CloudFormation sample.
"
372 | ]]},
373 | "mode" : "000644",
374 | "owner" : "root",
375 | "group" : "root"
376 | },
377 |
378 | "/etc/cfn/cfn-hup.conf" : {
379 | "content" : { "Fn::Join" : ["", [
380 | "[main]\n",
381 | "stack=", { "Ref" : "AWS::StackId" }, "\n",
382 | "region=", { "Ref" : "AWS::Region" }, "\n"
383 | ]]},
384 | "mode" : "000400",
385 | "owner" : "root",
386 | "group" : "root"
387 | },
388 |
389 | "/etc/cfn/hooks.d/cfn-auto-reloader.conf" : {
390 | "content": { "Fn::Join" : ["", [
391 | "[cfn-auto-reloader-hook]\n",
392 | "triggers=post.update\n",
393 | "path=Resources.WebServerInstance.Metadata.AWS::CloudFormation::Init\n",
394 | "action=/opt/aws/bin/cfn-init -v ",
395 | " --stack ", { "Ref" : "AWS::StackName" },
396 | " --resource WebServerInstance ",
397 | " --region ", { "Ref" : "AWS::Region" }, "\n",
398 | "runas=root\n"
399 | ]]}
400 | }
401 | },
402 |
403 | "services" : {
404 | "sysvinit" : {
405 | "httpd" : { "enabled" : "true", "ensureRunning" : "true" },
406 | "cfn-hup" : { "enabled" : "true", "ensureRunning" : "true",
407 | "files" : ["/etc/cfn/cfn-hup.conf", "/etc/cfn/hooks.d/cfn-auto-reloader.conf"]}
408 | }
409 | }
410 | }
411 | }
412 | },
413 | "Properties" : {
414 | "ImageId" : { "Fn::FindInMap" : [ "AWSRegionArch2AMI", { "Ref" : "AWS::Region" },
415 | { "Fn::FindInMap" : [ "AWSInstanceType2Arch", "t2.micro", "Arch" ] } ] },
416 | "InstanceType" : "t2.micro",
417 | "Tags" : [ {"Key" : "Application", "Value" : { "Ref" : "AWS::StackId"} } ],
418 | "NetworkInterfaces" : [{
419 | "GroupSet" : [{ "Ref" : "InstanceSecurityGroup" }],
420 | "AssociatePublicIpAddress" : "true",
421 | "DeviceIndex" : "0",
422 | "DeleteOnTermination" : "true",
423 | "SubnetId" : { "Ref" : "Subnet" }
424 | }],
425 | "UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
426 | "#!/bin/bash -xe\n",
427 | "yum update -y aws-cfn-bootstrap\n",
428 |
429 | "/opt/aws/bin/cfn-init -v ",
430 | " --stack ", { "Ref" : "AWS::StackName" },
431 | " --resource WebServerInstance ",
432 | " --region ", { "Ref" : "AWS::Region" }, "\n",
433 |
434 | "/opt/aws/bin/cfn-signal -e $? ",
435 | " --stack ", { "Ref" : "AWS::StackName" },
436 | " --resource WebServerInstance ",
437 | " --region ", { "Ref" : "AWS::Region" }, "\n"
438 | ]]}}
439 | },
440 | "CreationPolicy" : {
441 | "ResourceSignal" : {
442 | "Timeout" : "PT15M"
443 | }
444 | }
445 | },
446 | "S3TestBucket": {
447 | "DeletionPolicy" : "Delete",
448 | "Type": "AWS::S3::Bucket",
449 | "Properties": {
450 | "BucketName" : { "Fn::Join" : ["", [ "securityautomationtestbucket", { "Ref": "AWS::Region" } , "-", {"Ref" : "AWS::AccountId"} ]] },
451 | "VersioningConfiguration" : {
452 | "Status" : "Enabled"
453 | },
454 | "Tags" : [
455 | {"Key" : "Name", "Value" : "SecurityAutomationTestbucket" }
456 | ]
457 | }
458 | },
459 | "CFNUser" : {
460 | "Type" : "AWS::IAM::User",
461 | "Properties" : {
462 | "LoginProfile": {
463 | "Password": "Lab1pass123!"
464 | }
465 | }
466 | },
467 |
468 | "CFNUserGroup" : {
469 | "Type" : "AWS::IAM::Group"
470 | },
471 |
472 | "CFNAdminGroup" : {
473 | "Type" : "AWS::IAM::Group"
474 | },
475 |
476 | "Users" : {
477 | "Type" : "AWS::IAM::UserToGroupAddition",
478 | "Properties" : {
479 | "GroupName": { "Ref" : "CFNUserGroup" },
480 | "Users" : [ { "Ref" : "CFNUser" } ]
481 | }
482 | },
483 |
484 | "Admins" : {
485 | "Type" : "AWS::IAM::UserToGroupAddition",
486 | "Properties" : {
487 | "GroupName": { "Ref" : "CFNAdminGroup" },
488 | "Users" : [ { "Ref" : "CFNUser" } ]
489 | }
490 | },
491 |
492 | "CFNUserPolicies" : {
493 | "Type" : "AWS::IAM::Policy",
494 | "Properties" : {
495 | "PolicyName" : "CFNUsers",
496 | "PolicyDocument" : {
497 | "Statement": [{
498 | "Effect" : "Allow",
499 | "Action" : [
500 | "cloudformation:Describe*",
501 | "cloudformation:List*",
502 | "cloudformation:Get*"
503 | ],
504 | "Resource" : "*"
505 | }]
506 | },
507 | "Groups" : [{ "Ref" : "CFNUserGroup" }]
508 | }
509 | },
510 |
511 | "CFNAdminPolicies" : {
512 | "Type" : "AWS::IAM::Policy",
513 | "Properties" : {
514 | "PolicyName" : "CFNAdmins",
515 | "PolicyDocument" : {
516 | "Statement": [{
517 | "Effect" : "Allow",
518 | "Action" : "cloudformation:*",
519 | "Resource" : "*"
520 | }]
521 | },
522 | "Groups" : [{ "Ref" : "CFNAdminGroup" }]
523 | }
524 | },
525 |
526 | "CFNKeys" : {
527 | "Type" : "AWS::IAM::AccessKey",
528 | "Properties" : {
529 | "UserName" : { "Ref": "CFNUser" }
530 | }
531 | }
532 | },
533 |
534 | "Outputs" : {
535 | "URL" : {
536 | "Value" : { "Fn::Join" : [ "", ["http://", { "Fn::GetAtt" : ["WebServerInstance", "PublicIp"] }]]},
537 | "Description" : "Newly created application URL"
538 | }
539 | }
540 | }
541 |
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/templates/AutomatingSecurityEvents_StudentPolicy.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Effect":"Allow",
6 | "Action":[
7 | "ec2:*",
8 | "cloudwatch:*",
9 | "events:*",
10 | "iam:AddRoleToInstanceProfile",
11 | "iam:CreateInstanceProfile",
12 | "iam:PassRole",
13 | "iam:List*",
14 | "iam:Get*",
15 | "iam:CreatePolicy",
16 | "s3:*",
17 | "sns:*",
18 | "logs:*",
19 | "lambda:*",
20 | "cloudtrail:*",
21 | "cloudformation:*"
22 | ],
23 | "Resource":"*"
24 | },
25 | {
26 | "Sid": "LimitedAttachmentPermissions",
27 | "Effect": "Allow",
28 | "Action": [
29 | "iam:DetachRolePolicy",
30 | "iam:AttachRolePolicy"
31 | ],
32 | "Resource": "*",
33 | "Condition": {
34 | "ArnEquals": {
35 | "iam:PolicyArn": [
36 | "arn:aws:iam::aws:policy/CloudWatchLogsFullAccess",
37 | "arn:aws:iam::aws:policy/AWSCloudTrailReadOnlyAccess"
38 | ]
39 | }
40 | }
41 | }
42 | ]
43 | }
44 |
--------------------------------------------------------------------------------
/SID402Workshop/1_MonitoringSecEvents/templates/CloudWatch_Alarms_for_CloudTrail_API_Activity.json:
--------------------------------------------------------------------------------
1 | {
2 | "AWSTemplateFormatVersion" : "2010-09-09",
3 | "Description" : "AWS CloudTrail API Activity Alarm Template for CloudWatch Logs",
4 | "Parameters" : {
5 | "LogGroupName" : {
6 | "Type" : "String",
7 | "Default" : "CloudTrail/DefaultLogGroup",
8 | "Description" : "Enter CloudWatch Logs log group name which is in the region where the stack is being launched. Default is CloudTrail/DefaultLogGroup"
9 | },
10 | "Email" : {
11 | "Type" : "String",
12 | "Description" : "Email address to notify when an API activity has triggered an alarm"
13 | }
14 | },
15 | "Resources" : {
16 | "SecurityGroupChangesMetricFilter": {
17 | "Type": "AWS::Logs::MetricFilter",
18 | "Properties": {
19 | "LogGroupName": { "Ref" : "LogGroupName" },
20 | "FilterPattern": "{ ($.eventName = AuthorizeSecurityGroupIngress) || ($.eventName = AuthorizeSecurityGroupEgress) || ($.eventName = RevokeSecurityGroupIngress) || ($.eventName = RevokeSecurityGroupEgress) || ($.eventName = CreateSecurityGroup) || ($.eventName = DeleteSecurityGroup) }",
21 | "MetricTransformations": [
22 | {
23 | "MetricNamespace": "CloudTrailMetrics",
24 | "MetricName": "SecurityGroupEventCount",
25 | "MetricValue": "1"
26 | }
27 | ]
28 | }
29 | },
30 | "SecurityGroupChangesAlarm": {
31 | "Type": "AWS::CloudWatch::Alarm",
32 | "Properties": {
33 | "AlarmName" : "CloudTrailSecurityGroupChanges",
34 | "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Security Group.",
35 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
36 | "MetricName" : "SecurityGroupEventCount",
37 | "Namespace" : "CloudTrailMetrics",
38 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
39 | "EvaluationPeriods" : "1",
40 | "TreatMissingData" : "notBreaching",
41 | "Period" : "60",
42 | "Statistic" : "Sum",
43 | "Threshold" : "1"
44 | }
45 | },
46 |
47 | "NetworkAclChangesMetricFilter": {
48 | "Type": "AWS::Logs::MetricFilter",
49 | "Properties": {
50 | "LogGroupName": { "Ref" : "LogGroupName" },
51 | "FilterPattern": "{ ($.eventName = CreateNetworkAcl) || ($.eventName = CreateNetworkAclEntry) || ($.eventName = DeleteNetworkAcl) || ($.eventName = DeleteNetworkAclEntry) || ($.eventName = ReplaceNetworkAclEntry) || ($.eventName = ReplaceNetworkAclAssociation) }",
52 | "MetricTransformations": [
53 | {
54 | "MetricNamespace": "CloudTrailMetrics",
55 | "MetricName": "NetworkAclEventCount",
56 | "MetricValue": "1"
57 | }
58 | ]
59 | }
60 | },
61 | "NetworkAclChangesAlarm": {
62 | "Type": "AWS::CloudWatch::Alarm",
63 | "Properties": {
64 | "AlarmName" : "CloudTrailNetworkAclChanges",
65 | "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Network ACL.",
66 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
67 | "MetricName" : "NetworkAclEventCount",
68 | "Namespace" : "CloudTrailMetrics",
69 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
70 | "EvaluationPeriods" : "1",
71 | "TreatMissingData" : "notBreaching",
72 | "Period" : "60",
73 | "Statistic" : "Sum",
74 | "Threshold" : "1"
75 | }
76 | },
77 |
78 | "GatewayChangesMetricFilter": {
79 | "Type": "AWS::Logs::MetricFilter",
80 | "Properties": {
81 | "LogGroupName": { "Ref" : "LogGroupName" },
82 | "FilterPattern": "{ ($.eventName = CreateCustomerGateway) || ($.eventName = DeleteCustomerGateway) || ($.eventName = AttachInternetGateway) || ($.eventName = CreateInternetGateway) || ($.eventName = DeleteInternetGateway) || ($.eventName = DetachInternetGateway) }",
83 | "MetricTransformations": [
84 | {
85 | "MetricNamespace": "CloudTrailMetrics",
86 | "MetricName": "GatewayEventCount",
87 | "MetricValue": "1"
88 | }
89 | ]
90 | }
91 | },
92 | "GatewayChangesAlarm": {
93 | "Type": "AWS::CloudWatch::Alarm",
94 | "Properties": {
95 | "AlarmName" : "CloudTrailGatewayChanges",
96 | "AlarmDescription" : "Alarms when an API call is made to create, update or delete a Customer or Internet Gateway.",
97 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
98 | "MetricName" : "GatewayEventCount",
99 | "Namespace" : "CloudTrailMetrics",
100 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
101 | "EvaluationPeriods" : "1",
102 | "TreatMissingData" : "notBreaching",
103 | "Period" : "60",
104 | "Statistic" : "Sum",
105 | "Threshold" : "1"
106 | }
107 | },
108 |
109 | "VpcChangesMetricFilter": {
110 | "Type": "AWS::Logs::MetricFilter",
111 | "Properties": {
112 | "LogGroupName": { "Ref" : "LogGroupName" },
113 | "FilterPattern": "{ ($.eventName = CreateVpc) || ($.eventName = DeleteVpc) || ($.eventName = ModifyVpcAttribute) || ($.eventName = AcceptVpcPeeringConnection) || ($.eventName = CreateVpcPeeringConnection) || ($.eventName = DeleteVpcPeeringConnection) || ($.eventName = RejectVpcPeeringConnection) || ($.eventName = AttachClassicLinkVpc) || ($.eventName = DetachClassicLinkVpc) || ($.eventName = DisableVpcClassicLink) || ($.eventName = EnableVpcClassicLink) }",
114 | "MetricTransformations": [
115 | {
116 | "MetricNamespace": "CloudTrailMetrics",
117 | "MetricName": "VpcEventCount",
118 | "MetricValue": "1"
119 | }
120 | ]
121 | }
122 | },
123 | "VpcChangesAlarm": {
124 | "Type": "AWS::CloudWatch::Alarm",
125 | "Properties": {
126 | "AlarmName" : "CloudTrailVpcChanges",
127 | "AlarmDescription" : "Alarms when an API call is made to create, update or delete a VPC, VPC peering connection or VPC connection to classic.",
128 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
129 | "MetricName" : "VpcEventCount",
130 | "Namespace" : "CloudTrailMetrics",
131 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
132 | "EvaluationPeriods" : "1",
133 | "TreatMissingData" : "notBreaching",
134 | "Period" : "60",
135 | "Statistic" : "Sum",
136 | "Threshold" : "1"
137 | }
138 | },
139 |
140 | "EC2InstanceChangesMetricFilter": {
141 | "Type": "AWS::Logs::MetricFilter",
142 | "Properties": {
143 | "LogGroupName": { "Ref" : "LogGroupName" },
144 | "FilterPattern": "{ ($.eventName = RunInstances) || ($.eventName = RebootInstances) || ($.eventName = StartInstances) || ($.eventName = StopInstances) || ($.eventName = TerminateInstances) }",
145 | "MetricTransformations": [
146 | {
147 | "MetricNamespace": "CloudTrailMetrics",
148 | "MetricName": "EC2InstanceEventCount",
149 | "MetricValue": "1"
150 | }
151 | ]
152 | }
153 | },
154 | "EC2InstanceChangesAlarm": {
155 | "Type": "AWS::CloudWatch::Alarm",
156 | "Properties": {
157 | "AlarmName" : "CloudTrailEC2InstanceChanges",
158 | "AlarmDescription" : "Alarms when an API call is made to create, terminate, start, stop or reboot an EC2 instance.",
159 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
160 | "MetricName" : "EC2InstanceEventCount",
161 | "Namespace" : "CloudTrailMetrics",
162 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
163 | "EvaluationPeriods" : "1",
164 | "TreatMissingData" : "notBreaching",
165 | "Period" : "60",
166 | "Statistic" : "Sum",
167 | "Threshold" : "1"
168 | }
169 | },
170 |
171 | "EC2LargeInstanceChangesMetricFilter": {
172 | "Type": "AWS::Logs::MetricFilter",
173 | "Properties": {
174 | "LogGroupName": { "Ref" : "LogGroupName" },
175 | "FilterPattern": "{ ($.eventName = RunInstances) && (($.requestParameters.instanceType = *.8xlarge) || ($.requestParameters.instanceType = *.4xlarge)) }",
176 | "MetricTransformations": [
177 | {
178 | "MetricNamespace": "CloudTrailMetrics",
179 | "MetricName": "EC2LargeInstanceEventCount",
180 | "MetricValue": "1"
181 | }
182 | ]
183 | }
184 | },
185 | "EC2LargeInstanceChangesAlarm": {
186 | "Type": "AWS::CloudWatch::Alarm",
187 | "Properties": {
188 | "AlarmName" : "CloudTrailEC2LargeInstanceChanges",
189 | "AlarmDescription" : "Alarms when an API call is made to create, terminate, start, stop or reboot a 4x or 8x-large EC2 instance.",
190 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
191 | "MetricName" : "EC2LargeInstanceEventCount",
192 | "Namespace" : "CloudTrailMetrics",
193 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
194 | "EvaluationPeriods" : "1",
195 | "TreatMissingData" : "notBreaching",
196 | "Period" : "60",
197 | "Statistic" : "Sum",
198 | "Threshold" : "1"
199 | }
200 | },
201 |
202 | "CloudTrailChangesMetricFilter": {
203 | "Type": "AWS::Logs::MetricFilter",
204 | "Properties": {
205 | "LogGroupName": { "Ref" : "LogGroupName" },
206 | "FilterPattern": "{ ($.eventName = CreateTrail) || ($.eventName = UpdateTrail) || ($.eventName = DeleteTrail) || ($.eventName = StartLogging) || ($.eventName = StopLogging) }",
207 | "MetricTransformations": [
208 | {
209 | "MetricNamespace": "CloudTrailMetrics",
210 | "MetricName": "CloudTrailEventCount",
211 | "MetricValue": "1"
212 | }
213 | ]
214 | }
215 | },
216 | "CloudTrailChangesAlarm": {
217 | "Type": "AWS::CloudWatch::Alarm",
218 | "Properties": {
219 | "AlarmName" : "CloudTrailChanges",
220 | "AlarmDescription" : "Alarms when an API call is made to create, update or delete a CloudTrail trail, or to start or stop logging to a trail.",
221 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
222 | "MetricName" : "CloudTrailEventCount",
223 | "Namespace" : "CloudTrailMetrics",
224 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
225 | "EvaluationPeriods" : "1",
226 | "TreatMissingData" : "notBreaching",
227 | "Period" : "60",
228 | "Statistic" : "Sum",
229 | "Threshold" : "1"
230 | }
231 | },
232 |
233 |
234 | "ConsoleSignInFailuresMetricFilter": {
235 | "Type": "AWS::Logs::MetricFilter",
236 | "Properties": {
237 | "LogGroupName": { "Ref" : "LogGroupName" },
238 | "FilterPattern": "{ ($.eventName = ConsoleLogin) && ($.errorMessage = \"Failed authentication\") }",
239 | "MetricTransformations": [
240 | {
241 | "MetricNamespace": "CloudTrailMetrics",
242 | "MetricName": "ConsoleSignInFailureCount",
243 | "MetricValue": "1"
244 | }
245 | ]
246 | }
247 | },
248 | "ConsoleSignInFailuresAlarm": {
249 | "Type": "AWS::CloudWatch::Alarm",
250 | "Properties": {
251 | "AlarmName" : "CloudTrailConsoleSignInFailures",
252 | "AlarmDescription" : "Alarms when an unauthenticated API call is made to sign into the console.",
253 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
254 | "MetricName" : "ConsoleSignInFailureCount",
255 | "Namespace" : "CloudTrailMetrics",
256 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
257 | "EvaluationPeriods" : "1",
258 | "TreatMissingData" : "notBreaching",
259 | "Period" : "60",
260 | "Statistic" : "Sum",
261 | "Threshold" : "3"
262 | }
263 | },
264 |
265 | "AuthorizationFailuresMetricFilter": {
266 | "Type": "AWS::Logs::MetricFilter",
267 | "Properties": {
268 | "LogGroupName": { "Ref" : "LogGroupName" },
269 | "FilterPattern": "{ ($.errorCode = \"*UnauthorizedOperation\") || ($.errorCode = \"AccessDenied*\") }",
270 | "MetricTransformations": [
271 | {
272 | "MetricNamespace": "CloudTrailMetrics",
273 | "MetricName": "AuthorizationFailureCount",
274 | "MetricValue": "1"
275 | }
276 | ]
277 | }
278 | },
279 | "AuthorizationFailuresAlarm": {
280 | "Type": "AWS::CloudWatch::Alarm",
281 | "Properties": {
282 | "AlarmName" : "CloudTrailAuthorizationFailures",
283 | "AlarmDescription" : "Alarms when an unauthorized API call is made.",
284 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
285 | "MetricName" : "AuthorizationFailureCount",
286 | "Namespace" : "CloudTrailMetrics",
287 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
288 | "EvaluationPeriods" : "1",
289 | "TreatMissingData" : "notBreaching",
290 | "Period" : "60",
291 | "Statistic" : "Sum",
292 | "Threshold" : "1"
293 |
294 | }
295 | },
296 |
297 | "IAMPolicyChangesMetricFilter": {
298 | "Type": "AWS::Logs::MetricFilter",
299 | "Properties": {
300 | "LogGroupName": { "Ref" : "LogGroupName" },
301 | "FilterPattern": "{($.eventName=DeleteGroupPolicy)||($.eventName=DeleteRolePolicy)||($.eventName=DeleteUserPolicy)||($.eventName=PutGroupPolicy)||($.eventName=PutRolePolicy)||($.eventName=PutUserPolicy)||($.eventName=CreatePolicy)||($.eventName=DeletePolicy)||($.eventName=CreatePolicyVersion)||($.eventName=DeletePolicyVersion)||($.eventName=AttachRolePolicy)||($.eventName=DetachRolePolicy)||($.eventName=AttachUserPolicy)||($.eventName=DetachUserPolicy)||($.eventName=AttachGroupPolicy)||($.eventName=DetachGroupPolicy)}",
302 | "MetricTransformations": [
303 | {
304 | "MetricNamespace": "CloudTrailMetrics",
305 | "MetricName": "IAMPolicyEventCount",
306 | "MetricValue": "1"
307 | }
308 | ]
309 | }
310 | },
311 | "IAMPolicyChangesAlarm": {
312 | "Type": "AWS::CloudWatch::Alarm",
313 | "Properties": {
314 | "AlarmName" : "CloudTrailIAMPolicyChanges",
315 | "AlarmDescription" : "Alarms when an API call is made to change an IAM policy.",
316 | "AlarmActions" : [{ "Ref" : "AlarmNotificationTopic" }],
317 | "MetricName" : "IAMPolicyEventCount",
318 | "Namespace" : "CloudTrailMetrics",
319 | "ComparisonOperator" : "GreaterThanOrEqualToThreshold",
320 | "EvaluationPeriods" : "1",
321 | "TreatMissingData" : "notBreaching",
322 | "Period" : "60",
323 | "Statistic" : "Sum",
324 | "Threshold" : "1"
325 | }
326 | },
327 |
328 | "AlarmNotificationTopic": {
329 | "Type": "AWS::SNS::Topic",
330 | "Properties": {
331 | "Subscription": [
332 | {
333 | "Endpoint": { "Ref": "Email" },
334 | "Protocol": "email"
335 | }
336 | ]
337 | }
338 | }
339 | }
340 | }
341 |
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/README.md:
--------------------------------------------------------------------------------
1 | ## re:Invent 2017 - SID402
2 |
3 | # Module 2 - Implementing Security with AWS IoT
4 |
5 | ### Introduction
6 |
7 | The security enhancement project at IthaCorp is in full gear and you are continuing the process of implementing controls across the four CAF Security Perspective areas; **Directive**, **Preventative**, **Detective** and **Responsive**. Unexpectedly, you are approached by the business to support the launch of IthaCorp Telemachus, a new IoT Service offering that transforms traditional cities into "smart" cities by using IoT technology to improve efficiency through device instrumentation, analytics and automation. Your role is provide assistance with the security configuration of the AWS IoT resources. This is a critical service launch for the business so you get started immediately.
8 |
9 | In this module, you will set up an environment using the AWS IoT (Internet of Things) service. You will create a simulated device (a thing) and connect it to the AWS IoT service and watch traffic flow between the device and AWS IoT. You will then enhance the security of the communication between the device and AWS IoT and, in so doing, learn more about the various security features offered by the service.
10 |
11 | ### Architecture Overview
12 |
13 | 
14 |
15 | *Note: Going forward, we will use the terms device and thing interchangeably.*
16 |
17 | ### Topics covered
18 |
19 | By the end of this module, you will be able to:
20 |
21 | * Create a test AWS IoT environment using AWS CloudFormation. The environment will contain an Amazon EC2 instance running a package named [Node-RED](https://en.wikipedia.org/wiki/Node-RED). Node-RED provides a web-based interface that allows you to create message flows (i.e. sequences of transmissions). Node-RED can send these message flows using the MQTT and TLS protocols, which are used by AWS IoT. In short, Node-RED lets you simulate an AWS IoT device (a thing).
22 |
23 | * Configure Node-RED to simuilate AWS IoT device (a thing) and then test communication with the AWS IoT service.
24 |
25 | * Adjust the security permissions within AWS IoT to more tightly restrict the communication to AWS IoT.
26 |
27 | ### Prerequisites
28 |
29 | This module assumes you have a general knowledge of AWS services and that you have an AWS account with an IAM user that has full administrative privileges. Additionally, only one person should do this module in a specific AWS account in a given region. If more than one person is using the same AWS account for this module at the same time, each must use a different AWS IoT region.
30 |
31 | ### 1. Choose a Region
32 |
33 | AWS IoT is located in many [regions](http://docs.aws.amazon.com/general/latest/gr/rande.html#iot_region) across the world. We will provide shortcuts for the regions we want you to use later in this lab. As noted above, if more than one person is doing the module in the same AWS account, each person should use a different region. Please use the same region throughout the lab.
34 |
35 | **Tip** The AWS region name is always listed in the upper-right corner of the AWS Management Console, in the navigation bar.
36 |
37 | ### 2. Build the Node-RED Environment
38 |
39 | Our modules will use AWS CloudFormation to provision a web-based environment with Node-RED. Node-RED allows you to simulate an IoT device including the sending and receiving of IoT messages using the MQTT protocol. The AWS CloudFormation template will create a complete environment consisting of an Amazon VPC and an Amazon EC2 instance on which Node-RED will be installed.
40 |
41 | - __2.1.__ Sign in to the AWS management console at:
42 |
43 | - __2.2.__ Click the link below corresponding to the region in which you wish to deploy the environment.
44 | ___Hold the "Control" key while clicking and open the launch link in a new tab___
45 |
46 | Region| Launch
47 | ------|-----
48 | Ireland (eu-west-1) | [](https://console.aws.amazon.com/cloudformation/home?region=eu-west-1#/stacks/new?stackName=SID402-IoTSecurityLab&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_VPC.yaml)
49 | London (eu-west-2) | [](https://console.aws.amazon.com/cloudformation/home?region=eu-west-2#/stacks/new?stackName=SID402-IoTSecurityLab&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_VPC.yaml)
50 | Singapore (ap-southeast-1) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-1#/stacks/new?stackName=SID402-IoTSecurityLab&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_VPC.yaml)
51 | Sydney (ap-southeast-2) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-southeast-2#/stacks/new?stackName=SID402-IoTSecurityLab&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_VPC.yaml)
52 | Tokyo (ap-northeast-1) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-1#/stacks/new?stackName=SID402-IoTSecurityLab&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_VPC.yaml)
53 | Seoul (ap-northeast-2) | [](https://console.aws.amazon.com/cloudformation/home?region=ap-northeast-2#/stacks/new?stackName=SID402-IoTSecurityLab&templateURL=https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_VPC.yaml)
54 |
55 | - __2.3.__ A new browser tab or page will appear with the CloudFormation template selected. Click on **Next** to be taken to the list of parameters. Click on **Next** to accept the default values.
56 |
57 | - __2.4.__ On the next page, you can create tags to be applied to resources, then click **Next**.
58 |
59 | - __2.5.__ Review the settings. When requested, click the check box to acknowledge that IAM resources may be created and then click **Create**. You will return to the CloudFormation console. The process will take five to seven minutes to complete. While the stack is building, proceed to the next page to create your first AWS IoT device (a thing).
60 |
61 | ___Complete all the steps below. Use arrow to expand sections marked with "(expand for details)".___
62 |
63 | ### 3. Complete Initial Environment Configuration
64 |
65 |
66 | 3.1. Define Device (expand for details)
67 |
68 |
69 |
70 | You will now define an IoT device. A device is recognized by AWS IoT through a certificate. You will create a certificate and attach it to the device. You will also attach a policy to the device that gives the device (thing) full access to AWS IoT. Later in this module, you will configure the Node-RED with this certificate which will cause AWS IoT to recognize Node-RED as an AWS IoT device.
71 |
72 | - __3.1.1.__ Make sure you are still working in the same AWS region in which you are building the AWS CloudFormation stack.
73 |
74 | - __3.1.2.__ Select the service **AWS IoT** from the AWS Console. If you see a **Get started** button, click that.
75 |
76 | - __3.1.3.__ From the menu on the left, select **Manage**, **Things** and the click the **Register a thing** button (if there are already things listed, click the **Create** button instead).
77 |
78 | - __3.1.4.__ Enter the name `device1` and click **Create thing**. You should see a new entry as shown below.
79 |
80 | 
81 |
82 | - __3.1.5.__. On the left select **Secure**, then **Certificates**, then click **Create a certificate** and then Click **Create certificate.** You will then be presented with a page telling you the certificate has been created and given the opportunity to download four items as shown below. Continue below this picture for download instructions. **NOTE: You will not use the public key but please download it nonetheless.**
83 |
84 | 
85 |
86 | Use the top three download links to download the certificate, public key, and private key to a folder on your system. Also download the root CA from the link above the Activate button by right-clicking and saving the file as **rootCA.pem**. To clarify, you are downloading **four** separate items! Once done and verified you have the files locally saved, click **Activate** and then scroll to the bottom of the window and click **Attach a policy**.
87 |
88 | You have thus far created a device and a certificate. You will now define what the holder of the certificate (which will eventually be Node-RED running on Amazon EC2) can do.
89 |
90 | - __3.1.6.__ Click **Create new policy**.
91 |
92 | - __3.1.7.__ On the **Create a policy** page create the statement as follows:
93 |
94 | 
95 |
96 | **Name**: device1_full_access
97 |
98 | **Action**: iot:*
99 |
100 | **Resource ARN**: *
101 |
102 | **Effect**: Allow
103 |
104 | This represents a policy named device1_full_access that can perform all iot actions ( iot:* ) on all resources. In other words, the policy will grant full IoT access to any certificate to which the policy is attached.
105 |
106 | - __3.1.8.__ Select **Create**.
107 |
108 | - __3.1.9.__ From the main AWS IoT menu, select **Secure**, **Certificates.**
109 |
110 | - __3.1.10.__ Select the certificate that you created above by hovering over the certificate and checking the blue box that appears. With it checked, select the drop-down menu **Actions** and click on **Attach policy**. Then select the **device1_full_access** policy and click **Attach**. You have now attached the policy to the certificate.
111 |
112 | - __3.1.11.__ Select the drop-down menu **Actions** and click on **Attach thing** and select the thing named **device1**. Click **Attach**. You have now attached the certificate with its policy to the device. Later in this module, you will configure Node-RED with the certificate that has this policy causing, Node-RED to be recognized by AWS IoT as **device1**.
113 |
114 | - __3.1.12.__ On this AWS IoT console home page, near the bottom left click Settings. Copy the value in the **Endpoint** field and save it in a text file. You will need this value later in the module when you configure Node-RED.
115 |
116 |
117 |
118 | 3.2. Configure Node-RED (expand for details)
119 |
120 |
121 |
122 | - __3.2.1.__ By this point, the CloudFormation stack with the Node-RED Amazon EC2 instance should be complete Go to the AWS CloudFormation console, select the stack and look at the output tab. If you do not see the output tab, refresh the CloudFormation console page. You should see the following values:
123 |
124 | **HostIPAddress**: The IP address of the EC2 instance
125 |
126 | **NodeREDURL**: The URL of the EC2 instance
127 |
128 | - __3.2.2.__ Browse to the URL and you should see Node-RED appear. If you receive a timeout message or your browser pauses, the initial set up of the instance may still be taking place. In that case, just wait a minute or two and try again. Firefox users may have difficulty viewing Node-RED. If so, please try Chrome, IE, or Safari.
129 |
130 | 
131 |
132 | The interface has three sections. Going from left to right:
133 |
134 | **Nodes**: These represent actions or objects for Node-RED.
135 |
136 | **Flow Canvas**: You position nodes, configure them, and connect them on the canvas to create message flows.
137 |
138 | **Info/Debug**: The info tab will provide more details on the selected node. The debug tab will show in real time all activity for the debug nodes.
139 |
140 | Click on the **device1** tab. This will display the two flows to be tested. The first flow, **Publish time locally**, generate a binary timestamp (the Generate Timestamp node), then have that converted to a friendly date and time (the timestampToString node), and then finally print the time to the debug window (the Print time locally node). The second flow will do something similar, except you will see there is an additional output to be configured to send the message to the AWS IoT service.
141 |
142 | **First flow - Publish time locally**
143 |
144 | - __3.2.3.__ On the right side of the make sure the debug tab is selected.
145 |
146 | - __3.2.4.__ On the Generate Timestamp node for Publish time locally, click the button on the left side. This will generate the timestamp, then convert and send. You will see the message in the debug frame. Every click on the inject node (Generate Timestamp) will publish a message in the debug window. See the vertical red arrows below for clarification.
147 |
148 | 
149 |
150 | **Second flow - Single click message to AWS IoT**
151 |
152 | - __3.2.5.__ The second flow under **Single click message to AWS IoT** does two things. Like the first flow, Node-RED will print a timestamp locally. Additionally, there is also a branch flow which translates the time to JSON format (the timestampToJSON node) and then sends the message to AWS IoT (the AWS IoT node). You will see a red alert icon on the upper right corner of the AWS IoT node because some configuration information is missing.
153 |
154 | To configure the AWS IoT node, double-click it. This will bring up a window that allows you to edit the MQTT properties of the node. [MQTT](https://en.wikipedia.org/wiki/MQTT) is one of the underlying network protocols used by AWS IoT. Click the pencil icon as shown below by the red arrow.
155 |
156 | 
157 |
158 | Another window will appear on which you will enter MQTT configuration information.
159 |
160 | On the Connection tab, configure the following:
161 |
162 | **Server**: Endpoint value that you copied earlier
163 |
164 | **Port**: 8883 (Make sure you use this value otherwise your messages will not go through!)
165 |
166 | **Client ID**: device1
167 |
168 | Now check the box named Enable Secure SSL/TLS communication. The window should like similar to that shown below.
169 |
170 | 
171 |
172 | - __3.2.6.__ Click the pencil next to the Add new tls-config dropdown as shown by the red arrow above. A new window will appear as shown below.
173 |
174 | 
175 |
176 | - __3.2.7.__ On the Add new-tls-config screen, make sure the **Use key and certificates from local files** is deselected (which would cause Node-RED to use files on the Node-RED instance itself), and instead select the Upload button for each and navigate to the directory where the files are saved. The files will have names similar to the following:
177 |
178 | **Certificate**: c1234567-**certificate**.pem.crt
179 |
180 | **Private Key**: c1234567-**private**.pem.key (**NOTE: You must use the private key file! Do not select the public key file! You will not be uploading the public key in this lab! **)
181 |
182 | **CA Certificate**: rootCA.pem
183 |
184 | **Verify server certificate**: selected
185 |
186 | **Name**: IoT Security Lab
187 |
188 | If for some reason you forgot to download the **rootCA.pem** file earlier, you can right click on the following link, open it in a new tab and save the value into a file named **rootCA.pem**:
189 |
190 | [[rootCA.pem]](https://www.symantec.com/content/en/us/enterprise/verisign/roots/VeriSign-Class%203-Public-Primary-Certification-Authority-G5.pem)
191 |
192 | - __3.2.8.__ Then click **Add**, which will bring you back to the **Add mqtt-broker config node** window.
193 |
194 | - __3.2.9.__ From the mqtt-broker config node page, click **Add**. You will return to the **Edit mqtt out node** window.
195 |
196 | - __3.2.10.__ Enter the following information into the fields in the window.
197 |
198 | **Topic:** topic1
199 |
200 | **QoS**: 0
201 |
202 | **Name:** AWS IoT
203 |
204 | The server name will already be filled in based on the information you have provided as shown in the screen below. Later in the module, we will show how to subscribe to messages sent to **topic1** to verify communication from AWS IoT and Node-RED.
205 |
206 | 
207 |
208 | - __3.2.11.__ Click **Done** to go back to the main GUI.
209 |
210 | - __3.2.12.__ Finally, notice that the **Deploy** icon in the upper right of the GUI is red. If you do not do this, your changes will not be enabled! This means changes have been made and need to be deployed. Click on this button and the flow will be saved, validated, and ready for use. If validation succeeds, the AWS IoT node (the Node-RED Amazon EC2 instance) will connect to the AWS IoT platform. You should see a green icon with connected under the AWS IoT node, Node-RED was able to successfully connect to the AWS IoT platform. **(NOTE: If you are not seeing the connection icon showing in green, return to step 3.2.5 to reconfigure the IOT paramaters.)**
211 |
212 | - __3.2.13.__ Bring up the AWS Console in a new browser window or tab and navigate to the AWS IoT console and select **Test**. Then select Subscribe to a topic link, enter **topic1** as the topic, and finally click the Subscribe to topic button per the figure below.
213 |
214 | 
215 |
216 | The MQTT client will then appear as shown below.
217 |
218 | 
219 |
220 | - __3.2.14.__ Return to the Node-RED window. Clean out the debug window by clicking the trash can icon. Click the button to the left of the Generate Timestamp node for the Single click message to AWS IoT flow. You will see the friendly date and time posted in the debug window, but you will also see the message published in the MQTT client in the AWS Console. Notice also that the AWS IoT node continues to show that it is connected which means that the policy attached to the certificate does allow the desired communication.
221 |
222 | 
223 |
224 | - __3.2.15.__ Now return to the AWS IoT window with the MQTT client. You should see a message that was published to topic1 as shown in the figure below.
225 |
226 | 
227 |
228 | You have now done the following:
229 |
230 | * Defined an IoT device.
231 |
232 | * Created a certificate and attached a policy which has full access to AWS IoT
233 |
234 | * Launched a Node-RED instance on AWS and configured Node-RED with the certificate information from AWS IoT, thereby enabling the Node-RED instance to simulate an IoT device and communicate with AWS IoT
235 |
236 | * Captured traffic from Node-RED within AWS IoT.
237 |
238 | You will now learn how to restrict access to AWS IoT.
239 |
240 |
241 | ### 4. Restricting Access to AWS IoT
242 |
243 |
244 | 4.1. Create Permissions for Device Specific Topics (expand for details)
245 |
246 |
247 |
248 | Earlier in this module you created a policy for your AWS IoT certificate that was very open and allowed the holder of that certificate to publish to any IoT topic. We are now going to show you how to restrict that policy so it only allows publishing to the topic we have already created.
249 |
250 | - __4.1.1.__ Go to the main IoT console and choose **Secure**, **Policies**. You should see a policy named device1_full_acccess. Click directly on the policy name.
251 |
252 | On the top of the window you will see the policy ARN (Amazon Resource Name). It will look something like:
253 |
254 | `arn:aws:iot:us-west-2:123456789012:policy/device1_full_access`
255 |
256 | Copy the region name (`us-west-2` in the above example) and the account number (`123456789012` in the above example) to a scratch file for future use.
257 |
258 | - __4.1.2.__ Go back to the main IoT console and choose **Secure**, **Policies**. Click **Create**.
259 |
260 | Enter `device1_allow_publish` and click **Advanced mode.**
261 |
262 | - __4.1.3.__ Replace the JSON with the content below, replacing `REGION` and `ACCOUNT` with the values you copied earlier. Make sure you retain all of the colon (:) separators.
263 |
264 | ````
265 | {
266 | "Version": "2012-10-17",
267 | "Statement": [
268 | {
269 | "Effect": "Allow",
270 | "Action": [
271 | "iot:Subscribe",
272 | "iot:Connect",
273 | "iot:Receive"
274 | ],
275 | "Resource": [
276 | "*"
277 | ]
278 | },
279 | {
280 | "Effect": "Allow",
281 | "Action": [
282 | "iot:Publish"
283 | ],
284 | "Resource": [
285 | "arn:aws:iot:REGION:ACCOUNT:topic/topic1"
286 | ]
287 | }
288 | ]
289 | }
290 |
291 | ````
292 |
293 | - __4.1.4.__ Click **Create**.
294 |
295 | - __4.1.5.__ Navigate to **Secure**, **Certificates** and click on the name of your certificate. On the left menu, click **Policies**. Now select **Attach policy** under Actions and select **device1_allow_publish**. Then detach the **device1_full_access** policy from the certificate.
296 |
297 | - __4.1.6.__ Go to the IoT console and select **Test**. Subscribe to **topic1**.
298 |
299 | - __4.1.7.__ Go to the Node-RED window and generate another message under **Single click message to AWS IoT**. You should see messages continue to appear on the test window. The AWS IoT node should continue to remain connected.
300 | You have now restricted the AWS IoT device represented by Node-RED so that it can only publish to the topic named **topic1**.
301 |
302 | - __4.1.8.__ On the Node-RED window, double click on the **AWS IoT** node. Change the topic name to **topic2**. Click **Done**. Click **Deploy**.
303 |
304 | - __4.1.9.__ Generate another message under **Single click message to AWS IoT**. You should see the AWS IoT node disconnect for a few seconds as shown in the figure below. This is because you are only allowed to publish to topic **topic1**.
305 |
306 | 
307 |
308 |
309 | ### Conclusion
310 |
311 | Congratulations! You have now successfully:
312 |
313 | - Configured a device in AWS IoT
314 |
315 | - Launched an Amazon EC2 instance with the Node-RED platform
316 |
317 | - Associated Node-Red with the IoT device by attaching a certificate
318 |
319 | - Captured traffic from Node-RED with AWS IoT
320 |
321 | - Configured AWS IoT security policies to restrict actions from IoT devices
322 |
323 | ### [Continue on to Module 3](https://github.com/awslabs/aws-security-odyssey/tree/master/SID402Workshop/3_AutoSecRemediation)
324 |
325 | ### Clean Up
326 | ___Complete clean up at the end of the Workshop___
327 |
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/.gitkeep:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/diagramm2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/diagramm2.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image10.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image10.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image11.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image12.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image13.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image13.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image14.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image14.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image15.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image15.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image2.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image3.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image4.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image5-rev2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image5-rev2.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image5.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image6.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image7.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image8.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/images/image9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/images/image9.png
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/scripts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/scripts/.gitkeep
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/scripts/IoT_Security_Lab_Connect_Device.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "id": "561a26e3.c084b8",
4 | "type": "tab",
5 | "label": "device1",
6 | "disabled": false,
7 | "info": "IoT Security Lab - Connect device1 to AWS IoT and verify connectivity and the ability to publish a message"
8 | },
9 | {
10 | "id": "3104dbb5.d48cc4",
11 | "type": "inject",
12 | "z": "561a26e3.c084b8",
13 | "name": "Generate Timestamp",
14 | "topic": "",
15 | "payload": "",
16 | "payloadType": "date",
17 | "repeat": "",
18 | "crontab": "",
19 | "once": false,
20 | "x": 160,
21 | "y": 80,
22 | "wires": [
23 | [
24 | "2589d951.7edef6"
25 | ]
26 | ]
27 | },
28 | {
29 | "id": "2589d951.7edef6",
30 | "type": "function",
31 | "z": "561a26e3.c084b8",
32 | "name": "timestampToString",
33 | "func": "// Create a Date object from the payload\nvar date = new Date(msg.payload);\n// Change the payload to be a formatted Date string\nmsg.payload = 'Local Message: ' + date.toString();\n// Return the message so it can be sent on\nreturn msg;",
34 | "outputs": 1,
35 | "noerr": 0,
36 | "x": 390,
37 | "y": 140,
38 | "wires": [
39 | [
40 | "5ee1e04a.47457"
41 | ]
42 | ]
43 | },
44 | {
45 | "id": "5ee1e04a.47457",
46 | "type": "debug",
47 | "z": "561a26e3.c084b8",
48 | "name": "Print time locally",
49 | "active": true,
50 | "console": "false",
51 | "complete": "payload",
52 | "x": 560,
53 | "y": 80,
54 | "wires": []
55 | },
56 | {
57 | "id": "b9863901.7a6a68",
58 | "type": "comment",
59 | "z": "561a26e3.c084b8",
60 | "name": "Publish time locally",
61 | "info": "To start, select the debug tab on the right side of the browser. This will show a formatted time being published every 5 seconds.",
62 | "x": 150,
63 | "y": 40,
64 | "wires": []
65 | },
66 | {
67 | "id": "eed12f30.e0ee4",
68 | "type": "comment",
69 | "z": "561a26e3.c084b8",
70 | "name": "Single click message to AWS IoT",
71 | "info": "After disabling the debug above, follow these steps:\n\n1. Enable the debug output and *Deploy* (ignore warnings on nodes not configured)\n2. Click the *Generate Timestamp* icon and verify messages are being generated in the debug plane\n3. Follow the lab quide to configure the AWS IoT node\n4. Open the AWS Console and subscribe to the topic `device1/#` ",
72 | "x": 190,
73 | "y": 221,
74 | "wires": []
75 | },
76 | {
77 | "id": "ff97bf70.00296",
78 | "type": "inject",
79 | "z": "561a26e3.c084b8",
80 | "name": "Generate Timestamp",
81 | "topic": "",
82 | "payload": "",
83 | "payloadType": "date",
84 | "repeat": "",
85 | "crontab": "",
86 | "once": false,
87 | "x": 160,
88 | "y": 260,
89 | "wires": [
90 | [
91 | "c4a2eea6.67d86",
92 | "b8a5a65f.589918"
93 | ]
94 | ]
95 | },
96 | {
97 | "id": "c4a2eea6.67d86",
98 | "type": "function",
99 | "z": "561a26e3.c084b8",
100 | "name": "timestampToString",
101 | "func": "// Create a Date object from the payload\nvar date = new Date(msg.payload);\n// Change the payload to be a formatted Date string\nmsg.payload = 'Local Message: ' + date.toString();\n// Return the message so it can be sent on\nreturn msg;",
102 | "outputs": 1,
103 | "noerr": 0,
104 | "x": 390,
105 | "y": 260,
106 | "wires": [
107 | [
108 | "6de5130d.1c685c"
109 | ]
110 | ]
111 | },
112 | {
113 | "id": "aac91b32.b36038",
114 | "type": "mqtt out",
115 | "z": "561a26e3.c084b8",
116 | "name": "AWS IoT",
117 | "topic": "",
118 | "qos": "0",
119 | "retain": "",
120 | "broker": "",
121 | "x": 640,
122 | "y": 360,
123 | "wires": []
124 | },
125 | {
126 | "id": "6de5130d.1c685c",
127 | "type": "debug",
128 | "z": "561a26e3.c084b8",
129 | "name": "Print time locally",
130 | "active": true,
131 | "console": "false",
132 | "complete": "payload",
133 | "x": 600,
134 | "y": 260,
135 | "wires": []
136 | },
137 | {
138 | "id": "b8a5a65f.589918",
139 | "type": "function",
140 | "z": "561a26e3.c084b8",
141 | "name": "timestampToJSON",
142 | "func": "// Create a Date object from the payload\nvar date = new Date(msg.payload);\n// Change the payload to be a formatted Date string\nmsg.payload = {\"date\": date.toString(),\n \"timestamp\": msg.payload\n };\n// Return the message so it can be sent on\nreturn msg;",
143 | "outputs": 1,
144 | "noerr": 0,
145 | "x": 422.22222222222223,
146 | "y": 358.88888888888886,
147 | "wires": [
148 | [
149 | "aac91b32.b36038"
150 | ]
151 | ]
152 | }
153 | ]
154 |
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/scripts/IoT_Security_Lab_VPC.yaml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: "2010-09-09"
2 |
3 | Description:
4 | Creates a complete VPC, Node-RED EC2 instance, and public IP address. The
5 | Output tab has the specifics for directly accessing the instance or to SSH
6 | to the instance.
7 |
8 | Parameters:
9 | InstanceType:
10 | Description: 'EC2 instance type'
11 | Type: 'String'
12 | Default: 't2.micro'
13 | AllowedValues:
14 | - t2.nano
15 | - t2.micro
16 | - t2.small
17 | - t2.medium
18 | ConstraintDescription: 'Must be a valid EC2 instance type.'
19 | AllowedIPRange:
20 | Description: "The IP address range that can be used to SSH and connet to Node-RED to the EC2 instance"
21 | Type: "String"
22 | MinLength: "9"
23 | MaxLength: "18"
24 | Default: "0.0.0.0/0"
25 | AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
26 | ConstraintDescription: "must be a valid IP CIDR range of the form x.x.x.x/x."
27 |
28 | Mappings:
29 | AWSInstanceType2Arch:
30 | t2.nano:
31 | 'Arch': 'HVM64'
32 | t2.micro:
33 | 'Arch': 'HVM64'
34 | t2.small:
35 | 'Arch': 'HVM64'
36 | t2.medium:
37 | 'Arch': 'HVM64'
38 |
39 | Resources:
40 | VPC:
41 | Type: 'AWS::EC2::VPC'
42 | Properties:
43 | CidrBlock: 172.31.0.0/24
44 | EnableDnsSupport: true
45 | EnableDnsHostnames: true
46 | InstanceTenancy: default
47 | Tags:
48 | - Key: Name
49 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED' ] ]
50 | InternetGateway:
51 | Type: 'AWS::EC2::InternetGateway'
52 | Properties:
53 | Tags:
54 | - Key: Name
55 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED' ] ]
56 | VPCGatewayAttachment:
57 | Type: 'AWS::EC2::VPCGatewayAttachment'
58 | Properties:
59 | VpcId: !Ref VPC
60 | InternetGatewayId: !Ref InternetGateway
61 | SubnetAPublic:
62 | Type: 'AWS::EC2::Subnet'
63 | Properties:
64 | CidrBlock: 172.31.0.0/24
65 | MapPublicIpOnLaunch: true
66 | VpcId: !Ref VPC
67 | Tags:
68 | - Key: Name
69 | Value: !Join [ "-", [ !Sub '${AWS::StackName}', 'Node-RED-public' ] ]
70 | RouteTablePublic:
71 | Type: 'AWS::EC2::RouteTable'
72 | Properties:
73 | VpcId: !Ref VPC
74 | Tags:
75 | - Key: Name
76 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED-public' ] ]
77 | RouteTableAssociationAPublic:
78 | Type: 'AWS::EC2::SubnetRouteTableAssociation'
79 | Properties:
80 | SubnetId: !Ref SubnetAPublic
81 | RouteTableId: !Ref RouteTablePublic
82 | RouteTablePublicInternetRoute: # should be RouteTablePublicAInternetRoute, but logical id was not changed for backward compatibility
83 | Type: 'AWS::EC2::Route'
84 | DependsOn: VPCGatewayAttachment
85 | Properties:
86 | RouteTableId: !Ref RouteTablePublic
87 | DestinationCidrBlock: '0.0.0.0/0'
88 | GatewayId: !Ref InternetGateway
89 | EC2Instance:
90 | Type: "AWS::EC2::Instance"
91 | Properties:
92 | ImageId: !GetAtt AMIInfo.Id
93 | InstanceType: !Ref InstanceType
94 | NetworkInterfaces:
95 | - AssociatePublicIpAddress: "true"
96 | DeviceIndex: "0"
97 | GroupSet:
98 | - Ref: "SGSNodeRed"
99 | SubnetId: !Ref SubnetAPublic
100 | Tags:
101 | - Key: Name
102 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED' ] ]
103 | UserData:
104 | "Fn::Base64":
105 | "Fn::Sub": |
106 | #!/bin/bash
107 | yum upgrade -y
108 | yum install -y gcc-c++ make
109 | curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
110 | yum install -y nodejs
111 | mkdir /opt/.npm
112 | echo 'prefix = /opt/.npm' > ~/.npmrc
113 | echo 'export PATH=$PATH:/opt/.npm/bin' >> /home/ec2-user/.bashrc
114 | npm install -g --unsafe-perm node-red
115 |
116 | # Install supervisor
117 | pip install supervisor
118 | /usr/local/bin/echo_supervisord_conf > /etc/supervisord.conf
119 | # Append config for node-red
120 | cat << 'EOF' >> /etc/supervisord.conf
121 | [program:nodered]
122 | command=/opt/.npm/bin/node-red
123 | directory=/home/ec2-user
124 | autostart=true
125 | autorestart=true
126 | startretries=3
127 | stderr_logfile=/home/ec2-user/nodered.err.log
128 | stdout_logfile=/home/ec2-user/nodered.out.log
129 | user=ec2-user
130 | environment=HOME="/home/ec2-user"
131 | EOF
132 |
133 | cat << 'EOF' >> supervisor
134 | #!/bin/bash
135 | #
136 | # supervisor Start/Stop the supervisor daemon.
137 | #
138 | # chkconfig: 345 90 10
139 | # description: Supervisor is a client/server system that allows its users to
140 | # monitor and control a number of processes on UNIX-like operating
141 | # systems.
142 |
143 | . /etc/init.d/functions
144 |
145 | DAEMON=/usr/local/bin/supervisord
146 | PIDFILE=/var/run/supervisord.pid
147 |
148 | [ -x "$DAEMON" ] || exit 0
149 |
150 | start() {
151 | echo -n "Starting supervisord: "
152 | if [ -f $PIDFILE ]; then
153 | PID=`cat $PIDFILE`
154 | echo supervisord already running: $PID
155 | exit 2;
156 | else
157 | daemon $DAEMON --pidfile=$PIDFILE -c /etc/supervisord.conf -u ec2-user -d /home/ec2-user
158 | RETVAL=$?
159 | echo
160 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord
161 | return $RETVAL
162 | fi
163 |
164 | }
165 |
166 | stop() {
167 | echo -n "Shutting down supervisord: "
168 | echo
169 | killproc -p $PIDFILE supervisord
170 | echo
171 | rm -f /var/lock/subsys/supervisord
172 | return 0
173 | }
174 |
175 | case "$1" in
176 | start)
177 | start
178 | ;;
179 | stop)
180 | stop
181 | ;;
182 | status)
183 | status supervisord
184 | ;;
185 | restart)
186 | stop
187 | start
188 | ;;
189 | *)
190 | echo "Usage: {start|stop|status|restart}"
191 | exit 1
192 | ;;
193 | esac
194 | exit $?
195 | EOF
196 | mv supervisor /etc/init.d
197 | chmod +x /etc/init.d/supervisor
198 | chkconfig --add supervisor
199 | chkconfig supervisor on
200 | /sbin/iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 1880
201 | /etc/init.d/iptables save
202 | /bin/sed -i 's/HOSTNAME=localhost.localdomain/HOSTNAME=nodered/g' /etc/sysconfig/network
203 | /usr/bin/install -d -o ec2-user -g ec2-user 755 /home/ec2-user/.node-red
204 | /usr/bin/curl https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_Connect_Device.json > /home/ec2-user/.node-red/flows_nodered.json
205 | reboot
206 |
207 | SGSNodeRed:
208 | Type: "AWS::EC2::SecurityGroup"
209 | Properties:
210 | GroupDescription: Security controls for NodeRed instance
211 | SecurityGroupEgress:
212 | - # For yum updates
213 | IpProtocol: tcp
214 | FromPort: '80'
215 | ToPort: '80'
216 | CidrIp: 0.0.0.0/0
217 | - # For yum updates
218 | IpProtocol: tcp
219 | FromPort: '443'
220 | ToPort: '443'
221 | CidrIp: 0.0.0.0/0
222 | - # Connection to AWS IoT
223 | IpProtocol: tcp
224 | FromPort: '8883'
225 | ToPort: '8883'
226 | CidrIp: 0.0.0.0/0
227 | SecurityGroupIngress:
228 | -
229 | IpProtocol: tcp
230 | FromPort: '80'
231 | ToPort: '80'
232 | CidrIp: !Ref AllowedIPRange
233 | VpcId: !Ref VPC
234 |
235 | AMIInfo:
236 | Type: Custom::AMIInfo
237 | Properties:
238 | ServiceToken: !GetAtt AMIInfoFunction.Arn
239 | Region: !Ref "AWS::Region"
240 | Architecture:
241 | Fn::FindInMap:
242 | - AWSInstanceType2Arch
243 | - !Ref InstanceType
244 | - Arch
245 |
246 | AMIInfoFunction:
247 | Properties:
248 | Description: Return AMI of Amazon Linux
249 | Handler: index.handler
250 | Runtime: python3.6
251 | Role: !GetAtt LambdaExecutionRole.Arn
252 | Timeout: 60
253 | Code:
254 | ZipFile: |
255 | import cfnresponse
256 | import boto3
257 | from botocore.exceptions import ClientError
258 | from operator import itemgetter
259 | import json
260 | import time
261 | import logging
262 | logger = logging.getLogger()
263 | logger.setLevel(logging.INFO)
264 |
265 | archToAMINamePattern = {
266 | 'PV64': 'amzn-ami-pv*x86_64-ebs',
267 | 'HVM64': 'amzn-ami-hvm*x86_64-gp2',
268 | 'HVMG2': 'amzn-ami-graphics-hvm*x86_64-ebs*'
269 | }
270 |
271 | def handler(event, context):
272 | responseData = {}
273 | try:
274 | logger.info('Received event: {}'.format(json.dumps(event)))
275 | #Assume failed unless we find a match
276 | result = cfnresponse.FAILED
277 | if event['RequestType'] == 'Create' or event['RequestType'] == 'Update':
278 | ec2 = boto3.client('ec2', region_name=event['ResourceProperties']['Region'])
279 | start_time = time.time()
280 | result = ec2.describe_images( Filters=[
281 | {
282 | 'Name': 'name',
283 | 'Values': [
284 | archToAMINamePattern[event['ResourceProperties']['Architecture']]
285 | ]
286 | },
287 | ],
288 | Owners=[ '679593333241' if event['ResourceProperties']['Architecture'] == "HVMG2" else 'amazon']
289 | )
290 | end_time = time.time()
291 | logger.info('Describe instances for {} region took {} seconds'.format(event['ResourceProperties']['Region'], end_time - start_time))
292 | images = sorted(result['Images'], key=itemgetter('Description'), reverse=True)
293 | for x in images:
294 | if '.rc' in x['Description'].lower() or 'beta' in x['Description'].lower():
295 | continue
296 | result = cfnresponse.SUCCESS
297 | responseData['Id'] = x['ImageId']
298 | break
299 | elif event['RequestType'] == 'Delete':
300 | result = cfnresponse.SUCCESS
301 | except ClientError as e:
302 | logger.error('Error: {}'.format(e))
303 | result = cfnresponse.FAILED
304 | logger.info('Returning response of: {}, with result of: {}'.format(result, responseData))
305 | cfnresponse.send(event, context, result, responseData)
306 |
307 |
308 | Type: AWS::Lambda::Function
309 |
310 | LambdaExecutionRole:
311 | Type: AWS::IAM::Role
312 | Properties:
313 | Path: '/immersionday_iot/'
314 | AssumeRolePolicyDocument:
315 | Version: 2012-10-17
316 | Statement:
317 | - Effect: Allow
318 | Principal:
319 | Service: lambda.amazonaws.com
320 | Action: sts:AssumeRole
321 | Policies:
322 | - PolicyName: root
323 | PolicyDocument:
324 | Version: '2012-10-17'
325 | Statement:
326 | - Effect: Allow
327 | Action:
328 | - logs:CreateLogGroup
329 | - logs:CreateLogStream
330 | - logs:PutLogEvents
331 | Resource: arn:aws:logs:*:*:*
332 | - Effect: Allow
333 | Action:
334 | - ec2:DescribeImages
335 | Resource: "*"
336 |
337 | Outputs:
338 | HostIPAddress:
339 | Description: 'Node-RED Host IP Address'
340 | Value: !GetAtt EC2Instance.PublicIp
341 | DefaultUser:
342 | Description: 'Username for Node-RED Host'
343 | Value: 'ec2-user'
344 | NodeREDURL:
345 | Description: 'Link to Node-RED GUI'
346 | Value: !Join [ '', [ 'http://', !GetAtt EC2Instance.PublicIp] ]
347 |
348 |
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/templates/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/2_ImplementSecWithIoT/templates/.gitkeep
--------------------------------------------------------------------------------
/SID402Workshop/2_ImplementSecWithIoT/templates/IoT_Security_Lab_VPC.yaml:
--------------------------------------------------------------------------------
1 | AWSTemplateFormatVersion: "2010-09-09"
2 |
3 | Description:
4 | Creates a complete VPC, Node-RED EC2 instance, and public IP address. The
5 | Output tab has the specifics for directly accessing the instance or to SSH
6 | to the instance.
7 |
8 | Parameters:
9 | InstanceType:
10 | Description: 'EC2 instance type'
11 | Type: 'String'
12 | Default: 't2.micro'
13 | AllowedValues:
14 | - t2.nano
15 | - t2.micro
16 | - t2.small
17 | - t2.medium
18 | ConstraintDescription: 'Must be a valid EC2 instance type.'
19 | AllowedIPRange:
20 | Description: "The IP address range that can be used to SSH and connet to Node-RED to the EC2 instance"
21 | Type: "String"
22 | MinLength: "9"
23 | MaxLength: "18"
24 | Default: "0.0.0.0/0"
25 | AllowedPattern: "(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/(\\d{1,2})"
26 | ConstraintDescription: "must be a valid IP CIDR range of the form x.x.x.x/x."
27 |
28 | Mappings:
29 | AWSInstanceType2Arch:
30 | t2.nano:
31 | 'Arch': 'HVM64'
32 | t2.micro:
33 | 'Arch': 'HVM64'
34 | t2.small:
35 | 'Arch': 'HVM64'
36 | t2.medium:
37 | 'Arch': 'HVM64'
38 |
39 | Resources:
40 | VPC:
41 | Type: 'AWS::EC2::VPC'
42 | Properties:
43 | CidrBlock: 172.31.0.0/24
44 | EnableDnsSupport: true
45 | EnableDnsHostnames: true
46 | InstanceTenancy: default
47 | Tags:
48 | - Key: Name
49 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED' ] ]
50 | InternetGateway:
51 | Type: 'AWS::EC2::InternetGateway'
52 | Properties:
53 | Tags:
54 | - Key: Name
55 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED' ] ]
56 | VPCGatewayAttachment:
57 | Type: 'AWS::EC2::VPCGatewayAttachment'
58 | Properties:
59 | VpcId: !Ref VPC
60 | InternetGatewayId: !Ref InternetGateway
61 | SubnetAPublic:
62 | Type: 'AWS::EC2::Subnet'
63 | Properties:
64 | CidrBlock: 172.31.0.0/24
65 | MapPublicIpOnLaunch: true
66 | VpcId: !Ref VPC
67 | Tags:
68 | - Key: Name
69 | Value: !Join [ "-", [ !Sub '${AWS::StackName}', 'Node-RED-public' ] ]
70 | RouteTablePublic:
71 | Type: 'AWS::EC2::RouteTable'
72 | Properties:
73 | VpcId: !Ref VPC
74 | Tags:
75 | - Key: Name
76 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED-public' ] ]
77 | RouteTableAssociationAPublic:
78 | Type: 'AWS::EC2::SubnetRouteTableAssociation'
79 | Properties:
80 | SubnetId: !Ref SubnetAPublic
81 | RouteTableId: !Ref RouteTablePublic
82 | RouteTablePublicInternetRoute: # should be RouteTablePublicAInternetRoute, but logical id was not changed for backward compatibility
83 | Type: 'AWS::EC2::Route'
84 | DependsOn: VPCGatewayAttachment
85 | Properties:
86 | RouteTableId: !Ref RouteTablePublic
87 | DestinationCidrBlock: '0.0.0.0/0'
88 | GatewayId: !Ref InternetGateway
89 | EC2Instance:
90 | Type: "AWS::EC2::Instance"
91 | Properties:
92 | ImageId: !GetAtt AMIInfo.Id
93 | InstanceType: !Ref InstanceType
94 | NetworkInterfaces:
95 | - AssociatePublicIpAddress: "true"
96 | DeviceIndex: "0"
97 | GroupSet:
98 | - Ref: "SGSNodeRed"
99 | SubnetId: !Ref SubnetAPublic
100 | Tags:
101 | - Key: Name
102 | Value: !Join [ '-', [ !Sub '${AWS::StackName}', 'Node-RED' ] ]
103 | UserData:
104 | "Fn::Base64":
105 | "Fn::Sub": |
106 | #!/bin/bash
107 | yum upgrade -y
108 | yum install -y gcc-c++ make
109 | curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
110 | yum install -y nodejs
111 | mkdir /opt/.npm
112 | echo 'prefix = /opt/.npm' > ~/.npmrc
113 | echo 'export PATH=$PATH:/opt/.npm/bin' >> /home/ec2-user/.bashrc
114 | npm install -g --unsafe-perm node-red
115 |
116 | # Install supervisor
117 | pip install supervisor
118 | /usr/local/bin/echo_supervisord_conf > /etc/supervisord.conf
119 | # Append config for node-red
120 | cat << 'EOF' >> /etc/supervisord.conf
121 | [program:nodered]
122 | command=/opt/.npm/bin/node-red
123 | directory=/home/ec2-user
124 | autostart=true
125 | autorestart=true
126 | startretries=3
127 | stderr_logfile=/home/ec2-user/nodered.err.log
128 | stdout_logfile=/home/ec2-user/nodered.out.log
129 | user=ec2-user
130 | environment=HOME="/home/ec2-user"
131 | EOF
132 |
133 | cat << 'EOF' >> supervisor
134 | #!/bin/bash
135 | #
136 | # supervisor Start/Stop the supervisor daemon.
137 | #
138 | # chkconfig: 345 90 10
139 | # description: Supervisor is a client/server system that allows its users to
140 | # monitor and control a number of processes on UNIX-like operating
141 | # systems.
142 |
143 | . /etc/init.d/functions
144 |
145 | DAEMON=/usr/local/bin/supervisord
146 | PIDFILE=/var/run/supervisord.pid
147 |
148 | [ -x "$DAEMON" ] || exit 0
149 |
150 | start() {
151 | echo -n "Starting supervisord: "
152 | if [ -f $PIDFILE ]; then
153 | PID=`cat $PIDFILE`
154 | echo supervisord already running: $PID
155 | exit 2;
156 | else
157 | daemon $DAEMON --pidfile=$PIDFILE -c /etc/supervisord.conf -u ec2-user -d /home/ec2-user
158 | RETVAL=$?
159 | echo
160 | [ $RETVAL -eq 0 ] && touch /var/lock/subsys/supervisord
161 | return $RETVAL
162 | fi
163 |
164 | }
165 |
166 | stop() {
167 | echo -n "Shutting down supervisord: "
168 | echo
169 | killproc -p $PIDFILE supervisord
170 | echo
171 | rm -f /var/lock/subsys/supervisord
172 | return 0
173 | }
174 |
175 | case "$1" in
176 | start)
177 | start
178 | ;;
179 | stop)
180 | stop
181 | ;;
182 | status)
183 | status supervisord
184 | ;;
185 | restart)
186 | stop
187 | start
188 | ;;
189 | *)
190 | echo "Usage: {start|stop|status|restart}"
191 | exit 1
192 | ;;
193 | esac
194 | exit $?
195 | EOF
196 | mv supervisor /etc/init.d
197 | chmod +x /etc/init.d/supervisor
198 | chkconfig --add supervisor
199 | chkconfig supervisor on
200 | /sbin/iptables -A PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 1880
201 | /etc/init.d/iptables save
202 | /bin/sed -i 's/HOSTNAME=localhost.localdomain/HOSTNAME=nodered/g' /etc/sysconfig/network
203 | /usr/bin/install -d -o ec2-user -g ec2-user 755 /home/ec2-user/.node-red
204 | /usr/bin/curl https://s3-us-west-2.amazonaws.com/sid402-artifacts/scripts/IoT_Security_Lab_Connect_Device.json > /home/ec2-user/.node-red/flows_nodered.json
205 | reboot
206 |
207 | SGSNodeRed:
208 | Type: "AWS::EC2::SecurityGroup"
209 | Properties:
210 | GroupDescription: Security controls for NodeRed instance
211 | SecurityGroupEgress:
212 | - # For yum updates
213 | IpProtocol: tcp
214 | FromPort: '80'
215 | ToPort: '80'
216 | CidrIp: 0.0.0.0/0
217 | - # For yum updates
218 | IpProtocol: tcp
219 | FromPort: '443'
220 | ToPort: '443'
221 | CidrIp: 0.0.0.0/0
222 | - # Connection to AWS IoT
223 | IpProtocol: tcp
224 | FromPort: '8883'
225 | ToPort: '8883'
226 | CidrIp: 0.0.0.0/0
227 | SecurityGroupIngress:
228 | -
229 | IpProtocol: tcp
230 | FromPort: '80'
231 | ToPort: '80'
232 | CidrIp: !Ref AllowedIPRange
233 | VpcId: !Ref VPC
234 |
235 | AMIInfo:
236 | Type: Custom::AMIInfo
237 | Properties:
238 | ServiceToken: !GetAtt AMIInfoFunction.Arn
239 | Region: !Ref "AWS::Region"
240 | Architecture:
241 | Fn::FindInMap:
242 | - AWSInstanceType2Arch
243 | - !Ref InstanceType
244 | - Arch
245 |
246 | AMIInfoFunction:
247 | Properties:
248 | Description: Return AMI of Amazon Linux
249 | Handler: index.handler
250 | Runtime: python3.6
251 | Role: !GetAtt LambdaExecutionRole.Arn
252 | Timeout: 60
253 | Code:
254 | ZipFile: |
255 | import cfnresponse
256 | import boto3
257 | from botocore.exceptions import ClientError
258 | from operator import itemgetter
259 | import json
260 | import time
261 | import logging
262 | logger = logging.getLogger()
263 | logger.setLevel(logging.INFO)
264 |
265 | archToAMINamePattern = {
266 | 'PV64': 'amzn-ami-pv*x86_64-ebs',
267 | 'HVM64': 'amzn-ami-hvm*x86_64-gp2',
268 | 'HVMG2': 'amzn-ami-graphics-hvm*x86_64-ebs*'
269 | }
270 |
271 | def handler(event, context):
272 | responseData = {}
273 | try:
274 | logger.info('Received event: {}'.format(json.dumps(event)))
275 | #Assume failed unless we find a match
276 | result = cfnresponse.FAILED
277 | if event['RequestType'] == 'Create' or event['RequestType'] == 'Update':
278 | ec2 = boto3.client('ec2', region_name=event['ResourceProperties']['Region'])
279 | start_time = time.time()
280 | result = ec2.describe_images( Filters=[
281 | {
282 | 'Name': 'name',
283 | 'Values': [
284 | archToAMINamePattern[event['ResourceProperties']['Architecture']]
285 | ]
286 | },
287 | ],
288 | Owners=[ '679593333241' if event['ResourceProperties']['Architecture'] == "HVMG2" else 'amazon']
289 | )
290 | end_time = time.time()
291 | logger.info('Describe instances for {} region took {} seconds'.format(event['ResourceProperties']['Region'], end_time - start_time))
292 | images = sorted(result['Images'], key=itemgetter('Description'), reverse=True)
293 | for x in images:
294 | if '.rc' in x['Description'].lower() or 'beta' in x['Description'].lower():
295 | continue
296 | result = cfnresponse.SUCCESS
297 | responseData['Id'] = x['ImageId']
298 | break
299 | elif event['RequestType'] == 'Delete':
300 | result = cfnresponse.SUCCESS
301 | except ClientError as e:
302 | logger.error('Error: {}'.format(e))
303 | result = cfnresponse.FAILED
304 | logger.info('Returning response of: {}, with result of: {}'.format(result, responseData))
305 | cfnresponse.send(event, context, result, responseData)
306 |
307 |
308 | Type: AWS::Lambda::Function
309 |
310 | LambdaExecutionRole:
311 | Type: AWS::IAM::Role
312 | Properties:
313 | Path: '/immersionday_iot/'
314 | AssumeRolePolicyDocument:
315 | Version: 2012-10-17
316 | Statement:
317 | - Effect: Allow
318 | Principal:
319 | Service: lambda.amazonaws.com
320 | Action: sts:AssumeRole
321 | Policies:
322 | - PolicyName: root
323 | PolicyDocument:
324 | Version: '2012-10-17'
325 | Statement:
326 | - Effect: Allow
327 | Action:
328 | - logs:CreateLogGroup
329 | - logs:CreateLogStream
330 | - logs:PutLogEvents
331 | Resource: arn:aws:logs:*:*:*
332 | - Effect: Allow
333 | Action:
334 | - ec2:DescribeImages
335 | Resource: "*"
336 |
337 | Outputs:
338 | HostIPAddress:
339 | Description: 'Node-RED Host IP Address'
340 | Value: !GetAtt EC2Instance.PublicIp
341 | DefaultUser:
342 | Description: 'Username for Node-RED Host'
343 | Value: 'ec2-user'
344 | NodeREDURL:
345 | Description: 'Link to Node-RED GUI'
346 | Value: !Join [ '', [ 'http://', !GetAtt EC2Instance.PublicIp] ]
347 |
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/README.md:
--------------------------------------------------------------------------------
1 | ## re:Invent 2017 - SID402
2 |
3 | # Module 3 - Automating Security Remediation in AWS
4 |
5 | ### Introduction
6 |
7 | The Security Enhancement Project at IthaCorp is continuing to progress and you decide its time to implement responsive controls in order to automate remediation of security baseline deviations. This will help reduce overhead on the engineering team and allow them to focus on several strategic initiatives.
8 |
9 | #### Monitoring Security Groups with AWS Config
10 |
11 | In this lab you will learn how to use AWS Config Rules with an AWS Lambda function to monitor the ingress ports associated with an EC2 security group. The Lambda function will be triggered whenever the security group is modified. If the ingress rule configuration differs from that which is coded in the function, the Lambda function will revert the ingress rules back to the appropriate configuration. The activity from the Lambda function can then be viewed through Amazon CloudWatch Logs. In an accompanying lab, Monitoring Security Groups with Amazon CloudWatch Events, you will use a different set of services to monitor security groups. These two labs demonstrate techniques that can be used to provide additional layers of protection to infrastructure assets.
12 |
13 | ### Architecture Overview
14 |
15 | 
16 |
17 | ### Topics covered
18 |
19 | By the end of this module, you will be able to:
20 |
21 | 1. Upload a preconfigured Lambda function
22 |
23 | 2. Enable AWS Config
24 |
25 | 3. Create and enable a custom AWS Config rule
26 |
27 | 4. Use CloudWatch Logs to review the execution of the AWS Config rule
28 |
29 | ### Prerequisites
30 |
31 | To successfully complete this module, you should be familiar with EC2 security groups. Python programming skills are helpful, although full solution code is provided.
32 |
33 | ### 1. Select a Region
34 |
35 | Login to the AWS Console. Make sure that the user has "Admin" rights to the AWS services. Not using an Admin user will create permission issues during the module. Make a note of the AWS *region name*, for example, *EU (Ireland),*
36 |
37 | **Tip** The AWS region name is always listed in the upper-right corner of the AWS Management Console, in the navigation bar.
38 |
39 | For more information about regions, see [AWS Regions and Endpoints](http://docs.aws.amazon.com/general/latest/gr/rande.html).
40 |
41 | ___Complete all the steps below unless they are marked "optional". Use left arrow to expand sections marked with (expand for details).___
42 |
43 | ### 2. Complete Initial Environment Configuration
44 |
45 |
46 | 2.1. Enable AWS Config (expand for details)
47 |
48 |
49 |
50 | - __2.1.1.__ On the **Services** menu, click **Config**.
51 |
52 | - __2.1.2.__ Click **Get Started** if you see a button with that text, else click
53 | **Settings**.
54 |
55 | - __2.1.3.__ Under Resource types to record, ***uncheck*** the box **Record all resources supported in this region**.
56 |
57 | - __2.1.4.__ Click inside of the **Specific types** box. A scroll box field will appear. Scroll down to the EC2 section and click **SecurityGroup**. You should see **EC2: Security Group** appear in the **Specific types** box. Click outside of the box to close the scroll box field.
58 |
59 | - __2.1.5.__ Under **Amazon S3 bucket**, select **Create a bucket**. In the **Bucket name** field, use the default name that is provided. Leave the **Prefix (optional)** text box empty. *Make sure that the Bucket Name is not already created else you will get a bucket already exist error.*
60 |
61 | - __2.1.6.__ Under **AWS Config Role**, select **Create a Role**. In the **Role name** field, use the default name that is provided.
62 |
63 | - __2.1.7.__ Click the **Next** button at the bottom right of the web page.
64 |
65 | - __2.1.8.__ On the **AWS Config Rules** page, do not select any rules. You will add a custom rule later. Click **Next**.
66 |
67 | - __2.1.9.__ On the **Review** page, click **Confirm.** After a while, you will see the **Config Dashboard** page appear.
68 |
69 | 
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | 2.2. Create an EC2 Security Group (expand for details)
78 |
79 |
80 |
81 | - __2.2.1.__ Click the **Services** menu and select **VPC.** The **VPC Dashboard** will appear.
82 |
83 | - __2.2.2.__ On the left hand side of the window click **Security Groups**.
84 |
85 | - __2.2.3.__ Click **Create Security Group button**.
86 |
87 | - __2.2.4.__ In the **Name tag** text box, enter "SID402Module3SG". The **Group name** text box should populate automatically.
88 |
89 | - __2.2.5.__ In the Description text box, enter "Module 3 Security Group". Keep the default VPC in the **VPC** drop down list.
90 |
91 | - __2.2.6.__ Click **Yes, Create** button.
92 |
93 | - __2.2.7.__ Select the **SID402Module3SG** Security Group. Copy the group identifier which will be in the form of sg-######## to a scratch file as you will need it later.
94 |
95 | - __2.2.8.__ Click on the **Inbound Rules** tab and click the **Edit** button.
96 |
97 | - __2.2.9.__ Add the Inbound Rules. Your Inbound Rules should look like this:
98 |
99 |
100 |
101 | 
102 |
103 |
104 |
105 | You have now set up the ingress configuration of the default security
106 |
107 |
108 |
109 | 2.3. Create and Run the AWS Config Rule (expand for details)
110 |
111 |
112 |
113 | - __2.3.1.__ Click on the **Services** menu and select **Config.** The AWS Config page will appear.
114 |
115 | - __2.3.2.__ On the left side of the window, click **Rules**. On the bottom of the window, you should see “*No rules. Click Add rule to create a rule”.* Go ahead and click the **Add rule** button. The **Add rule** page will appear.
116 |
117 | - __2.3.3.__ Click the **Add custom rule** button.
118 |
119 | - __2.3.4.__ In the **Name** field, enter **EC2SecurityGroup**.
120 |
121 | - __2.3.5.__ In the Description field enter “Restrict ingress ports to HTTP and
122 | HTTPS”.
123 |
124 | - __2.3.6.__ Click the **Create AWS Lambda function** link. Click **Author From
125 | Scratch** button.
126 |
127 | - __2.3.7.__ In the Name field enter **awsconfig_lambda_security_group**.
128 |
129 | - __2.3.8.__ In the **Role** field select **Create a custom role** and a new page
130 | window will appear.
131 |
132 | - __2.3.9.__ In the **IAM Role** field, select **Create new IAM Role** from the list and in the **Role Name** text box enter **awsconfig_lambda_ec2_security_group_role**.
133 |
134 | - __2.3.10.__ Click on **View Policy Document** to open the policy window and then click on the **Edit** link. Click **Ok** if a warning message appears about reading the documentation.
135 |
136 | - __2.3.11.__ In the policy window erase the existing content and enter the following:
137 |
138 | ````
139 | {
140 | "Version": "2012-10-17",
141 | "Statement": [
142 | {
143 | "Effect": "Allow",
144 | "Action": [
145 | "logs:CreateLogGroup",
146 | "logs:CreateLogStream",
147 | "logs:PutLogEvents"
148 | ],
149 | "Resource": "arn:aws:logs:*:*:*"
150 | },
151 | {
152 | "Effect": "Allow",
153 | "Action": [
154 | "config:PutEvaluations",
155 | "ec2:DescribeSecurityGroups",
156 | "ec2:AuthorizeSecurityGroupIngress",
157 | "ec2:RevokeSecurityGroupIngress"
158 | ],
159 | "Resource": "*"
160 | }
161 | ]
162 | }
163 | ````
164 |
165 | - __2.3.12.__ Click the **Allow** button. The page will close and you will return to the Lambda **Basic Information** page.
166 |
167 | - __2.3.13.__ Click **Create function**
168 |
169 | - __2.3.14.__ For Runtime select **Python 2.7**.
170 |
171 | - __2.3.15.__ For Code entry type select **Upload a .ZIP file**
172 |
173 | - __2.3.16.__ Download this file the [awsconfig_lambda_security_group.zip](https://s3-us-west-2.amazonaws.com/sid402-artifacts/lambda/awsconfig_lambda_security_group.py.zip) file and save it on your computer. Click the Upload button under Function Package and upload the file you just downloaded.
174 |
175 | - __2.3.17.__ In the Handler field enter **awsconfig_lambda_security_group.lambda_handler**.
176 |
177 | - __2.3.18.__ Leave the **Memory (MB)** field under Basic Settings field with the default value of 128.
178 |
179 | - __2.3.19.__ In the **Timeout** fields, set **min** to 1 and **sec** to 0. Lambda functions can run for a maximum of five minutes. This is particular function typically takes less than five seconds to run so allowing one minute should be more than adequate.
180 |
181 | - __2.3.20.__ For **VPC** under Network tab, accept the default value of **No VPC**.
182 |
183 | - __2.3.21.__ Click the “Save” button at the top of the page.
184 |
185 | - __2.3.22.__ You should see Python code that looks similar to what appears below. If you don’t see code, revisit the work you did in steps 14 and 15. The part of the handler name to the left of the period must match the file name.
186 |
187 | 
188 |
189 | Let’s take a look at a few things in the code. Scroll down to where you see the value **REQUIRED_PERMISSIONS**.
190 |
191 | 
192 |
193 | This is an array of desired ingress IP Permissions in the format used by the **describe_security_groups()** API call which is used later in the code. Notice that the array only contains permissions for HTTP (TCP port 80) and HTTPS (TCP port 443). It does not contain the permissions we added for SMTPS (TCP port 465) and IMAPS (TCP port 993).
194 |
195 | If the ingress permissions contain anything other than the permissions in this array, the code uses the
196 | **authorize_security_group_ingress()** and **revoke_security_group_ingress()** calls to add or remove
197 | permissions as appropriate. Therefore, we should expect that the SMTPS (TCP port 465) and IMAPS (TCP port 993) permissions should be removed when we run this function.
198 |
199 | - __2.3.23.__ On the upper right part of the page you should some text following **ARN**. Copy the text beginning with **arn:aws:lambda** all the way to the end into scratch text file or leave it in your copy/paste buffer. It should look something like this: *arn:aws:lambda:us-west-2:account number:function:awsconfig_lambda_security_group*
200 |
201 | Go back to the **AWS Config** page that should still be open to **Add custom rule**.
202 |
203 | __Note:__ If you closed the AWS Config page accidentally, then go back to the Lambda page you were just on and click **Services** and select **Config** and do steps 2.1-2.5 again and then continue below.
204 |
205 | - __2.3.24.__ In the **AWS Lambda function ARN** field, enter the **arn:aws:lambda** value that you copied in the previous step.
206 |
207 | - __2.3.25.__ For Trigger type select **Configuration changes**.
208 |
209 | - __2.3.26.__ For **Scope of changes** select the radio box for **Resources**. Click in the **Resources** text box scroll box will appear.
210 |
211 | - __2.3.27.__ Pick **EC2: SecurityGroup**. Enter the security group identifier you copied earlier (in the form of sg-########) into the **Resource identifier** field.
212 |
213 | - __2.3.28.__ In **Rule parameters**, in the **Key** field enter **debug** and in the **Value** field enter **true** to generate additional data you can look at later if you choose.
214 |
215 | - __2.3.29.__ Click **Save**. You will return to the AWS Config Rules page. Under the **Compliance** column, you will see the function has been submitted for an initial evaluation. This initial evaluation may take several minutes to complete. This same evaluation will also take place whenever the security group is changed again in the future. Click the refresh button periodically as well to update the evaluation status.
216 |
217 | 
218 |
219 | - __2.3.30.__ Once the compliance evaluation has taken place, you should see the
220 | following:
221 |
222 | 
223 |
224 |
225 | ### 3. Verify Expected Behavior
226 |
227 |
228 | 3.1. Revisiting the VPC Security Group (expand for details)
229 |
230 |
231 |
232 | - __3.1.1.__ We will now examine the VPC security group that we had previously created to allow HTTP, HTTPS, IMAPS, and SMTPS traffic. Click the **Services** menu and select **VPC**. The **VPC Dashboard** will appear.
233 |
234 | - __3.1.2.__ On the left hand side of the window click Security Groups.
235 |
236 | - __3.1.3.__ Click the **Inbound** tab that appears below. Notice that only HTTP and HTTPS traffic are permitted as shown below.
237 |
238 | 
239 |
240 | This corresponds to the **REQUIRED_PERMISSIONS** that were configured into the Lambda function as described in step 44. The Lambda function detected the additional permissions for SMTPS (TCP port 465) and IMAPS (TCP port 993) that were present in the security group and removed them. In this case, the detection happened during the initial rule validation. If you were to modify the security group again, a
241 | compliance evaluation would be triggered which would again invoke the Lambda function and the changes would be reverted.
242 |
243 |
244 |
245 | 3.2. Using Amazon CloudWatch Logs for Verification (expand for details)
246 |
247 |
248 |
249 | - __3.2.1.__ We will now use Amazon CloudWatch Logs to see what the Lambda function did. Click the **Services** menu and select **Cloudwatch.**
250 |
251 | - __3.2.2.__ On the left side of page, select **Logs**.
252 |
253 | - __3.2.3.__ Click on the link that contains **awsconfig_lambda_security_group**.
254 |
255 | - __3.2.4.__ Under **Log Streams**, beginning with the top link, click each link until you see an entry that contains the words **revoking for** and expand the entry. You should see something similar to this. The security group values have been blacked out. This shows that the two entries for ports 993 and 465 have been removed.
256 |
257 | 
258 |
259 | - __3.2.5.__ (Optional) If have another 15 minutes remaining, modify the ingress ports of the security group as described in steps 17-24. That will trigger another evaluation of the security group configuration. After 8-13 minutes, the ingress port configuration will revert to include only HTTP (TCP port 80) and HTTPS (TCP port 443). You will be able to verify this by revisiting the security group settings.
260 |
261 |
262 |
263 |
264 | # ___VICTORY!___
265 |
266 |
267 |
268 | ### Conclusion
269 |
270 | Congratulations! You have now successfully:
271 |
272 | 1. Enabled AWS Config
273 |
274 | 2. Uploaded a Lambda function to support a rule for AWS Config that
275 | evaluations permissions on an EC2 security group.
276 |
277 | 3. Modified the default VPC Security group to contain both compliant
278 | and noncompliant permissions
279 |
280 | 4. Enabled the AWS Config Rule and observed the results
281 |
282 | 5. Examined the activity of the Lambda function using Amazon Cloudwatch
283 | Logs.
284 |
285 | ### Clean Up
286 |
287 | ___Complete clean up at the end of the Workshop___
288 |
289 |
290 | 1. Module 1 Clean Up (expand for details)
291 |
292 |
293 |
294 | 1. In the AWS Management Console, on the Services menu, click CloudFormation
295 | 2. select SID402-AutomatingSecurityEvents
296 | 3. click on Actions, select Delete Stack
297 | 4. click on Yes, Delete to confirm deletion
298 | 5. repeat steps 2-4 to delete the SID402-CWLforCloudTrailAPIActivity Stack
299 | 6. In the AWS Management Console, on the Services menu, click CloudWatch
300 | 7. Under Alarms, select S3 Bucket Activity
301 | 8. click on Actions, select Delete
302 | 9. click on Yes, Delete
303 | 10. In the AWS Management Console, on the Services menu, click CloudTrail
304 | 11. Open the trail that you created in this module
305 | 12. In top right, next to Logging, click on "On/Off" switch
306 | 13. Click Continue in the popup window
307 | 14. Click on the "trash can" icon to delete the trail
308 | 15. Click Delete in the popup window
309 |
310 |
311 |
312 | 2. Module 2 Clean Up (expand for details)
313 |
314 |
315 |
316 | 1. Delete the AWS CloudFormation stack you previously launched.
317 |
318 | 2. Remove all IOT configuration items (things, certificates, policies).
319 |
320 |
321 |
322 | 3. Module 3 Clean Up (expand for details)
323 |
324 |
325 |
326 | 1. Delete the IAM role "awsconfig_lambda_ec2_security_group_role".
327 |
328 | 2. Delete the AWS Config Rule "EC2SecurityGroup".
329 |
330 | 3. If AWS Config was not enabled, turn off AWS Config in Config Settings.
331 |
332 | 4. Delete the Lambda function "awsconfig_lambda_security_group".
333 |
334 | 5. Delete s3 bucket for config if created during lab: config-bucket-
335 |
336 | 6. Delete config role if created "config-role-"
337 |
338 | 7. Delete cloudwatch logs group "/aws/lambda/awsconfig_lambda_security_group"
339 |
340 |
341 | ### Additional Resources
342 |
343 | For more information about AWS Lambda and Amazon CloudWatch, see:
344 |
345 | 1. For more information about AWS Config, see
346 |
347 |
348 | 2. For more information about AWS Lambda, see
349 |
350 |
351 | 3. For more information about Amazon CloudWatch, see
352 |
353 |
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/.gitkeep
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/diagramm3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/diagramm3.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image1.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image11.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image11.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image12.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image12.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image3.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image4.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image5.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image5.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image6.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image6.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image7.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image7.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image8.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image8.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/images/image9.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/images/image9.png
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/lambda/awsconfig_lambda_security_group.py:
--------------------------------------------------------------------------------
1 | #
2 | # This file made available under CC0 1.0 Universal (https://creativecommons.org/publicdomain/zero/1.0/legalcode)
3 | #
4 | # awsconfig_lambda_security_group.py
5 | # Trigger Type: Change Triggered
6 | #
7 | # Author: jslevine@
8 | # Date: 2016-09-05
9 | #
10 | #
11 | # This file contains an AWS Lambda handler which responds to AWS Config triggers in AWS EC2 security groups.
12 | # The Lambda function examines changes in the security group ingress permissions to see if they differ from
13 | # the required permissions as specificed in the REQUIRED_PERMISSIONS variable below. If so, the Lambda
14 | # function adds or removes ingress ports as needed. Egress rules are not checked.
15 | #
16 | # NOTES:
17 | #
18 | # This code is only intended for instructional purposes and should not be used for any other use.
19 |
20 | import boto3
21 | import botocore
22 | import json
23 |
24 |
25 | APPLICABLE_RESOURCES = ["AWS::EC2::SecurityGroup"]
26 |
27 | # Specify the required ingress permissions using the same key layout as that provided in the
28 | # describe_security_group API response and authorize_security_group_ingress/egress API calls.
29 |
30 | REQUIRED_PERMISSIONS = [
31 | {
32 | "IpProtocol" : "tcp",
33 | "FromPort" : 80,
34 | "ToPort" : 80,
35 | "UserIdGroupPairs" : [],
36 | "IpRanges" : [{"CidrIp" : "0.0.0.0/0"}],
37 | "PrefixListIds" : [],
38 | "Ipv6Ranges": []
39 | },
40 | {
41 | "IpProtocol" : "tcp",
42 | "FromPort" : 443,
43 | "ToPort" : 443,
44 | "UserIdGroupPairs" : [],
45 | "IpRanges" : [{"CidrIp" : "0.0.0.0/0"}],
46 | "PrefixListIds" : [],
47 | "Ipv6Ranges": []
48 | }]
49 |
50 | # normalize_parameters
51 | #
52 | # Normalize all rule parameters so we can handle them consistently.
53 | # All keys are stored in lower case. Only boolean and numeric keys are stored.
54 |
55 | def normalize_parameters(rule_parameters):
56 | for key, value in rule_parameters.iteritems():
57 | normalized_key=key.lower()
58 | normalized_value=value.lower()
59 |
60 | if normalized_value == "true":
61 | rule_parameters[normalized_key] = True
62 | elif normalized_value == "false":
63 | rule_parameters[normalized_key] = False
64 | elif normalized_value.isdigit():
65 | rule_parameters[normalized_key] = int(normalized_value)
66 | else:
67 | rule_parameters[normalized_key] = True
68 | rule_parameters[normalized_key] = rule_parameters.pop(normalized_key)
69 | return rule_parameters
70 |
71 | # evaluate_compliance
72 | #
73 | # This is the main compliance evaluation function.
74 | #
75 | # Arguments:
76 | #
77 | # configuration_item - the configuration item obtained from the AWS Config event
78 | # debug_enabled - debug flag
79 | #
80 | # return values:
81 | #
82 | # compliance_type -
83 | #
84 | # NOT_APPLICABLE - (1) something other than a security group is being evaluated
85 | # (2) the configuration item is being deleted
86 | # NON_COMPLIANT - the rules do not match the required rules and we couldn't
87 | # fix them
88 | # COMPLIANT - the rules match the required rules or we were able to fix
89 | # them
90 | #
91 | # annotation - the annotation message for AWS Config
92 |
93 | def evaluate_compliance(configuration_item, debug_enabled):
94 | if configuration_item["resourceType"] not in APPLICABLE_RESOURCES:
95 | return {
96 | "compliance_type" : "NOT_APPLICABLE",
97 | "annotation" : "The rule doesn't apply to resources of type " +
98 | configuration_item["resourceType"] + "."
99 | }
100 |
101 | if configuration_item["configurationItemStatus"] == "ResourceDeleted":
102 | return {
103 | "compliance_type": "NOT_APPLICABLE",
104 | "annotation": "The configurationItem was deleted and therefore cannot be validated."
105 | }
106 |
107 | group_id = configuration_item["configuration"]["groupId"]
108 | client = boto3.client("ec2");
109 |
110 | try:
111 | response = client.describe_security_groups(GroupIds=[group_id])
112 | except botocore.exceptions.ClientError as e:
113 | return {
114 | "compliance_type" : "NON_COMPLIANT",
115 | "annotation" : "describe_security_groups failure on group " + group_id
116 | }
117 |
118 | if debug_enabled:
119 | print("security group definition: ", json.dumps(response, indent=2))
120 |
121 | ip_permissions = response["SecurityGroups"][0]["IpPermissions"]
122 | authorize_permissions = [item for item in REQUIRED_PERMISSIONS if item not in ip_permissions]
123 | revoke_permissions = [item for item in ip_permissions if item not in REQUIRED_PERMISSIONS]
124 |
125 | if authorize_permissions or revoke_permissions:
126 | annotation_message = "Permissions were modified."
127 | else:
128 | annotation_message = "Permissions are correct."
129 |
130 | if authorize_permissions:
131 | if debug_enabled:
132 | print("authorizing for ", group_id, ", ip_permissions ", json.dumps(authorize_permissions, indent=2))
133 |
134 | try:
135 | client.authorize_security_group_ingress(GroupId=group_id, IpPermissions=authorize_permissions)
136 | annotation_message += " " + str(len(authorize_permissions)) +" new authorization(s)."
137 | except botocore.exceptions.ClientError as e:
138 | return {
139 | "compliance_type" : "NON_COMPLIANT",
140 | "annotation" : "authorize_security_group_ingress failure on group " + group_id
141 | }
142 |
143 | if revoke_permissions:
144 | if debug_enabled:
145 | print("revoking for ", group_id, ", ip_permissions ", json.dumps(revoke_permissions, indent=2))
146 |
147 | try:
148 | client.revoke_security_group_ingress(GroupId=group_id, IpPermissions=revoke_permissions)
149 | annotation_message += " " + str(len(revoke_permissions)) +" new revocation(s)."
150 | except botocore.exceptions.ClientError as e:
151 | return {
152 | "compliance_type" : "NON_COMPLIANT",
153 | "annotation" : "revoke_security_group_ingress failure on group " + group_id
154 | }
155 |
156 | return {
157 | "compliance_type": "COMPLIANT",
158 | "annotation": annotation_message
159 | }
160 |
161 | # lambda_handler
162 | #
163 | # This is the main handle for the Lambda function. AWS Lambda passes the function an event and a context.
164 | # If "debug" is specified as a rule parameter, then debugging is enabled.
165 |
166 | def lambda_handler(event, context):
167 | invoking_event = json.loads(event['invokingEvent'])
168 | configuration_item = invoking_event["configurationItem"]
169 | rule_parameters = normalize_parameters(json.loads(event["ruleParameters"]))
170 |
171 | debug_enabled = False
172 |
173 | if "debug" in rule_parameters:
174 | debug_enabled = rule_parameters["debug"]
175 |
176 | if debug_enabled:
177 | print("Received event: " + json.dumps(event, indent=2))
178 |
179 | evaluation = evaluate_compliance(configuration_item, debug_enabled)
180 |
181 | config = boto3.client('config')
182 |
183 | response = config.put_evaluations(
184 | Evaluations=[
185 | {
186 | 'ComplianceResourceType': invoking_event['configurationItem']['resourceType'],
187 | 'ComplianceResourceId': invoking_event['configurationItem']['resourceId'],
188 | 'ComplianceType': evaluation["compliance_type"],
189 | "Annotation": evaluation["annotation"],
190 | 'OrderingTimestamp': invoking_event['configurationItem']['configurationItemCaptureTime']
191 | },
192 | ],
193 | ResultToken=event['resultToken'])
194 |
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/lambda/awsconfig_lambda_security_group.py.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/lambda/awsconfig_lambda_security_group.py.zip
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/scripts/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/aws-samples/aws-security-odyssey/99e8c238f50eb86d7a5571e3115df214f6bf06f7/SID402Workshop/3_AutoSecRemediation/scripts/.gitkeep
--------------------------------------------------------------------------------
/SID402Workshop/3_AutoSecRemediation/templates/MonitoringSGwithAWSConfigStudentPolicy.json:
--------------------------------------------------------------------------------
1 | {
2 | "Version": "2012-10-17",
3 | "Statement": [
4 | {
5 | "Effect":"Allow",
6 | "Action":[
7 | "ec2:Describe*",
8 | "ec2:Authorize*",
9 | "elasticloadbalancing:*",
10 | "autoscaling:*",
11 | "cloudwatch:*",
12 | "elasticbeanstalk:*",
13 | "config:*",
14 | "events:*",
15 | "iam:*",
16 | "iam:AddRoleToInstanceProfile",
17 | "iam:CreateInstanceProfile",
18 | "iam:Get*",
19 | "iam:PassRole",
20 | "iam:CreateRole",
21 | "iam:PutRolePolicy",
22 | "iam:List*",
23 | "iam:CreatePolicyVersion",
24 | "iam:DeletePolicyVersion",
25 | "iam:CreatePolicy",
26 | "kms:List*",
27 | "kms:Get*",
28 | "s3:*",
29 | "sns:*",
30 | "sqs:*",
31 | "tag:Get*",
32 | "logs:*",
33 | "lambda:*",
34 | "cloudformation:*",
35 | "vpc:*"
36 | ],
37 | "Resource":"*"
38 | },
39 | {
40 | "Sid": "LimitedAttachmentPermissions",
41 | "Effect": "Allow",
42 | "Action": [
43 | "iam:AttachUserPolicy",
44 | "iam:DetachUserPolicy",
45 | "iam:DetachRolePolicy",
46 | "iam:AttachRolePolicy"
47 | ],
48 | "Resource": "*",
49 | "Condition": {
50 | "ArnEquals": {
51 | "iam:PolicyArn": [
52 | "arn:aws:iam::aws:policy/service-role/AWSConfigRole"
53 | ]
54 | }
55 | }
56 | },
57 | {
58 | "Sid": "MoreLimitedAttachmentPermissions",
59 | "Effect": "Allow",
60 | "Action": [
61 | "iam:AttachRolePolicy"
62 | ],
63 | "Resource": "*",
64 | "Condition": {
65 | "ArnLike": {
66 | "iam:PolicyArn": [
67 | "arn:aws:iam::*:policy/service-role/*AWSConfigDeliveryPermissions*"
68 | ]
69 | }
70 | }
71 | },
72 | {
73 | "Effect": "Deny",
74 | "Action": [
75 | "ec2:RunInstances"
76 | ],
77 | "Resource": "arn:aws:ec2:*:*:instance/*"
78 | }
79 | ]
80 | }
81 |
--------------------------------------------------------------------------------
/SID402Workshop/README.md:
--------------------------------------------------------------------------------
1 | # ___An AWS Security Odyssey___
2 |
3 | ## re:Invent 2017 - SID402 - Workshop
4 | ### Implementing Security Controls in the World of Internet, Big Data, IoT and E-Commerce Platforms
5 |
6 |
7 |
8 | ## ___Welcome to the IthaCorp Cloud Engineering Team!___
9 |
10 |
11 |
12 | IthaCorp Enterprises is a multinational conglomerate with businesses in multiple industries including manufacturing, hospitality, IoT and consumer electronics. IthaCorp provides an array of back office and public facing services to internal and external customers. To support these services, a significant AWS footprint has been established consisting of multiple workloads leveraging resources including Amazon VPC, Amazon EC2 and Amazon S3. As this footprint has grown organically, the IthaCorp Cloud Engineering Team has identified the need to enhance security controls across their AWS environments.
13 |
14 | You have have joined the Cloud Engineering Team to lead the AWS security enhancement project. You decide to use the [Cloud Adoption Framework (CAF) - Security Perspective](https://d0.awsstatic.com/whitepapers/AWS_CAF_Security_Perspective.pdf) as a framework for the project. This entails implementing security controls across the following areas:
15 |
16 | - **Directive controls** establish the governance, risk, and compliance models the environment will operate within.
17 | - **Preventive controls** protect your workloads and mitigate threats and vulnerabilities.
18 | - **Detective controls** provide full visibility and transparency over the operation of your deployments in AWS.
19 | - **Responsive controls** drive remediation of potential deviations from your security baselines.
20 |
21 | To help deliver the project, you will use [Amazon EC2](https://aws.amazon.com/ec2/), [Amazon VPC](https://aws.amazon.com/vpc/), [Amazon S3](https://aws.amazon.com/s3/), [AWS CloudTrail](https://aws.amazon.com/cloudtrail/), [AWS CloudWatch](https://aws.amazon.com/cloudwatch/), [Amazon Lambda](https://aws.amazon.com/lambda/), [AWS IoT](https://aws.amazon.com/iot/).
22 |
23 |
24 |
25 | # [Let the Odyssey begin!](1_MonitoringSecEvents)
26 |
27 |
28 |
29 | ## Prerequisites
30 |
31 | ### AWS Account
32 |
33 | In order to complete this workshop you'll need an AWS Account with admin access to services including Amazon EC2, Amazon VPC, AWS Identity and Access Management (IAM), Amazon Simple Storage Service (S3), AWS Lambda, and AWS IoT.
34 |
35 | The code and instructions in this workshop assume only one student is using a given AWS account at a time. If you try sharing an account with another student, you'll run into naming conflicts for certain resources. You can work around this by either using a suffix in your resource names or using distinct Regions, but the instructions do not provide details on the changes required to make this work.
36 |
37 | ### Region
38 |
39 | Choose an AWS Region to execute the workshops which support the complete set of services covered in the material including Amazon EC2, Amazon VPC, Amazon S3, AWS Lambda, Amazon VPC, AWS IoT, AWS CloudWatch and AWS CloudTrail. Use the [Region Table](https://aws.amazon.com/about-aws/global-infrastructure/regional-product-services/) to determine which services are available in a Region.
40 |
41 | ## Modules
42 |
43 | 1. [Monitoring Security Events in AWS](1_MonitoringSecEvents)
44 | 2. [Implementing Security with AWS IoT](2_ImplementSecWithIoT)
45 | 3. [Automating Security Remediation in AWS](3_AutoSecRemediation)
46 |
--------------------------------------------------------------------------------