本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
配置 VPC 流日志以实现对 Amazon Web Services account 的集中管理
创建者:Benjamin Morris (AWS) 和 Aman Kaur Gandhi (AWS)
摘要
在 Amazon Web Services(AWS)虚拟私有云(VPC)中,VPC 流日志功能可以为运营和安全故障排除提供有用的数据。但是,在多账户环境中使用 VPC 流日志存在限制。具体而言,不支持 Amazon Logs 中的跨账户流 CloudWatch 日志。相反,您可以通过使用相应存储桶策略配置 Amazon Simple Storage Service(Amazon S3)存储桶来集中管理日志。
注意
此模式讨论了将流日志发送到集中位置的要求。但是,如果您还希望在成员账户中本地提供日志,则可以为每个 VPC 创建多个流日志。无法访问日志存档账户的用户可以查看流量日志以进行故障排除。或者,您可以为向日志发送日志的每个 VPC 配置一个流 CloudWatch 日志。然后,您可以使用 Amazon Data Firehose 订阅筛选器将日志转发到 S3 存储桶。有关更多信息,请参阅相关资源部分。
先决条件和限制
先决条件
一个有效的 Amazon Web Services account
AWS Organizations 组织,其账户用于集中管理日志(例如,日志存档)
限制
如果您使用 AWS Key Management Service(AWS KMS)托管密钥 aws/s3
来加密您的中央存储桶,它将不会收到来自其他账户的日志。相反,你会看到一个Unsuccessful
错误代码 400,其中包含一条消息,例如你"LogDestination: <bucketName> is undeliverable"
给定的消息ResourceId
。
这是因为账户的 AWS 托管式密钥无法在账户之间共享。
解决方案是使用 Amazon S3 托管加密(SSE-S3)或 AWS KMS 客户托管密钥,您可以与成员账户共享该密钥。
架构
目标技术堆栈
在下图中,为每个 VPC 部署了两个流日志。一个向本地日志组发送 CloudWatch 日志。另一个将日志发送到集中式日志账户中的 S3 存储桶。存储桶策略允许日志传输服务将日志写入存储桶。
注意
自 2023 年 11 月起, AWS 现在支持 a ws: SourceOrg ID 条件密钥
目标架构

自动化和扩缩
每个 VPC 都配置为将日志发送到中央日志账户中的 S3 存储桶。使用以下自动化解决方案之一来帮助确保正确配置流日志:
工具
工具
Amazon CloudWatch Lo gs 可帮助您集中管理来自所有系统、应用程序和 AWS 服务的日志,以便您可以监控它们并安全地将其存档。
Amazon Simple Storage Service (Amazon S3) 是一项基于云的对象存储服务,可帮助您存储、保护和检索任意数量的数据。
Amazon Virtual Private Cloud (Amazon VPC) 可帮助您将 AWS 资源启动到您定义的虚拟网络中。此虚拟网络类似于您在自己的数据中心内运行的传统网络,具有使用 AWS 可扩展基础设施的优势。此模式使用 VPC 流日志功能来捕获有关在您的 VPC 中传入和传出各个网络接口的 IP 流量的信息。
最佳实践
使用基础设施即代码(IaC)可以极大地简化 VPC 流日志的部署过程。将您的 VPC 部署定义抽象化为包含流日志资源构造,将自动 VPCs 使用流日志进行部署。这将在下一节中演示。
集中式流日志
在 HashiCorp Terraform 中向 VPC 模块添加集中式流日志的语法示例
此代码创建流日志,用于将日志从 VPC 发送到集中式 S3 存储桶。请注意,此模式不包括 S3 存储桶的创建。
有关推荐的存储桶策略语句,请参阅其他信息部分。
variable "vpc_id" { type = string }
locals { 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_flow_log" {
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.
}
有关自定义日志格式的更多信息,请参阅 AWS 文档。
本地流日志
使用所需权限将本地流日志添加到 Terraform 中的 VPC 模块的语法示例
此代码创建流日志,用于将日志从 VPC 发送到本地 CloudWatch 日志组。
data "aws_region" "current" {}
variable "vpc_id" { type = string }
resource "aws_iam_role" "local_flow_log_role" {
name = "flow-logs-policy-${var.vpc_id}"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [{
"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:CreateLog*", "logs:PutLogEvents", "logs:DescribeLog*", "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" {
name = "vpc-flow-logs/${var.vpc_id}"
retention_in_days = 30
}
resource "aws_flow_log" "local_flow_log" {
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
}
操作说明
Task | 描述 | 所需技能 |
---|---|---|
确定加密策略并为中央 S3 存储桶创建策略。 | 中央存储桶不支持 | 合规 |
创建中央流日志存储桶。 | 创建将向其发送流日志的中央存储桶,然后应用您在上一步中选择的加密策略。这应该在日志存档或类似用途的账户中。 从其他信息部分获取存储桶策略,并在使用您的环境特定值更新占位符后,将其应用于您的中央存储桶。 | 常规 AWS |
配置 VPC 流日志以将日志发送到中央流日志存储桶。 | 向要从中收集数据的每个 VPC 添加流日志。实现这一目标的最具可扩展性的方法是使用 IaC 工具,例如 AFT 或 AWS Cloud Development Kit(AWS CDK)。例如,您可以创建一个在流日志旁边部署 VPC 的 Terraform 模块。如有必要,您可以手动添加流日志。 | 网络管理员 |
将 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"
}
}
}
]
}