自动扫描公共Amazon S3存储桶并阻止公共访问

2 分钟阅读
内容级别:中级
3

本文提供了使用AWS服务(如Security Hub、Lambda、EventBridge和CloudWatch)自动检测并阻止Amazon S3存储桶公共访问的指南。通过事件驱动的架构,帮助组织防止S3存储桶意外公开,提升安全性,并允许在特定情况下保留必要的公共访问。

数据是组织的宝贵资产,用户始终在寻找简单的工具来保护其数据免受未经授权的访问。尽管某些用例确实需要数据在某些情况下可以公开访问,但大多数企业用例和数据隐私都依赖于严格管理的权限,且不允许公共访问。

企业使用Amazon S3对象存储来处理多种用例,例如云应用程序、动态网站、内容分发、移动和游戏应用程序。随着Amazon S3成为组织多功能且集中的数据存储库,除非绝对必要,否则保持数据私密至关重要。默认情况下,新创建的S3存储桶启用了S3阻止公共访问功能,并在存储桶级别禁用了访问控制列表 (ACLs),同时所有新对象默认加密。为了确保您的S3存储桶和对象的公共访问被阻止,您可以在账户级别开启S3阻止公共访问功能。尽管这些功能提供了强大的安全姿态,但由于意外操作、用户拥有过多权限甚至恶意活动,可能导致创建了没有启用S3阻止公共访问的S3存储桶,或现有的S3存储桶意外地禁用了S3阻止公共访问。

在这篇文章中,我们将引导您通过一个主动的事件驱动解决方案,使用AWS Security Hub检测公共S3存储桶,并自动在存储桶级别启用S3阻止公共访问功能。在某些情况下,可能需要对S3存储桶进行公共访问,针对这些场景,我们建议您标记这些S3存储桶(例如,tag_key = “bucket.status” & tag_value = “public.bucket)。该解决方案基于事件驱动架构,具有成本效益且易于部署,它可以通过确保本应保持私密的存储桶始终保持私密,进而提高组织的整体安全姿态和运营可靠性。

解决方案概述

下图展示了该事件驱动架构的不同组件。

Enter image description here

该解决方案的工作流程大致如下:

  1. AWS Security Hub检查S3存储桶的合规性和安全性。
  2. 检测结果发送到Amazon EventBridge
  3. EventBridge调用两个目标:
    a. 包含阻止公共访问S3存储桶逻辑的AWS Lambda函数,该函数基于特定资源标签操作。
    b. 一个Amazon CloudWatch日志组触发CloudWatch告警,告警通过Amazon SNS主题发送通知。
  4. SNS主题生成一封电子邮件通知,告知检测到了一个公共S3存储桶。

该解决方案使用‘GetBucketTagging’应用程序接口(API)操作返回与S3存储桶关联的标签集。本文共享的Lambda函数会迭代标签键值对,并检查是否存在特定的标签键值对(例如,tag_key = “bucket.status” & tag_value = “public.bucket”)。如果存在指定标签,则不会在这些存储桶上启用S3阻止公共访问。如果S3存储桶没有必要的标签,该解决方案会在这些存储桶上启用S3阻止公共访问。除非您希望S3存储桶可公开访问,否则应该启用S3阻止公共访问功能。

前提条件

在开始操作之前,您需要以下条件:

  • AWS账户
  • S3存储桶
  • AWS Lambda执行IAM角色
  • 提供Lambda函数权限以更新S3阻止公共访问设置的S3存储桶策略

操作步骤

接下来的部分将引导您完成解决方案的设置过程:

  1. 配置Security Hub
  2. 设置AWS Lambda函数
  3. 配置EventBridge规则及其目标
  4. 设置CloudWatch指标和告警

1) 配置Security Hub

在之前的文章“在您的AWS账户中查找公共Amazon S3存储桶”中,我们介绍了如何使用不同的AWS服务来检测组织中不同AWS区域的公共S3存储桶。Security Hub是其中之一,它是一种云安全姿态管理(CSPM)服务,可执行安全最佳实践检查,汇总警报,并启用自动修复。

您可以使用Security Hub通过AWS基础安全最佳实践(FSBP)标准的控制来监控公共S3存储桶。Security Hub使用与服务相关联的AWS Config规则来执行大部分控制的安全检查。请按照以下步骤开始:

  1. 在每个AWS区域中启用AWS Config。
  2. 通过与AWS Organizations集成或手动启用Security Hub。
  3. 在Security Hub中启用AWS FSBP标准

本文使用FSBP安全控制[S3.8] 一般用途的S3存储桶应阻止公共访问。此控制检查S3一般用途存储桶是否在存储桶级别阻止公共访问。以下图片显示了Security Hub中检测到公共S3存储桶的发现

Enter image description here

Security Hub自动发送新的发现并将更新的发现发送到EventBridge作为Security Hub Findings – Imported事件。也就是说,每次Security Hub在连续监控中检测到公共S3存储桶时,都会将事件发送到EventBridge。

2) 设置AWS Lambda函数

Lambda是一种无服务器计算服务,用于运行无需预置服务器的代码。在该解决方案中,EventBridge事件会调用一个Lambda函数(“BlockPublicS3Bucket”),以阻止S3存储桶的公共访问。此函数执行以下操作:

  1. 使用JSONPath表达式识别S3存储桶名称。
  2. 迭代S3存储桶标签并检查是否存在特定标签键值对。本文中使用的示例标签键值对为:
bucket_tag_key = "bucket.status"
bucket_tag_value = "public.bucket"
  1. 如果未找到标签,函数则继续使用put_public_access_block API调用阻止存储桶的公共访问配置。
  2. 如果找到了标签,则函数会跳过公共访问阻止,并记录一条日志消息。

该函数仅在S3存储桶上不存在指定标签的情况下才会阻止公共访问。以下是Lambda函数的前提条件:

  • 授予Lambda函数访问AWS服务和资源权限的Lambda执行IAM角色
  • 一个提供Lambda函数访问权限以更新S3阻止公共访问设置的S3存储桶策略。以下是一个示例策略。
{
    "Version": "2012-10-17",
    "Id": "BlockPublicAccess",
    "Statement": [
        {
            "Sid": "LambdaAccess",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789012:role/service-role/BlockPublicS3Bucket-role-123"
            },
            "Action": [
                "s3:GetBucketTagging", 
                "s3:PutBucketPublicAccessBlock"
            ],
            "Resource": "arn:aws:s3:::my-bucket"
        }
    ]
}

您可以在此AWS示例中找到Lambda函数

3) 配置EventBridge规则及其目标

EventBridge是一种无服务器服务,用于构建可扩展的事件驱动应用程序。通过使用EventBridge,您可以监控和审计AWS环境,并实时响应应用程序中的操作变更,以防止基础架构中的漏洞。EventBridge规则用于监控特定类型的事件。当发生匹配事件时,事件将路由到与该规则关联的目标。规则使用事件模式来选择事件并将其发送到目标,您可以将规则与一个或多个目标相关联。在本节中,我将介绍如何创建EventBridge规则及其两个关联目标。

  1. 创建一个EventBridge规则来监控由Security Hub生成的公共S3存储桶事件。参考文档中的创建响应事件的规则。您可以在此处找到示例Security Hub事件:示例事件
  2. 选择带有事件模式的规则。使用以下事件模式匹配由Security Hub生成的公共S3存储桶事件。
{
  "source": ["aws.securityhub"],
  "detail-type": ["Security Hub Findings - Imported"],
  "detail": {
    "findings": {
      "Compliance": {
        "Status": ["FAILED"],
        "SecurityControlId": ["S3.8"]
      },
      "RecordState": ["ACTIVE"],
      "Workflow": {
        "Status": ["NEW"]
      }
    }
  }
}
  1. 添加本方案中的Lambda函数和一个CloudWatch日志组作为目标(代码块后的截图中所示):

    a. 添加先前步骤中的Lambda函数“BlockPublicS3Bucket”。

    b. 添加一个CloudWatch日志组作为目标。CloudWatch允许您监控整个堆栈,并使用日志、指标和告警自动采取行动,减少平均解决时间。要将事件数据传送到目标日志组,EventBridge需要权限访问目标日志组。以下示例策略文档展示了您必须在日志组资源策略中定义的权限。更多详细说明请参考CloudWatch日志权限

Id": "CloudWatchLogforEventBridge 
  "Statement": [
    {
      "Action": [
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Effect": "Allow",
      "Principal": {
        "Service": [
          "events.amazonaws.com",
          "delivery.logs.amazonaws.com"
        ]
      },
      "Resource": "arn:aws:logs:<region>:<123456789012>:log-group:/aws/events/*:*",
      "Sid": "TrustEventsToStoreLogEvent"
    }
  ]
}

Enter image description here

  1. 配置标签、审查规则并选择创建规则

4) 设置CloudWatch指标和告警

一旦您将事件发送到CloudWatch日志组,可以配置CloudWatch指标和告警。

  1. 创建CloudWatch指标过滤器,以捕捉事件[S3.8] 一般用途的S3存储桶应阻止公共访问,并将其转换为数字CloudWatch指标。您可以使用指标过滤器将日志数据转换为可操作的指标。过滤器模式仅返回包含您定义术语的日志事件。这是一种创建告警或将日志事件路由到其他AWS服务的成本效益高的方式。要创建指标过滤器,请参考文档中的为日志组创建指标过滤器
  2. 使用自定义指标创建CloudWatch告警。更多说明请参考文档中的为CloudTrail事件创建CloudWatch告警示例。在配置操作页面,选择通知,然后选择告警,这意味着当阈值被突破时,将发送通知到SNS主题。使用Amazon SNS在您创建的CloudWatch告警状态改变时发送电子邮件通知给订阅的终端或客户端。要创建SNS主题,请按照文档中的步骤操作:创建Amazon SNS主题

清理

为了避免AWS账户中的持续费用,请务必清理为本篇文章创建的所有资源。删除Lambda函数、S3存储桶、CloudWatch告警、SNS主题,并移除您创建的其他AWS服务,以避免产生不必要的费用。

结论

在本文中,我们介绍了一种主动的、事件驱动的方法,使用AWS Security Hub检测公共S3存储桶,并在存储桶级别自动启用S3阻止公共访问功能。Security Hub会检查S3存储桶的合规性和安全性,并将发现发送到Amazon EventBridge。EventBridge随后调用AWS Lambda函数,该函数基于特定的资源标签阻止S3存储桶的公共访问,同时Amazon CloudWatch日志组触发告警,通知检测到一个公共S3存储桶。

在设计和实施自动修复工作流时,需谨慎操作,并建议进行彻底测试,以避免对应用程序造成意外后果或中断。除非您有意公开您的S3存储桶,否则应启用存储桶级和账户级别的Amazon S3阻止公共访问功能。防止数据被意外访问至关重要,本篇文章介绍的解决方案可以帮助确保您的数据不会被无意公开或共享。开始之前,请务必查看本文中提到的各服务选项的定价页面。

更多信息,请访问以下资源:

本文翻译自:Automatically scan for public Amazon S3 buckets and block public access