aws ac

实验 7.1:使用 AWS Config 和 Lambda 修复事件
实验概览与目标
在本实验中,您将了解如何使用 AWS Config 服务来监控 AWS 账户中特定资源的更改。您将了解如何使用该服务来识别可能是安全问题的更改,例如用户修改 Amazon Elastic Compute Cloud (Amazon EC2) 安全组。此外,您还将通过将 AWS Config 与 AWS Lambda 集成,获得自动修复相关特定安全事件的实践经验。

在完成本实验后,您应该能够:

说明如何使用 AWS Identity and Access Management (IAM) 角色授予 AWS 服务访问其他 AWS 服务的权限。

启用 AWS Config 来监控 AWS 账户中的资源。

创建并启用使用预先创建的 Lambda 函数的自定义 AWS Config 规则。

测试 AWS Config 规则的行为,确保规则按预期工作。

分析 Amazon CloudWatch 日志,审计何时调用了 AWS Config 规则。

时长
完成本实验大约需要 75 分钟。

AWS 服务限制
在本实验环境中,对 AWS 服务和服务操作的访问权限可能仅限于完成实验说明所需的服务和操作。如果您尝试访问其他服务,或执行本实验所述之外的操作,则可能会遇到错误。

场景
在本实验中,您负责监控 AWS 账户中的 Amazon EC2 安全组设置。您将定义在安全组中应该打开和不应该打开哪些入站端口。您将配置一个解决方案,当有人修改安全组的入站规则,使之不再符合期望配置时,自动修复这个事件。

当您启动实验时,您的 AWS 账户将包含两个 IAM 角色和一个 Lambda 函数。账户还将包含一个默认 VPC(有一个默认安全组)和一个名为 Lab VPC 的自定义 VPC(有一个名为 LabSG1 的安全组)。

下图显示了实验开始时在 AWS 中为您创建的架构。

最初的架构

在实验中,您将配置 AWS Config 服务,以便在 AWS 账户的一个区域内创建特定资源的清单。然后,您将创建 AWS Config 规则。

在本实验结束时,您会创建如下图所示的架构。

结束时的架构

构建解决方案后,安全事件会通过下表中所述的步骤进行修复。

步骤    说明
1    AWS Config 规则将监控 AWS Config 资源清单中跟踪的安全组的任何更改。
2    当规则检测到安全组发生更改时,规则会调用 Lambda 函数。
3    函数会更新安全组的期望入站规则配置,从而纠正这种情况。
 

访问 AWS 管理控制台
在本说明的顶部,选择  Start Lab(开始实验)。

实验会话开始。

页面顶部会显示一个计时器,指示会话的剩余时间。

 提示:只要计时器未达到 0:00,您就可以随时再次选择  Start Lab(开始实验)来刷新会话时长。

在继续之前,请等到左上角的 AWS  链接右侧的圆形图标变为绿色。当实验环境准备好之后,还会显示 AWS Details(AWS 详细信息)面板。

要连接到 AWS 管理控制台,请选择终端窗口上方左上角的 AWS 链接。

此时会打开一个新的浏览器标签页,并连接到控制台。

 提示:如果未打开新的浏览器标签页,如果未打开新的浏览器标签页,浏览器顶部通常会显示一个横幅或图标,并附带一条消息,提示浏览器阻止该网站打开弹出窗口。选择该横幅或图标,然后选择 Allow pop-ups(允许弹出窗口)。

任务 1:检查和更新 IAM 角色
在此任务中,您将分析在实验环境中为您预先预置的两个 IAM 角色。您还将更新其中一个角色的权限。AWS Config 和 Lambda 稍后将在实验中使用这些角色。

在 IAM 控制台中,检查 AwsConfigLambdaSGRole 角色获授的权限。

在  Services(服务)右侧的搜索框中,搜索并选择 IAM。

在导航窗格中,选择 Roles(角色)。

选择 AwsConfigLambdaSGRole 链接。

在 Permissions(权限)选项卡上,展开  awsconfig_lambda_ec2_sg_role_policy。

此时会显示以下 IAM 策略文档。策略采用 JavaScript 对象表示法 (JSON) 格式。

{
 "Version":"2012-10-17",
 "Statement":[
  {
     "Action":[
       "logs:CreateLogGroup",
       "logs:CreateLogStream",
       "logs:PutLogEvents"
     ],
     "Resource":"arn:aws:logs:*:*:*",
     "Effect":"Allow"
  },
  {
    "Action":[
       "config:PutEvaluations",
       "ec2:DescribeSecurityGroups",
       "ec2:AuthorizeSecurityGroupIngress",
       "ec2:RevokeSecurityGroupIngress"
    ],
    "Resource":"*",
    "Effect":"Allow"
  }
 ]
}
  分析:这是为您创建的自定义角色。在本实验的后面部分,您会将此角色附加到创建的 Lambda 函数。此角色定义了 Lambda 函数在运行时拥有的权限。该策略将允许 Lambda 函数在 Amazon EC2 安全组中添加或删除入站规则。该策略还将允许 Lambda 函数创建事件并将其写入 CloudWatch 日志。

  账户中还为您创建了第二个自定义 IAM 角色。您将在下面几步查看该角色并进行修改。

更新 AwsConfigRole IAM 角色获授的权限。

在导航窗格中,选择 Roles(角色)。

选择 AwsConfigRole 链接。

在 Permissions(权限)选项卡上,展开  S3Access 策略,该策略已附加到此角色。

目前,此角色授予的权限包括:获取 Amazon Simple Storage Service (Amazon S3) 存储桶的存储桶访问控制列表 (ACL),以及将对象上传到 S3 存储桶的权限,前提是满足某些特定条件。这些权限将允许 AWS Config 将 CloudWatch 日志文件写入 Amazon S3。

在选项卡顶部附近,选择 Add permissions(添加权限)> Attach policies(附加策略)。

要搜索与 AWS Config 相关的策略,请在  Search(搜索)框中搜索 Config 并按 Enter 键。

选择 AWS_ConfigRole 策略。

选择位于右下角的 Add permissions(添加权限)。

-(可选)展开 AWS_ConfigRole,查看策略详细信息。

  该策略授予的是针对许多 AWS 服务的读取级别访问权限(主要是 Get、List 和 Describe 操作)。

  分析:在下一个任务中配置 AWS Config 时,您将授权 AWS Config 使用此角色。该角色定义了 AWS Config 在监控 AWS 账户其中一个区域时所具有的权限。

  

在此任务中,您分析了两个 IAM 角色获授的权限,第一个角色将用于本实验后续任务中的 Lambda 函数,而第二个角色将在下一个任务中用于 AWS Config;您还更新了第二个角色获授的权限。

任务 2:设置 AWS Config 来监控资源
在此任务中,您将配置 AWS Config 来监控 AWS 账户某个区域中的特定资源。

设置 AWS Config。

在  Services(服务)右侧的搜索框中,搜索并选择 Config。

选择 Get started(开始使用),然后配置以下设置:

在 Recording strategy(记录策略)下,选择 Specific resource types(特定资源类型)。

Resource type(资源类型):选择 AWS EC2 SecurityGroup(AWS EC2 安全组)。对于 Frequency(频率),选择 Continuous(持续)。

对于 IAM role for AWS Config(AWS Config 的 IAM 角色),选择 Choose a role from your account(从您的账户选择一个角色)。

Existing roles(现有角色):选择 AwsConfigRole。

 注意:回想一下,AwsConfigRole 是您在上一个任务中分析的第二个角色。

在 Delivery method(交付方式)部分,可以看到在默认情况下,AWS Config 会将结果存储在 S3 存储桶中。保留默认设置,然后选择 Next(下一步)。

在 AWS Managed Rules(AWS 托管规则)页面上,选择页面底部的 Next(下一步)。

查看 AWS Config 设置详细信息,然后选择 Confirm(确认)。

此时会短暂显示一个横幅,然后显示 AWS Config 控制面板。

要查看 AWS Config 创建的资源清单,请在导航窗格中选择 Resources(资源)。

此时会显示 Resource Inventory(资源清单)页面,并列出您账户中的 Amazon EC2 资源。

 注意:如果资源列表中显示一条消息,指出正在发现您的资源,请耐心等待几分钟。AWS Config 可能需要几分钟才能识别您的所有资源。

分析:回想一下,您已将 AWS Config 配置为列出 EC2 安全组类型资源的清单。在设置 AWS Config 的区域中,预先预置的 Amazon EC2 安全组将会包括在清单中。不过,可以看到清单中还会显示许多其他资源类型。AWS Config 会跟踪与您主要关注的资源相关的资源,因为相关资源会影响主要资源的行为。您正在使用的实验环境包括许多这种相关资源(例如,互联网网关和网络 ACL)。

在此任务中,您在 AWS 账户的一个区域中设置了 AWS Config 服务,以便监控感兴趣的特定资源,然后查看了 AWS Config 如何创建资源清单。

任务 3:修改 AWS Config 监控的安全组
在此任务中,您将针对 AWS Config 资源清单中列出的一个安全组,配置新的入站规则设置。这样做是为了有效地模拟安全事件。您在此任务中定义的一些入站规则设置,与您在后面的任务中定义的期望设置不匹配。

找到 Lab VPC 中的安全组。

在  Services(服务)右侧的搜索框中,搜索并选择 VPC。

在导航窗格中,选中 Filter by VPC(按 VPC 筛选)框,然后选择 Lab VPC。

在导航窗格中,选择 Security Groups(安全组)。

此 VPC 中定义了至少两个安全组。

选择 LabSG1 安全组。

向安全组添加入站规则,以便允许 HTTP、HTTPS、SMTPS 和 IMAPS 网络流量。

选择 Inbound rules(入站规则)选项卡,然后选择 Edit inbound rules(编辑入站规则)。

可以看到,已经定义了一个 HTTP 入站规则。

对于现有规则,将 Source(源)更改为 Anywhere-IPv4。

选择 Add Rule(添加规则),然后配置以下各项:

Type(类型):选择 HTTPS。

Source(源):选择 Anywhere-IPv4。

再次选择 Add Rule(添加规则),然后配置以下各项:

Type(类型):选择 SMTPS。

Source(源):选择 Anywhere-IPv4。

再次选择 Add Rule(添加规则),然后配置以下各项:

Type(类型):选择 IMAPS。

Source(源):选择 Anywhere-IPv4。

选择 Save rules(保存规则)。

入站规则现在应类似于以下屏幕截图中的规则(但您的安全组规则 ID 不同)。

之前配置的入站规则

在此任务中,您找到了 Lab VPC 中的一个安全组,并在该安全组中定义了三个新的入站规则。在本实验的后面部分,您将看到这些修改会被识别为安全事件并加以修复。

任务 4:创建调用 Lambda 函数的 AWS Config 规则
在本任务中,您将配置 AWS Config 规则,以便调用预先创建的 Lambda 函数。规则和函数互相配合,确保受监控的 Amazon EC2 安全组仅包含期望的入站规则。

前往 i AWS Details(AWS 详细信息)部分,将 LambdaFunctionARN 的值复制到剪贴板中。

注意:您将在后面的步骤中使用该 ARN。

创建新的 AWS Config 规则,每当受监控的 Amazon EC2 安全组发生更改时调用 Lambda 函数。

导航到 AWS Config 控制台。

在导航窗格中,选择 Rules(规则)。

目前,AWS Config 还没有定义任何规则。

选择 Add rule(添加规则)。

对于 Select rule type(选择规则类型),选择 Create custom Lambda rule(创建自定义 Lambda 规则)。

选择 Next(下一步)。

在 Configure rule(配置规则)页面上,配置以下各项:

AWS Lambda function ARN(AWS Lambda 函数 ARN):粘贴您复制的 Lambda 函数 ARN。

Name(名称):输入 EC2SecurityGroup

Description(描述):输入 Restrict inbound ports to HTTP and HTTPS

Trigger type(触发器类型):选择 When configuration changes(当配置更改时)。

Scope of changes(更改范围):选择 Resources(资源)。

Resource type(资源类型):选择 AWS EC2 SecurityGroup(AWS EC2 安全组)。

在资源区域中会显示 AWS EC2 SecurityGroup(AWS EC2 安全组)。

在 Parameters(参数)部分,添加具有以下设置的参数:

Key(键):debug

Value(值):true

 注意:您在这里定义的任何参数都将通过此 AWS Config 规则传递给 EC2SecurityGroup Lambda 函数。

选择 Next(下一步),然后选择 Save(保存)。

查看 AWS Config EC2SecurityGroup 规则详细信息。

选择 EC2SecurityGroup 链接。

在 Resources in scope(范围中的资源)部分,选择 Noncompliant(不合规)下拉菜单,然后选择 All(全部)。

在 Rule details(规则详细信息)部分,注意 Last successful evaluation(上次成功评估)字段。最初,此字段显示 Not available(不可用);但在几分钟后,系统会显示一个时间戳。

 注意:初次评估可能需要几分钟时间才能完成。将来修改范围内的任何安全组时,也会进行同样的评估。

请注意在范围内列出的 Amazon EC2 安全组资源。

进行初次评估时,Compliance(合规性)值将为 No results available(无可用结果)。几分钟后,每个安全组资源的值更改为 Compliant(合规)。请稍等片刻,直到您看到值变为合规。

可以看到,Annotation(注释)列显示 Permissions were modified(已修改权限)。

在本任务中,您配置了一条 AWS Config 规则来调用预先创建的 Lambda 函数。规则和函数互相配合,可以监控和修复对受监控的 Amazon EC2 安全组的入站规则进行的任何不需要的更新。

任务 5:重新访问安全组配置
请注意,我们已经进行了初始 AWS Config 合规性评估,您将重新检查 LabSG1 安全组。您将观察系统是否注意到并修复安全事件更改(您对入站规则所作的修改)。

分析 LabSG1 安全组上定义的入站规则。

导航到 VPC 控制台。

在导航窗格中,选中 Filter by VPC(按 VPC 筛选)框,然后选择 Lab VPC。

在导航窗格中,选择 Security Groups(安全组)。

选择 LabSG1 安全组。

可以看到,在 Inbound rules(入站规则)选项卡中,只允许 HTTP 和 HTTPS 流量。

入站规则现在应类似于以下屏幕截图中的规则(但您的安全组规则 ID 不同)。

当前入站规则

分析:回想一下,您对此安全组定义了 SMTP 和 IMAPS 以及 HTTP 和 HTTPS 的入站规则。但是,SMTPS 和 IMAPS 的规则已经不存在了。此外,再回想一下,您将所有规则的 IP 版本设置为仅 IPv4,但现在 HTTP 和 HTTPS 规则针对 IPv4 和 IPv6 进行定义。

总之,您修改了此安全组中的入站规则,使其类似于以下屏幕截图中的规则。但入站规则经过重大修改,看起来像上面的屏幕截图中的规则。

之前配置的入站规则

分析 Lambda 函数代码。

导航至 Lambda 控制台。

在导航窗格中,选择 Functions(函数)。

选择 awsconfig_lambda_security_group 函数链接。

在 Code source(代码源)部分,打开您导入的 awsconfig_lambda_security_group.py 文件。

观察以下详细信息:

在第 20 行,该函数导入了 boto3,即适用于 Python 的 AWS SDK。

在第 30 行,定义了 REQUIRED_PERMISSIONS。该数组包括了在您定义的 AWS Config 规则范围内的 Amazon EC2 安全组资源所需的进入(入站)IP 权限。

这些必需的权限是按照 describe_security_groups() API 调用所需的格式定义的。此调用在第 117 行调用。

有关此 API 调用的更多信息,请参阅适用于 Python 的 AWS SDK 文档。

在第 180 行,该函数检查 AWS Config 规则中是否包括了 debug 参数。回想一下,这是您在任务 4 中定义 AWS Config 规则时配置的参数。如果 debug 设置为 true,则 Lambda 函数代码将在运行时输出额外的调试信息。您可以在 Lambda 代码中看到这方面的例子。

在此任务中,您查看了 Lambda 函数检测和删除安全组中 SMTPS(TCP 端口 465)和 IMAPS(TCP 端口 993)附加权限的逻辑。

分析:安全事件(当您修改入站规则时)发生在您创建用于修复此类事件的 AWS Config 规则和 Lambda 函数之前。在初次规则验证期间,AWS Config 检测到安全事件。

如果您再次修改安全组,则会启动 AWS Config 合规性评估。评估将调用 Lambda 函数,并撤销您的更改,以便入站规则再次与期望设置匹配。系统对默认安全组采用类似的方式加以监控,并在发生更改时修复相应的设置。

任务 6:使用 CloudWatch Logs 进行验证
在此任务中,您将分析 CloudWatch 日志,筛选日志条目以查找修复的证据。

查找相关的日志条目,找到 AWS Config 规则及其关联 Lambda 函数对安全组所作更改的证据。

在  Services(服务)右侧的搜索框中,搜索并选择 CloudWatch。

在导航窗格中,展开  Logs(日志),然后选择 Log groups(日志组)。

选择 awsconfig_lambda_security_group 日志组链接。

日志流列表中显示一个或多个日志流条目。

选择 Search all(全部搜索)。

在 Filter events(筛选事件)搜索字段中,输入 revoking for,然后按 Enter 键。

展开  每个日志事件并查看内容。

每个事件都提供有关 Lambda 函数所执行操作的详细信息。在其中一个事件中,您应该可找到相关的详细信息,表明已经删除了您手动添加的 SMTPS(TCP 端口 465)和 IMAPS(TCP 端口 993)入站规则。

筛选的其他事件记录了对账户中存在的其他两个安全组的更改。这些安全组也位于您的 AWS Config 规则正在监控的资源清单中。

在此任务中,您在 CloudWatch Logs 中观察到的证据表明,AWS Config 调用了 Lambda 函数,自动撤销了对安全组所作的修改。

提交作业
要记录您的进度,请选择本说明顶部的 Submit(提交)。

在系统提示时,选择 Yes(是)。

几分钟后,成绩面板会显示每个任务所获得的分数。如果在几分钟后仍未显示结果,请选择本说明顶部的 Grades(成绩)。

 提示:您可以多次提交作业。更改作业后,再次选择 Submit(提交)。最后一次提交的作业记为本实验的作业。

要查找有关作业的详细反馈,请选择 Submission Report(提交报告)。

lambda 函数

import boto3
import botocore
import json


APPLICABLE_RESOURCES = ["AWS::EC2::SecurityGroup"]

REQUIRED_PERMISSIONS = [
{
    "IpProtocol" : "tcp",
    "FromPort" : 80,
    "ToPort" : 80,
    "UserIdGroupPairs" : [],
    "IpRanges" : [{"CidrIp" : "0.0.0.0/0"}],
    "PrefixListIds" : [],
    "Ipv6Ranges": [
        {
            "CidrIpv6": "::/0"
        }
    ]
},
{
    "IpProtocol" : "tcp",
    "FromPort" : 443,
    "ToPort" : 443,
    "UserIdGroupPairs" : [],
    "IpRanges" : [{"CidrIp" : "0.0.0.0/0"}],
    "PrefixListIds" : [],
    "Ipv6Ranges": [
        {
            "CidrIpv6": "::/0"
        }
    ]
}]

def normalize_parameters(rule_parameters):
    for key, value in rule_parameters.items():
        normalized_parameters = {}
        normalized_key=key.lower()
        normalized_value=value

        if normalized_value == "true":
            normalized_parameters[normalized_key] = True
        elif normalized_value == "false":
            normalized_parameters[normalized_key] = False
        else:
            normalized_parameters[normalized_key] = True

    return normalized_parameters

def evaluate_compliance(configuration_item, debug_enabled):
    if configuration_item["resourceType"] not in APPLICABLE_RESOURCES:
        return {
            "compliance_type" : "NOT_APPLICABLE",
            "annotation" : "The rule doesn't apply to resources of type " +
            configuration_item["resourceType"] + "."
        }

    if configuration_item["configurationItemStatus"] == "ResourceDeleted":
        return {
            "compliance_type": "NOT_APPLICABLE",
            "annotation": "The configurationItem was deleted and therefore cannot be validated."
        }

    group_id = configuration_item["configuration"]["groupId"]
    client = boto3.client("ec2");

    try:
        response = client.describe_security_groups(GroupIds=[group_id])
    except botocore.exceptions.ClientError as e:
        return {
            "compliance_type" : "NON_COMPLIANT",
            "annotation" : "describe_security_groups failure on group " + group_id
        }

    if debug_enabled:
        print(("security group definition: ", json.dumps(response, indent=2)))

    ip_permissions = response["SecurityGroups"][0]["IpPermissions"]
    authorize_permissions = [item for item in REQUIRED_PERMISSIONS]
    revoke_permissions = [item for item in ip_permissions]

    if authorize_permissions or revoke_permissions:
        annotation_message = "Permissions were modified."
    else:
        annotation_message = "Permissions are correct."

    if revoke_permissions:
        if debug_enabled:
            print(("revoking for ", group_id, ", ip_permissions ", json.dumps(revoke_permissions, indent=2)))

        try:
            client.revoke_security_group_ingress(GroupId=group_id, IpPermissions=revoke_permissions)
            annotation_message += " " + str(len(revoke_permissions)) +" new revocation(s)."
        except botocore.exceptions.ClientError as e:
            return {
                "compliance_type" : "NON_COMPLIANT",
                "annotation" : "revoke_security_group_ingress failure on group " + group_id
            }

    if authorize_permissions:
        if debug_enabled:
            print(("authorizing for ", group_id, ", ip_permissions ", json.dumps(authorize_permissions, indent=2)))

        try:
            client.authorize_security_group_ingress(GroupId=group_id, IpPermissions=authorize_permissions)
            annotation_message += " " + str(len(authorize_permissions)) +" new authorization(s)."
        except botocore.exceptions.ClientError as e:
            print(("Error - "+ str(e)))
            return {
                "compliance_type" : "NON_COMPLIANT",
                "annotation" : "authorize_security_group_ingress failure on group " + group_id
            }

    return {
        "compliance_type": "COMPLIANT",
        "annotation": annotation_message
    }


def lambda_handler(event, context):
    invoking_event = json.loads(event['invokingEvent'])
    configuration_item = invoking_event["configurationItem"]
    rule_parameters = normalize_parameters(json.loads(event["ruleParameters"]))

    debug_enabled = False

    if "debug" in rule_parameters:
        debug_enabled = rule_parameters["debug"]

    if debug_enabled:
        print("Received event: " + json.dumps(event, indent=2))

    evaluation = evaluate_compliance(configuration_item, debug_enabled)

    config = boto3.client('config')

    response = config.put_evaluations(
      Evaluations=[
          {
              'ComplianceResourceType': invoking_event['configurationItem']['resourceType'],
              'ComplianceResourceId': invoking_event['configurationItem']['resourceId'],
              'ComplianceType': evaluation["compliance_type"],
              "Annotation": evaluation["annotation"],
              'OrderingTimestamp': invoking_event['configurationItem']['configurationItemCaptureTime']
          },
      ],
      ResultToken=event['resultToken'])

boto文档
https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/cloudwatch/client/can_paginate.html


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值