AWS Lambda(七)---用CloudTrail

本文任务:

利用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

发布了140 篇原创文章 · 获赞 80 · 访问量 36万+

猜你喜欢

转载自blog.csdn.net/daiqinge/article/details/103323577
AWS