本文任務:
利用cloud trail和cloud watch檢測 cloudformation中配置的component的異常,然後cloudformation中配置發郵件通知給指定郵箱。
1. s3頁面新建一個bucket
2. 新建cloudtrail
cloudtrail頁面,新建cloudtrail,過程中配置如下:
然後選擇步驟1中新建號的bucket:
在trails頁面,看到新建號的trails。對着新建好的trail雙擊進入,往下翻,可以看到cloudwatch的配置部分:
在configure中,
點擊continue,跳轉到下面界面,然後點擊下面的allow:
3. 創建VPC
VPC頁面,create 一個新的default VPC
4. 部署CloudFormation Template
(1)新建cloudformation
cloudformation頁面,新建stack,使用以下yaml代碼,新建template。然後再用建好的template新建stack。操作過程有問題可參考https://blog.csdn.net/daiqinge/article/details/103320419
---
AWSTemplateFormatVersion: 2010-09-09
Description: |
Creates the resources necessary to create a rule to monitor and
auto-mitigate security group change events
Metadata:
License:
Description: |
Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance with the License. A copy of the License is located at
http://aws.amazon.com/apache2.0/
or in the "license" file accompanying this file. This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
AWS::CloudFormation::Interface:
ParameterGroups:
- Label:
default: Settings
Parameters:
- NotificationEmailAddress
ParameterLabels:
NotificationEmailAddress:
default: Send notifications to
Parameters:
NotificationEmailAddress:
Description: |
This is the email address that will receive change notifications. You will
receive a confirmation email that you must accept before you will receive
notifications.
Type: String
Conditions:
AddEmailNotificationSubscription:
!Not [!Equals [!Ref NotificationEmailAddress, ""]]
Resources:
WebServerSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Allow HTTPS access to web servers
SecurityGroupIngress:
- IpProtocol: tcp
FromPort: 443
ToPort: 443
CidrIp: 0.0.0.0/0
Tags:
- Key: Name
Value: Web Server Security Group
SecurityGroupChangeAutoResponseRole:
Type: AWS::IAM::Role
Properties:
AssumeRolePolicyDocument:
Version: 2012-10-17
Statement:
-
Effect: Allow
Principal:
Service: lambda.amazonaws.com
Action:
- sts:AssumeRole
ManagedPolicyArns:
- arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
Policies:
-
PolicyName: SecurityGroupModification
PolicyDocument:
Version: 2012-10-17
Statement:
-
Sid: AllowSecurityGroupActions
Effect: Allow
Action:
- ec2:RevokeSecurityGroupIngress
Resource: !Sub arn:aws:ec2:${AWS::Region}:${AWS::AccountId}:security-group/${WebServerSecurityGroup.GroupId}
-
Sid: AllowSnsActions
Effect: Allow
Action:
- sns:Publish
Resource: !Ref SnsTopicForCloudWatchEvent
SecurityGroupChangeAutoResponse:
Type: AWS::Lambda::Function
Properties:
Description: Responds to security group changes
Handler: index.lambda_handler
MemorySize: 1024
Role: !GetAtt SecurityGroupChangeAutoResponseRole.Arn
Runtime: python2.7
Timeout: 60
Environment:
Variables:
security_group_id: !GetAtt WebServerSecurityGroup.GroupId
sns_topic_arn: !Ref SnsTopicForCloudWatchEvent
Code:
ZipFile: |
import os, json, boto3
#===============================================================================
def lambda_handler(event, context):
print(event)
# Ensure that we have an event name to evaluate.
if 'detail' not in event or ('detail' in event and 'eventName' not in event['detail']):
return {"Result": "Failure", "Message": "Lambda not triggered by an event"}
# Remove the rule only if the event was to authorize the ingress rule for the given
# security group that was injected during CloudFormation execution.
if (event['detail']['eventName'] == 'AuthorizeSecurityGroupIngress' and
event['detail']['requestParameters']['groupId'] == os.environ['security_group_id']):
result = revoke_security_group_ingress(event['detail'])
message = "AUTO-MITIGATED: Ingress rule removed from security group: {} that was added by {}: {}".format(
result['group_id'],
result['user_name'],
json.dumps(result['ip_permissions'])
)
boto3.client('sns').publish(
TargetArn = os.environ['sns_topic_arn'],
Message = message,
Subject = "Auto-mitigation successful"
)
#===============================================================================
def revoke_security_group_ingress(event_detail):
request_parameters = event_detail['requestParameters']
# Build the normalized IP permission JSON struture.
ip_permissions = normalize_paramter_names(request_parameters['ipPermissions']['items'])
response = boto3.client('ec2').revoke_security_group_ingress(
GroupId = request_parameters['groupId'],
IpPermissions = ip_permissions
)
# Build the result
result = {}
result['group_id'] = request_parameters['groupId']
result['user_name'] = event_detail['userIdentity']['arn']
result['ip_permissions'] = ip_permissions
return result
#===============================================================================
def normalize_paramter_names(ip_items):
# Start building the permissions items list.
new_ip_items = []
# First, build the basic parameter list.
for ip_item in ip_items:
new_ip_item = {
"IpProtocol": ip_item['ipProtocol'],
"FromPort": ip_item['fromPort'],
"ToPort": ip_item['toPort']
}
#CidrIp or CidrIpv6 (IPv4 or IPv6)?
if 'ipv6Ranges' in ip_item and ip_item['ipv6Ranges']:
# This is an IPv6 permission range, so change the key names.
ipv_range_list_name = 'ipv6Ranges'
ipv_address_value = 'cidrIpv6'
ipv_range_list_name_capitalized = 'Ipv6Ranges'
ipv_address_value_capitalized = 'CidrIpv6'
else:
ipv_range_list_name = 'ipRanges'
ipv_address_value = 'cidrIp'
ipv_range_list_name_capitalized = 'IpRanges'
ipv_address_value_capitalized = 'CidrIp'
ip_ranges = []
# Next, build the IP permission list.
for item in ip_item[ipv_range_list_name]['items']:
ip_ranges.append(
{ipv_address_value_capitalized : item[ipv_address_value]}
)
new_ip_item[ipv_range_list_name_capitalized] = ip_ranges
new_ip_items.append(new_ip_item)
return new_ip_items
SecurityGroupChangeAutoResponseLambdaPermission:
Type: AWS::Lambda::Permission
Properties:
Action: lambda:InvokeFunction
Principal: events.amazonaws.com
FunctionName: !Ref SecurityGroupChangeAutoResponse
TriggeredRuleForSecurityGroupChangeAutoResponse:
Type: AWS::Events::Rule
Properties:
#Name: SecurityGroupChangeAutoResponse
Description: Responds to security group change events
EventPattern:
detail:
eventSource:
- ec2.amazonaws.com
eventName:
- AuthorizeSecurityGroupIngress
- AuthorizeSecurityGroupEgress
- RevokeSecurityGroupEgress
- RevokeSecurityGroupIngress
- CreateSecurityGroup
- DeleteSecurityGroup
State: ENABLED
Targets:
-
Arn: !GetAtt SecurityGroupChangeAutoResponse.Arn
Id: TargetFunctionV1
SnsTopicForCloudWatchEvent:
Type: AWS::SNS::Topic
Properties:
DisplayName: Broadcasts message to subscribers
SnsTopicSubscriptionForCloudWatchEvent:
Type: AWS::SNS::Subscription
Condition: AddEmailNotificationSubscription
Properties:
TopicArn: !Ref SnsTopicForCloudWatchEvent
Endpoint: !Ref NotificationEmailAddress
Protocol: email