使用 AWS CloudFormation 模板 GuardDuty 有条件地启用 Amazon - AWS 规范指引

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

使用 AWS CloudFormation 模板 GuardDuty 有条件地启用 Amazon

Ram Kandaswamy,Amazon Web Services

Summary

AWS CloudFormation是一款基础设施即代码 (IaC) 工具,可帮助您通过基于模板的部署来管理 AWS 资源。 CloudFormation 通常用于管理 AWS 资源。使用它来启用 AWS 服务(例如 Amazon GuardDuty)可能会带来独特的挑战。 GuardDuty 是一项威胁检测服务,可持续监控您的 AWS 账户 恶意活动和未经授权的行为。与可以多次创建的典型资源不同, GuardDuty 这是一项需要为每个账户启用一次的服务,而且 AWS 区域。传统 CloudFormation 条件仅支持静态值比较,因此很难检查服务的当前状态,例如 GuardDuty。如果您尝试在已处于活动状态的账户 CloudFormation 中启用 GuardDuty 直通,堆栈部署将失败。这可能会给管理多账户环境的 DevOps 团队带来运营挑战。

这种模式引入了应对这一挑战的解决方案。它使用由AWS Lambda函数支持的 CloudFormation 自定义资源来执行动态状态检查。条件逻辑 GuardDuty 只有在尚未启用的情况下才会启用。它使用堆栈输出来记录 GuardDuty 状态以备将来参考。

通过遵循这种模式,您可以自动 GuardDuty 部署整个 AWS 基础架构,同时保持干净、可预测的 CloudFormation 堆栈操作。这种方法对于符合以下条件的组织特别有价值:

  • AWS 账户 通过 IaC 管理多个

  • 大规模实施安全服务

  • 需要进行等性基础架构部署

  • 自动部署安全服务

先决条件和限制

先决条件

  • 活跃的 AWS 账户

  • 有权创建、更新和删除 CloudFormation 堆栈的 AWS Identity and Access Management (IAM) 角色

  • AWS Command Line Interface (AWS CLI),已安装配置

限制

如果 GuardDuty 已为 AWS 账户 或手动禁用此模式 AWS 区域,则不会 GuardDuty 为该目标账户或区域启用此模式。

架构

目标技术堆栈

该模式 CloudFormation 用于基础设施即代码 (IaC)。您可以使用由 Lambda 函数支持的 CloudFormation 自定义资源来实现动态服务启用功能。

目标架构

以下高级架构图显示了 GuardDuty 通过部署 CloudFormation 模板实现启用的过程:

使用 CloudFormation 堆栈在 AWS 账户 GuardDuty 中启用。
  1. 您可以部署 CloudFormation 模板来创建 CloudFormation 堆栈。

  2. 堆栈创建 IAM 角色和 Lambda 函数。

  3. Lambda 函数代入 IAM 角色。

  4. 如果尚未 GuardDuty 在目标上启用 AWS 账户,则 Lambda 函数将其启用。

自动化和扩展

您可以使用该 AWS CloudFormation StackSet 功能将此解决方案扩展到多个 AWS 账户 和 AWS 区域。有关更多信息,请参阅 CloudFormation 文档 AWS CloudFormation StackSets中的使用

工具

  • AWS Command Line Interface (AWS CLI) 是一个开源工具,可帮助您 AWS 服务 通过命令行外壳中的命令进行交互。

  • AWS CloudFormation帮助您设置 AWS 资源,快速一致地配置资源,并在资源的整个生命周期中跨地区对其 AWS 账户 进行管理。

  • Amazon GuardDuty 是一项持续的安全监控服务,可分析和处理日志,以识别您的 AWS 环境中意外和可能未经授权的活动。

  • AWS Identity and Access Management (IAM) 通过控制谁经过身份验证并有权使用 AWS 资源,从而帮助您安全地管理对资源的访问权限。

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

操作说明

Task说明所需技能

将代码存储在亚马逊 S3 中。

  1. 复制此模式的 “其他信息” 部分中的 Python 代码。

  2. 将代码粘贴至文本编辑器中。

  3. 将该文件保存为 index.py

  4. 将 文件上传到 Amazon Simple Storage Service (Amazon S3) 存储桶。有关说明,请参阅 Amazon S3 文档中的上传对象

AWS DevOps

创建 CloudFormation 模板。

  1. 打开 CloudFormation 控制台

  2. 在左侧导航窗格中,选择基础架构编排

  3. 如果您没有看到空白画布,请创建一个新项目。

  4. 将 AWS Lambda 函数拖放到画布上。

  5. 在模板视图中,验证 Lambda 函数和日志组是否存在。

  6. Runtime Lambda 函数修改为最新版本的 Python。

  7. 验证该Handler属性的值是否为 index.lambda_handler.

  8. 将该CodeUri属性配置为上传 Python 代码的 Amazon S3 位置。示例值为 s3://amzn-s3-demo-bucket/key-name

  9. 为资源添加Policies属性。遵循安全最佳实践,提供允许 CloudFormation 和 GuardDuty 操作的最低权限访问权限。例如,您可以将AWSLambdaExecute托管策略用于日志,将自定义策略iam:CreateServiceLinkedRole用于日志 GuardDuty。

  10. 导航到模板视图,将自定义资源定义添加到代码片段中。

    CheckResourceExist: Type: 'Custom::LambdaCustomResource' Properties: ServiceToken: !GetAtt Function.Arn
  11. 将模板另存为sample.yaml

AWS DevOps

创建 CloudFormation 堆栈。

  1. 在中 AWS CLI,输入以下命令。这将使用该sample.yaml文件创建一个新的 CloudFormation 堆栈。有关更多信息,请参阅 CloudFormation 文档中的创建堆栈

    aws cloudformation create-stack \ --stack-name guardduty-cf-stack \ --template-body file://sample.yaml
  2. 确认以下值出现在中 AWS CLI,表示堆栈已成功创建。创建堆栈所需时间量可能会有所不同。

    "StackStatus": "CREATE_COMPLETE",
AWS DevOps

验证 GuardDuty 是否已为启用 AWS 账户。

  1. 登录 AWS 管理控制台 并打开GuardDuty 控制台

  2. 确认该 GuardDuty 服务已启用。

云管理员、AWS 管理员

配置其他账户或区域。

根据您的用例需要,使用该 CloudFormation StackSet 功能将此解决方案扩展到多个 AWS 账户 和 AWS 区域。有关更多信息,请参阅 CloudFormation 文档 AWS CloudFormation StackSets中的使用

云管理员、AWS 管理员

相关资源

参考

教程和视频

附加信息

Python 代码

import boto3 import os import json from botocore.exceptions import ClientError import cfnresponse guardduty=boto3.client('guardduty') cfn=boto3.client('cloudformation') def lambda_handler(event, context): print('Event: ', event) if 'RequestType' in event: if event['RequestType'] in ["Create","Update"]: enabled=False try: response=guardduty.list_detectors() if "DetectorIds" in response and len(response["DetectorIds"])>0: enabled="AlreadyEnabled" elif "DetectorIds" in response and len(response["DetectorIds"])==0: cfn_response=cfn.create_stack( StackName='guardduty-cfn-stack', TemplateBody='{ "AWSTemplateFormatVersion": "2010-09-09", "Description": "Guard duty creation template", "Resources": { "IRWorkshopGuardDutyDetector": { "Type": "AWS::GuardDuty::Detector", "Properties": { "Enable": true } } } }' ) enabled="True" except Exception as e: print("Exception: ",e) responseData = {} responseData['status'] = enabled cfnresponse.send(event, context, cfnresponse.SUCCESS, responseData, "CustomResourcePhysicalID" ) elif event['RequestType'] == "Delete": cfn_response=cfn.delete_stack( StackName='guardduty-cfn-stack') cfnresponse.send(event, context, cfnresponse.SUCCESS, {})