使用 Terraform 自动 GuardDuty 为组织启用亚马逊 - AWS Prescriptive Guidance

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

使用 Terraform 自动 GuardDuty 为组织启用亚马逊

由 Aarthi Kannan (AWS) 编写

代码存储库:amazon-guardduty-for-aws-organizations-with-terraform

环境:生产

技术:安全、身份、合规 CloudNative; DevOps

工作负载:所有其他工作负载

AWS 服务:亚马逊 GuardDuty;AWS Organizations

Summary

亚马逊 GuardDuty 持续监控您的亚马逊网络服务 (AWS) 账户,并使用威胁情报来识别您的 AWS 环境中意外和潜在的恶意活动。跨多个 AWS 区域或通过 AWS 管理控制台 GuardDuty 为多个账户或组织手动启用可能很麻烦。您可使用基础设施即代码(IaC)工具(例如 Terraform)实现流程自动化,该工具可在云中配置和管理多账户、多区域的服务和资源。

AWS 建议使用 AWS Organizations 在中设置和管理多个账户 GuardDuty。这种模式符合此建议。这种方法的一个好处是,在创建或向组织中添加新账户时, GuardDuty 将在这些账户中自动为所有受支持的地区启用这些账户,而无需手动干预。

此模式演示如何使用 HashiCorp Terraform GuardDuty 为组织中的三个或更多亚马逊网络服务 (AWS) 账户启用亚马逊。此模式所提供的示例代码执行以下操作:

  • GuardDuty 适用于所有 AWS Organizations 中目标组织当前成员的 AWS 账户

  • 在中启用 “自动启用” 功能 GuardDuty,该功能会自动 GuardDuty 为将来添加到目标组织的所有帐户启用

  • 允许您选择要启用的区域 GuardDuty

  • 使用组织的安全账户作为 GuardDuty 委派管理员

  • 在日志账户中创建 Amazon Simple Storage Service (Amazon S3) 存储桶,并 GuardDuty 配置为发布该存储桶中所有账户的汇总结果

  • 默认情况下,分配生命周期策略,在 365 天后将调查发现从 S3 存储桶转移至 Amazon S3 Glacier Flexible Retrieval 存储

您可手动运行此示例代码,也可以将其集成至持续集成和持续交付 (CI/CD) 管道。

目标受众

建议有使用 Terraform、 GuardDuty Python 和 AWS Organizations 经验的用户使用这种模式。

先决条件和限制

先决条件

  • 一个有效的 Amazon Web Services account。

  • 在 AWS Organizations 中设立了组织,该组织至少包含以下三个账户:

    • 管理账户 — 这是您从中部署 Terraform 代码的账户,可为是独立的,也可以作为 CI/CD 管道的一部分。Terraform 状态也存储至此账户。

    • 安全帐户-此帐户用作 GuardDuty 委派管理员。有关更多信息,请参阅 GuardDuty 委派管理员的重要注意事项(GuardDuty 文档)。

    • 日志账户-此账户包含 S3 存储桶,用于 GuardDuty 发布所有成员账户的汇总结果。

    有关如何使用所需配置设置组织的更多信息,请参阅创建账户结构 (AWS Well-Architected Labs)。

  • 一个 Amazon S3 存储桶和一个 Amazon DynamoDB 表,用作远程后端,将 Terraform 状态存储至管理账户中。有关使用远程后端获得 Terraform 状态的更多信息,请参见 S3 后端(Terraform 文档)。有关使用 S3 后端设置远程状态管理的代码示例,请参阅 remote-state-s3 后端(Terraform Registry)。请注意以下要求:

    • S3 存储桶和 DynamoDB 表必须在同一个区域中。

    • 创建 DynamoDB 表时,分区键必须为 LockID(区分大小写),并且分区键类型必须为字符串。所有其他表设置必须为其默认值。有关更多信息,请参阅关于主键创建表格(DynamoDB 文档)。

  • 一个 S3 存储桶,用于存储 GuardDuty 将在其中发布发现结果的 S3 存储桶的访问日志。有关更多信息,请参阅启用 Amazon S3 服务器访问日志记录(Amazon S3 文档)。如果您要部署至 AWS Control Tower 登录区,则可以为此目的重复使用日志存档账户中的 S3 存储桶。

  • 已安装并配置了 Terraform 版本 0.14.6 或更高版本。有关更多信息,请参阅入门 – AWS(Terraform 文档)。

  • Python 3.9.6 或更高版本已安装并配置。有关更多信息,请参见源版本(Python 网站)。

  • 已安装适用于 Python 的 Amazon SDK (Boto3)。更多信息,请参阅安装(Boto3 文档)。

  • 安装并配置了 jq。有关更多信息,请参阅下载 jq(jq 文档)。

限制

  • 此模式支持 macOS 和Amazon Linux 2 操作系统。此模式尚未经测试,无法在 Windows 操作系统中使用。

  • GuardDuty 必须尚未在任何目标区域的任何账户中启用。

  • 这种模式的 IaC 解决方案不部署先决条件。

  • 此模式专为遵循以下最佳实践标准的 AWS 登录区而设计:

    • 登录区是使用 AWS Control Tower 创建的。

    • 单独的 Amazon Web Services account 可用于安全和日志记录。

产品版本

  • Terraform 版本 0.14.6 或更高版本。示例代码已经过 1.2.8 的测试。

  • Python,版本 3.9.6 或更高版本。

架构

本节概括介绍此解决方案,以及由示例代码建立的架构。下图显示了在单个 AWS 区域 内跨组织不同账户部署的资源。

此架构图显示了管理、安全、日志和成员账户中的资源。
  1. Terraform 在安全账户和日志账户中创建 GuardDutyTerraformOrgRoleAWS Identity and Access Management (IAM) 角色。

  2. Terraform 在日志登录账户的默认 AWS 区域 中创建一个 S3 存储桶。此存储桶用作发布目的地,用于汇总组织中所有区域和所有账户的所有 GuardDuty 调查结果。Terraform 还在安全账户中创建了 AWS Key Management Service (AWS KMS) 密钥,用于加密 S3 存储桶中的调查发现,并配置以将结果从 S3 存储桶自动存档至 S3 Glacier Flexible Retrieval 存储。

  3. 在管理帐户中,Terraform 将安全帐户指定为的委托管理员。 GuardDuty这意味着安全账户现在可以管理包括管理账户在内的所有成员账户的 GuardDuty 服务。个人成员账户不能自行暂停或 GuardDuty 禁用。

  4. Terraform 在安全账户中为 GuardDuty 委托的管理员创建 GuardDuty 探测器。

  5. 如果尚未启用,Terraform 将在中启用 S3 保护。 GuardDuty有关更多信息,请参阅亚马逊中的 Amazon S3 保护 GuardDuty(GuardDuty 文档)。

  6. Terraform 将组织中所有当前活跃的成员帐户注册为成员。 GuardDuty

  7. Terraform 将 GuardDuty 委派管理员配置为将所有成员账户的汇总结果发布到日志账户中的 S3 存储桶。

  8. Terraform 会为您选择的每个 AWS 区域重复步骤 3 到 7。

自动化和扩缩

提供的示例代码为模块化特点,因此您可以将其集成至您的 CI/CD 管道中以实现自动部署。

工具

Amazon Web Services

其他工具和服务

  • HashiCorp Terraform 是一款命令行界面应用程序,可帮助您使用代码来配置和管理云基础架构和资源。

  • Python 是通用的编程语言。

  • jq 是命令行处理器,可帮助您处理 JSON 文件。

代码存储库

此模式的代码可在 GitHub amazon-guardduty-for-aws-organizations-with-terraform 存储库中找到。

操作说明

任务描述所需技能

克隆存储库。

在 Bash Shell 中,运行以下命令。在 其他信息” 部分的 “克隆存储库” 中,您可以复制包含 GitHub 存储库 URL 的完整命令。这会从中克隆 amazon-guardduty-for-aws-organizations-with-terraform 存储库。 GitHub

git clone <github-repository-url>
DevOps 工程师

编辑 Terraform 配置文件。

  1. 在克隆存储库的 root 文件夹,通过运行以下命令复制 configuration.json.sample 文件。

    cp configuration.json.sample configuration.json
  2. 编辑新的 configuration.json 文件,并为以下每个变量定义值:

    • management_acc_id — 管理账户的账户 ID。

    • delegated_admin_acc_id — 安全账户的账户 ID。

    • logging_acc_id — 登录账户的账户 ID。

    • target_regions— 您要启用的 AWS 区域列表,以逗号分隔。 GuardDuty

    • organization_id— 您要在其中启用的组织的 AWS Organizations ID GuardDuty。

    • default_region — 管理账户中存储您的 Terraform 状态的区域。这与您为 Terraform 后端部署 S3 存储桶以及 DynamoDB 表的区域相同。

    • role_to_assume_for_role_creation — 您要分配给安全和日志账户中的新 IAM 角色的名称。您在下一个故事中创建这个新角色。Terraform 代入此角色,以在安全和日志账户中创建 GuardDutyTerraformOrgRole IAM 角色。

    • finding_publishing_frequency— 将调查结果 GuardDuty 发布到 S3 存储桶的频率。

    • guardduty_findings_bucket_region — 您想要在其中为发布的调查发现创建 S3 存储桶的首选区域。

    • logging_acc_s3_bucket_name — 用于发布的调查发现的 S3 存储桶的首选名称。

    • security_acc_kms_key_alias— 用于加密 GuardDuty 发现结果的密钥的 AWS KMS 别名。

    • s3_access_log_bucket_name— 先前存在的 S3 存储桶的名称,您要在其中收集用于 GuardDuty 查找的 S3 存储桶的访问日志。此存储桶应与 GuardDuty 调查结果存储桶位于同一 AWS 区域。

    • tfm_state_backend_s3_bucket — 用于存储 Terraform 远程后端状态的先前存在的 S3 存储桶的名称。

    • tfm_state_backend_dynamodb_table — 用于锁定 Terraform 状态的先前存在的 DynamoDB 表的名称。

  3. 保存并关闭配置文件。

DevOps 工程师、通用 AWS、Terraform、Python

为新的 IAM 角色生成 CloudFormation 模板。

此模式包括用于创建两个 CloudFormation 模板的 IaC 解决方案。这些模板创建了 Terraform 在设置期间中使用的两个 IAM 角色。这些模板遵循最低权限安全最佳实践。

  1. 在 Bash shell 的存储库 root 文件夹中,导航至 cfn-templates/。此文件夹包含带有存根的 CloudFormation 模板文件。

  2. 运行以下命令。这会将存根替换为您在 configuration.json 文件中提供的值。

    bash scripts/replace_config_stubs.sh
  3. 确认已在该cfn-templates/文件夹中创建了以下 CloudFormation 模板:

    • management-account-role.yaml — 此文件包含角色定义和管理账户中 IAM 角色的相关权限,该角色具有完成此模式所需的最低权限。

    • role-to-assume-for-role-creation.yaml — 此文件包含安全账户和日志账户中 IAM 角色的角色定义和关联权限。Terraform 扮演这个角色是为了在这些账户中创建GuardDutyTerraformOrgRole角色。

DevOps 工程师,通用 AWS

创建 IAM 角色。

按照创建堆栈(CloudFormation 文档)中的说明,执行以下操作:

  1. 在安全账户和日志role-to-assume-for账户中部署-role-creation.yaml 堆栈。

  2. 在管理账户中部署 management-account-role.yaml 堆栈。成功创建堆栈并看到 CREATE_COMPLETE 堆栈状态后,请在输出中记下此新角色的 Amazon 资源名称(ARN)。

DevOps 工程师,通用 AWS

在管理账户中代入 IAM 角色。

作为安全最佳实践,我们建议您在继续操作之前担任新management-account-role的 IAM 角色。在 AWS 命令行界面(AWS CLI)的其他信息部分输入代入管理账户 IAM 角色命令

DevOps 工程师,通用 AWS

运行安装脚本。

在存储库 root 文件夹中,运行以下命令以启动安装脚本。

bash scripts/full-setup.sh

full-setup.sh脚本将执行以下操作:

  • 将所有配置值导出至环境变量

  • 为每个 Terraform 模块生成 backend.tfterraform.tfvars 代码

  • 通过 AWS CLI 为 GuardDuty 组织内部启用可信访问。

  • 将组织状态导入至 Terraform 状态

  • 创建 S3 存储桶,以用于在日志账户中发布调查发现

  • 创建 AWS KMS 密钥,以加密安全账户中的调查发现

  • 在 GuardDuty 整个组织、所有选定区域中启用,如架构部分所述

DevOps 工程师,Python
任务描述所需技能

运行清理脚本。

如果您使用此模式 GuardDuty 为组织启用并想要禁用 GuardDuty,请在存储库root文件夹中运行以下命令来启动 cleanup-gd.sh 脚本。

bash scripts/cleanup-gd.sh

此脚本在目标组织 GuardDuty 中禁用,删除所有已部署的资源,并将组织恢复到使用 Terraform 启用之前的状态。 GuardDuty

注意此脚本不会从本地和远程后端删除 Terraform 状态文件或者锁定文件。如果需要执行此操作,则必须手动执行这些操作。此外,此脚本不会删除已导入的组织或由其管理的账户。在清理脚本中,并 GuardDuty 未禁用对的可信访问。

DevOps 工程师、通用 AWS、Terraform、Python

移除 IAM 角色。

删除使用 role-to-assume-for-role-c reation.yaml 和.yaml 模板创建的堆栈。management-account-role CloudFormation 有关更多信息,请参阅删除堆栈(CloudFormation 文档)。

DevOps 工程师,通用 AWS

相关资源

AWS 文档

AWS 营销

其他资源

其他信息

克隆存储库

运行以下命令来克隆 GitHub 存储库。

git clone https://github.com/aws-samples/amazon-guardduty-for-aws-organizations-with-terraform

代入管理账户 IAM 角色

若要代入管理账户中的 IAM 角色,请运行以下命令。将 <IAM role ARN>替换为 IAM 角色的 ARN。

export ROLE_CREDENTIALS=$(aws sts assume-role --role-arn <IAM role ARN> --role-session-name AWSCLI-Session --output json) export AWS_ACCESS_KEY_ID=$(echo $ROLE_CREDENTIALS | jq .Credentials.AccessKeyId | sed 's/"//g') export AWS_SECRET_ACCESS_KEY=$(echo $ROLE_CREDENTIALS | jq .Credentials.SecretAccessKey | sed 's/"//g') export AWS_SESSION_TOKEN=$(echo $ROLE_CREDENTIALS | jq .Credentials.SessionToken | sed 's/"//g')