View a markdown version of this page

使用以下方法为公共子网部署基于侦探属性的访问控制 AWS Config - AWS 规范指引

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

使用以下方法为公共子网部署基于侦探属性的访问控制 AWS Config

Alberto Menendez,Amazon Web Services

Summary

分布式边缘网络架构依赖于与其虚拟私有云中的工作负载一起运行的网络边缘安全(VPCs)。与更常见的集中式方法相比,此方法的可扩展性无可比拟。尽管在工作负载账户中部署公有子网可以带来好处,但它也会带来新的安全风险,因为它增加了攻击面。我们建议您仅在这些资源的公有子网中部署 Elastic Load Balancing 资源,例如应用程序负载均衡器或 NAT 网关。 VPCs在专用公有子网中使用负载均衡器和 NAT 网关有助于实现对入站和出站流量的精细控制。

我们建议您同时实施预防性控件和检测性控件,以限制可在公有子网中部署的资源类型。有关使用基于属性的访问权限控制(ABAC)为公有子网部署预防性控件的更多信息,请参阅为公有子网部署预防性的基于属性的访问权限控制。尽管这些预防性控件对大多数情况都有效,但可能无法处理所有可能的使用案例。因此,此模式以 ABAC 方法为基础,可帮助您配置提醒,就部署在公有子网中的不合规资源发出提醒。该解决方案检查弹性网络接口是否属于公有子网中不允许使用的资源。

为此,此模式使用 AWS Config 自定义规则ABAC。无论何时创建或修改弹性网络接口的配置,自定义规则都会对其进行处理。简而言之,此规则会执行两个操作,以来确定网络接口是否合规:

  1. 为了确定网络接口是否在规则范围内,此规则会检查子网是否具有可表明其为公有子网的特定 AWS 标签。例如,此标签可能是 IsPublicFacing=True

  2. 如果网络接口部署在公有子网中,则该规则将检查 AWS 服务 创建此资源的原因。如果此资源不是弹性负载均衡资源或 NAT 网关,则它会将此资源标记为不合规。

先决条件和限制

先决条件

  • 活跃的 AWS 账户

  • AWS Config,在工作负载账户中设置

  • 在工作负载账户中部署所需资源的权限

  • 具有公有子网的 VPC

  • 正确应用标签以识别目标公有子网

  • (可选)中的组织 AWS Organizations

  • (可选)中央安全账户,它是 AWS Config 和的委派管理员 AWS Security Hub CSPM

架构

目标架构

使用 AWS Config 自定义规则,检测公有子网中的不合规资源

下图说明了以下内容:

  1. 部署或修改 elastic network interface 资源 (AWS::EC2::NetworkInterface) 时,会 AWS Config 捕获事件和配置。

  2. AWS Config 将此事件与用于评估配置的自定义规则进行匹配。

  3. 调用与此自定义规则关联的 AWS Lambda 函数。该函数评估资源并应用指定的逻辑,进而确定资源配置是 COMPLIANTNON_COMPLIANT 还是 NOT_APPLICABLE

  4. 如果确定资源为,则通过亚马逊简单通知服务 (Amazon SNS) Simple Notification Service AWS Config 发送提醒。NON_COMPLIANT

    注意:如果此账户是中的成员账户 AWS Organizations,则可以通过 AWS Config 或将合规性数据发送到中央安全账户 AWS Security Hub CSPM。

Lambda 函数评估逻辑

下图显示了 Lambda 函数用于评估弹性网络接口的合规性的逻辑。

Lambda 函数逻辑示意图

自动化和扩展

此模式是一种检测性解决方案。您还可以使用修复规则对其进行补充,以自动解决任何不合规的资源。有关更多信息,请参阅使用规则修复不合规的 AWS Config 资源

您可以通过以下方式扩展此解决方案:

  • 强制应用您为识别面向公众的子网而建立的相应 AWS 标签。有关更多信息,请参阅 AWS Organizations 文档中的标签策略

  • 配置一个中央安全帐户,将 AWS Config 自定义规则应用于组织中的每个工作负载帐户。有关更多信息,请参阅 AWS(AWS 博客文章)中的大规模自动配置合规性

  • AWS Config 与集成 AWS Security Hub CSPM ,以便大规模捕获、集中和通知。有关更多信息,请参阅 AWS Security Hub CSPM 文档 AWS Config中的配置

工具

  • AWS Config提供了您的资源 AWS 账户 及其配置方式的详细视图。它可以帮助您确定资源之间的相互关系,以及它们的配置如何随时间变化。

  • 弹性负载均衡在多个目标上分配传入的应用程序或网络流量。例如,您可以跨亚马逊弹性计算云 (Amazon EC2) 实例、容器以及一个或多个可用区中的 IP 地址分配流量。

  • AWS Lambda 是一项计算服务,可帮助您运行代码,无需预调配或管理服务器。它只在需要时运行您的代码,并自动进行扩展,因此您只需为使用的计算时间付费。

  • Amazon Simple Notification Service (Amazon SNS) 可帮助您协调和管理发布者与客户端(包括 Web 服务器和电子邮件地址)之间的消息交换。 

  • Amazon Virtual Private Cloud(亚马逊 VPC)可帮助您将 AWS 资源启动到您定义的虚拟网络中。该虚拟网络类似于您在数据中心中运行的传统网络,并具有使用 AWS的可扩展基础设施的优势。

最佳实践

有关开发自定义 AWS Config 规则的更多示例和最佳实践,请参阅上的官方AWS Config 规则存储库 GitHub。

操作说明

Task说明所需技能

创建 Lambda 函数。

  1. 登录 AWS 管理控制台,然后打开AWS Lambda 控制台

  2. Functions (LAM 函数) 页面上,选择 Create function (创建函数)

  3. 选择从头开始编写

  4. 基本信息窗格中,对于函数名称,输入一个名称。

  5. 对于运行时系统,选择 Python 3.12

  6. 架构设置为 x86_64

  7. 选择创建函数

  8. 选择节点选项卡。

  9. 在文件资源管理器中,选择 lambda_function.py

  10. 将此模式的其他信息部分中提供的示例代码粘贴到 lambda_function.py 选项卡中。自定义示例代码以识别 evaluate_change_notification_compliance 函数中的任何那个自定义评估逻辑。

  11. 选择部署

常规 AWS

为 Lambda 函数的执行角色添加这些权限。

  1. 在导航窗格中,选择函数

  2. 选择您刚刚创建的函数。

  3. 选择 Configuration(配置),然后选择 Permissions(权限)。

  4. 选择角色名称以在 AWS Identity and Access Management (IAM) 控制台中打开该角色。

  5. 权限策略选项卡中,选择添加权限,然后选择创建内联策略

  6. 选择 JSON

  7. 将以下策略粘贴到策略编辑器中。这允许 Lambda 函数:

    • 获取子网标签的详细信息。

    • 将合规结果发回给 AWS Config。

    { "Version": "2012-10-17", "Statement": [ { "Action": [ "config:PutEvaluations", "ec2:DescribeSubnets" ], "Resource": "*", "Effect": "Allow" } ] }
  8. 选择下一步

  9. 为策略输入名称,然后选择 Create policy (创建策略)

常规 AWS

检索 Lambda 函数 Amazon 资源名称(ARN)。

  1. 打开 Lambda 控制台

  2. 在导航窗格中,选择函数

  3. 选择您刚刚创建的函数。

  4. 函数概述部分的函数 ARN 下,复制该值。

常规 AWS

创建 AWS Config 自定义规则。

  1. 打开 AWS Config 控制台

  2. Rules 页面,选择 Add rule

  3. 指定规则类型页面上,选择创建自定义规则,然后选择下一步

  4. 配置规则页面上,执行以下操作:

    1. 输入名称和描述。

    2. 对于 AWS Lambda 函数 ARN,粘贴您之前复制的 ARN。

    3. 对于触发器类型,选择在配置发生更改时

    4. 对于更改范围,选择资源

    5. 对于资源类型,请选择 AWS EC2 NetworkInterface

    6. 选择下一步

  5. 审查并创建页面上,验证您的规则,然后选择保存

常规 AWS

配置通知。

  1. 按照创建 Amazon SNS 主题中的说明进行操作,以创建 Amazon SNS 主题。

  2. 按照订阅 Amazon SNS 主题中的说明进行操作,以配置接收 Amazon SNS 主题通知的端点。

  3. 按照资源不合规时如何收到通知中的说明使用 AWS Config为您的不合规 AWS 资源配置自定义 Amazon EventBridge 规则。

常规 AWS
Task说明所需技能

创建合规资源。

  1. 按照以下说明,在公有子网中创建一种支持的资源:

  2. 创建资源后, AWS Config 自定义规则将评估与资源关联的弹性网络接口。它会将这些网络接口标记为 COMPLIANT。您可以按照以下步骤查看中的 AWS Config 资源:

    1. 打开 AWS Config 控制台

    2. 规则页面上,选择您的规则。

    3. 规则详细信息页面上,转到页面底部。

    4. 范围中的资源下,选择合规。确认您看到已创建 IDs 的网络接口。

    5. 有关网络接口配置的更多详细信息,请选择资源 ID。

常规 AWS

创建不合规资源。

  1. 按照以下说明,在公有子网中创建一种不合规资源:

  2. 创建资源后, AWS Config 自定义规则将评估与资源关联的弹性网络接口。它会将这些网络接口标记为 NON_COMPLIANT。您可以按照以下步骤查看中的 AWS Config 资源:

    1. 打开 AWS Config 控制台

    2. 规则页面上,选择您的规则。

    3. 规则详细信息页面上,转到页面底部。

    4. 在 “范围内的资源” 下,选择NonCompliant。确认您看到已创建 IDs 的网络接口。

    5. 有关网络接口配置的更多详细信息,请选择资源 ID。

  3. 确认您在 Amazon SNS 中配置的端点已收到通知。

常规 AWS

创建不适用的资源。

  1. 在私有子网中,创建任何需要弹性网络接口的资源。

  2. 创建资源后, AWS Config 自定义规则将评估与资源关联的弹性网络接口。它会将这些网络接口标记为 NOT_APPLICABLE。这些资源未显示在 AWS Config 控制台中。

常规 AWS

相关资源

AWS 文档

其他 AWS 资源

附加信息

以下是一个 Lambda 函数示例,仅用于演示目的。

import boto3 import json import os # Init clients config_client = boto3.client('config') ec2_client = boto3.client('ec2') def lambda_handler(event, context): # Init values compliance_value = 'NOT_APPLICABLE' invoking_event = json.loads(event['invokingEvent']) configuration_item = invoking_event['configurationItem'] status = configuration_item['configurationItemStatus'] eventLeftScope = event['eventLeftScope'] # First check if the event configuration applies. Ex. resource event is not delete if (status == 'OK' or status == 'ResourceDiscovered') and not eventLeftScope: compliance_value = evaluate_change_notification_compliance(configuration_item) config_client.put_evaluations( Evaluations=[ { 'ComplianceResourceType': invoking_event['configurationItem']['resourceType'], 'ComplianceResourceId': invoking_event['configurationItem']['resourceId'], 'ComplianceType': compliance_value, 'OrderingTimestamp': invoking_event['configurationItem']['configurationItemCaptureTime'] }, ], ResultToken=event['resultToken']) # Function with the logs to evaluate the resource def evaluate_change_notification_compliance(configuration_item): is_in_scope = is_in_scope_subnet(configuration_item['configuration']['subnetId']) if (configuration_item['resourceType'] != 'AWS::EC2::NetworkInterface') or not is_in_scope: return 'NOT_APPLICABLE' else: alb_condition = configuration_item['configuration']['requesterId'] in ['amazon-elb'] nlb_condition = configuration_item['configuration']['interfaceType'] in ['network_load_balancer'] nat_gateway_condition = configuration_item['configuration']['interfaceType'] in ['nat_gateway'] if alb_condition or nlb_condition or nat_gateway_condition: return 'COMPLIANT' return 'NON_COMPLIANT' # Function to check if elastic network interface is in public subnet def is_in_scope_subnet(eni_subnet): subnet_description = ec2_client.describe_subnets( SubnetIds=[eni_subnet] ) for subnet in subnet_description['Subnets']: for tag in subnet['Tags']: if tag['Key'] == os.environ.get('TAG_KEY') and tag['Value'] == os.environ.get('TAG_VALUE'): return True return False