配置VPC流日志以实现跨AWS账户的集中管理 - AWS Prescriptive Guidance

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

配置VPC流日志以实现跨AWS账户的集中管理

由本杰明·莫里斯 (AWS) 和 Aman Kaur Gandhi () 创作 AWS

环境:生产

技术:管理和治理

AWS服务:亚马逊 S3;亚马逊 VPC

Summary

在 Amazon Web Services (AWSVPC) 虚拟私有云 () 中,VPC流日志功能可以为操作和安全故障排除提供有用的数据。但是,在多账户环境中使用VPC流日志存在限制。具体而言,不支持 Amazon Logs 中的跨账户流 CloudWatch 日志。相反,您可以通过使用相应存储桶策略配置 Amazon Simple Storage Service(Amazon S3)存储桶来集中管理日志。

注意:此模式讨论了将流日志发送到集中位置的要求。但是,如果您还希望在成员账户中本地提供日志,则可以为每个账户创建多个流日志VPC。无法访问日志存档账户的用户可以查看流量日志以进行故障排除。或者,您可以为向日志发送日志的每个VPC流日志配置一个流 CloudWatch 日志。然后,您可以使用 Amazon Data Firehose 订阅筛选器将日志转发到 S3 存储桶。有关更多信息,请参阅相关资源部分。

先决条件和限制

先决条件

  • 一个活跃的AWS账户

  • 一个 Organizations AWS 组织,其账户用于集中管理日志(例如,日志存档)

限制

如果您使用AWS密钥管理服务 (AWSKMS) 托管密钥aws/s3来加密您的中央存储桶,它将不会收到来自其他账户的日志。相反,您将看到如下错误。

"Unsuccessful": [ { "Error": { "Code": "400", "Message": "LogDestination: <bucketName> is undeliverable" }, "ResourceId": "vpc-1234567890123456" } ]

这是因为账户的AWS托管密钥无法在账户之间共享。

解决方案是使用 Amazon S3 托管加密 (SSE-S3) 或您可以与成员账户共享的AWSKMS客户托管密钥。

架构

目标技术堆栈

在下图中,为每个流日志部署了两个流日志VPC。一个向本地日志组发送 CloudWatch 日志。另一个将日志发送到集中式日志账户中的 S3 存储桶。存储桶策略允许日志传输服务将日志写入存储桶。

注意:自 2023 年 11 月起, AWS 现在支持 a ws: SourceOrg ID 条件密钥。此条件允许您拒绝向 AWS Organizations 组织以外的账户写入中央存储桶。

目标架构

每个VPC流日志将日志发送到 S3 存储桶 CloudWatch ,一个流日志显示日志到 S3 buckt。

自动化和扩缩

每个VPC都配置为将日志发送到中央日志账户中的 S3 存储桶。使用以下自动化解决方案之一来帮助确保正确配置流日志:

工具

工具

  • Amazon CloudWatch Lo gs 可帮助您集中管理所有系统、应用程序和AWS服务的日志,以便您可以对其进行监控并安全地存档。

  • Amazon Simple Storage Service (Amazon S3) 是一项基于云的对象存储服务,可帮助您存储、保护和检索任意数量的数据。

  • Amazon Virtual Private Cloud(亚马逊VPC)可帮助您将AWS资源启动到您定义的虚拟网络中。此虚拟网络类似于您在自己的数据中心中运行的传统网络,其优点是使用的可扩展基础架构。AWS此模式使用VPC流日志功能来捕获有关进出您的网络接口的 IP 流量的信息VPC。

最佳实践

使用基础设施即代码 (IaC) 可以极大地简化VPC流日志的部署过程。将您的VPC部署定义抽象化为包含流日志资源构造将自动VPCs使用流日志进行部署。这将在下一节中演示。

集中式流日志

在 HashiCorp Terraform 中向VPC模块添加集中式流日志的语法示例

此代码创建了一个流日志,用于将日志从发送VPC到集中式 S3 存储桶。请注意,此模式不包括 S3 存储桶的创建。

有关推荐的存储桶策略语句,请参阅其他信息部分。

variable "vpc_id" { type = string description = "ID of the VPC for which you want to create a Flow Log" } locals { # For more details: https://docs.aws.amazon.com/vpc/latest/userguide/flow-logs.html#flow-logs-custom custom_log_format_v5 = "$${version} $${account-id} $${interface-id} $${srcaddr} $${dstaddr} $${srcport} $${dstport} $${protocol} $${packets} $${bytes} $${start} $${end} $${action} $${log-status} $${vpc-id} $${subnet-id} $${instance-id} $${tcp-flags} $${type} $${pkt-srcaddr} $${pkt-dstaddr} $${region} $${az-id} $${sublocation-type} $${sublocation-id} $${pkt-src-aws-service} $${pkt-dst-aws-service} $${flow-direction} $${traffic-path}" } resource "aws_flow_log" "centralized" { log_destination = "arn:aws:s3:::centralized-vpc-flow-logs-<log_archive_account_id>" # Optionally, a prefix can be added after the ARN. log_destination_type = "s3" traffic_type = "ALL" vpc_id = var.vpc_id log_format = local.custom_log_format_v5 # If you want fields from VPC Flow Logs v3+, you will need to create a custom log format. tags = { Name = "centralized_flow_log" } }

本地流日志

在 Terraform 中向具有所需权限的VPC模块添加本地流日志的语法示例

此代码创建了一个流日志,用于将日志从发送VPC到本地 CloudWatch 日志组。

data "aws_region" "current" {} variable "vpc_id" { type = string description = "ID of the VPC for which you want to create a Flow Log" } resource "aws_iam_role" "local_flow_log_role" { name = "flow-logs-policy-${var.vpc_id }" assume_role_policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Sid": "", "Effect": "Allow", "Principal": { "Service": "vpc-flow-logs.amazonaws.com" }, "Action": "sts:AssumeRole" } ] } EOF } resource "aws_iam_role_policy" "logs_permissions" { name = "flow-logs-policy-${var.vpc_id}" role = aws_iam_role.local_flow_log_role.id policy = <<EOF { "Version": "2012-10-17", "Statement": [ { "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:DescribeLogGroups", "logs:DescribeLogStreams", "logs:CreateLogDelivery", "logs:DeleteLogDelivery" ], "Effect": "Allow", "Resource": "arn:aws:logs:${data.aws_region.current.name}:*:log-group:vpc-flow-logs*" } ] } EOF } resource "aws_cloudwatch_log_group" "local_flow_logs" { # checkov:skip=CKV_AWS_338:local retention is set to 30, centralized S3 bucket can retain for long-term name = "vpc-flow-logs/${var.vpc_id}" retention_in_days = 30 } resource "aws_flow_log" "local" { iam_role_arn = aws_iam_role.local_flow_log_role.arn log_destination = aws_cloudwatch_log_group.local_flow_logs.arn traffic_type = "ALL" vpc_id = var.vpc_id tags = { Name = "local_flow_log" } }

操作说明

任务描述所需技能

确定加密策略并为中央 S3 存储桶创建策略。

中央存储桶不支持aws/s3AWSKMS密钥,因此您必须使用 SSE-S3 或AWSKMS客户管理的密钥。如果您使用AWSKMS密钥,则密钥策略必须允许成员账户使用该密钥。

合规

创建中央流日志存储桶。

创建将向其发送流日志的中央存储桶,然后应用您在上一步中选择的加密策略。这应该在日志存档或类似用途的账户中。

其他信息部分获取存储桶策略,并在使用您的环境特定值更新占位符后,将其应用于您的中央存储桶。

将军 AWS

配置VPC流日志以将日志发送到中央流日志存储桶。

将流日志添加到要从VPC中收集数据的每个流日志。实现此目的的最具可扩展性的方法是使用 IaC 工具,例如AFT或 AWS Cloud Development Kit (AWSCDK)。例如,您可以创建一个 Terraform 模块,在流日志VPC旁边部署。如有必要,您可以手动添加流日志。

网络管理员

将VPC流日志配置为发送到本地 CloudWatch 日志。

(可选)如果您希望流日志在生成日志的账户中可见,请创建另一个流日志,将数据发送到本地账户中的 CloudWatch 日志。或者,您可以将数据发送到本地账户中特定于账户的 S3 存储桶。

将军 AWS

相关资源

其他信息

桶策略

在为占位符名称添加值后,可以将此存储桶策略示例应用于流日志的中央 S3 存储桶。

{ "Version": "2012-10-17", "Statement": [ { "Sid": "AWSLogDeliveryWrite", "Effect": "Allow", "Principal": { "Service": "delivery.logs.amazonaws.com" }, "Action": "s3:PutObject", "Resource": "arn:aws:s3:::<BUCKET_NAME>/*", "Condition": { "StringEquals": { "s3:x-amz-acl": "bucket-owner-full-control", "aws:SourceOrgID": "<ORG_ID>" } } }, { "Sid": "AWSLogDeliveryCheck", "Effect": "Allow", "Principal": { "Service": "delivery.logs.amazonaws.com" }, "Action": "s3:GetBucketAcl", "Resource": "arn:aws:s3:::<BUCKET_NAME>", "Condition": { "StringEquals": { "aws:SourceOrgID": "<ORG_ID>" } } }, { "Sid": "DenyUnencryptedTraffic", "Effect": "Deny", "Principal": { "AWS": "*" }, "Action": "s3:*", "Resource": [ "arn:aws:s3:::<BUCKET_NAME>/*", "arn:aws:s3:::<BUCKET_NAME>" ], "Condition": { "Bool": { "aws:SecureTransport": "false" } } } ] }