亚马逊AWS官方博客

跨 AWS 账号复制加密的 S3 对象

不同账号间复制Amazon S3加密对象

一个企业内拥有多个 AWS 账号是一种非常常见的情况,不同的 AWS 账号可以非常方便的实现资源隔离、安全隔离、成本分摊、计费、业务部门分离、审计、合规性等。但是,管理多个 AWS 账号也会有一些额外的复杂性。 通常,我们复制存储在 S3 中的数据主要是出于可靠性、合规性或者数据汇总等原因。 Amazon S3的复制支持跨存储桶自动以异步方式复制对象,可以将对象复制到单个目标存储桶或多个目标存储桶。目标存储桶可以位于不同的AWS区域(CRR: Cross-Region Replication),也可以与源存储桶位于同一区域(SRR: Same-Region Replication)内。但如果源存储桶中的对象被加密了,尤其是在跨账号的S3复制的情况下,对象要在不同的账号进行加/解密,该怎么操作呢? 本文介绍跨账号复制S3加密对象的配置方法和过程。

环境说明和先决条件

  • 2个 AWS 账号:在这里分别为abcxyz
  • AWS KMS密钥:事先创建2个KMS密钥,类型为“客户管理的密钥”
    abc账号下为:abc-KMS-key
    xyz账号下为:xyz-KMS-key
  • 源和目标端S3存储桶:事先创建2个S3存储桶,并启用版本控制和服务器端加密,加密密钥为上面创建的KMS密钥。
    S3存储桶:abc账号的S3存储桶位于us-west-2 区域,名称为:abc-crossaccount-bucket
    目标S3存储桶:xyz账号的S3存储桶位于eu-central-1 区域,名称为:xyz-crossaccount-bucket

KMS密钥创建

下面以源账号abc为例,说明如何创建为接下来的S3存储桶加密用的KMS密钥:

  1. KMS密钥创建 (密钥创建操作指引可参考官方文档:创建对称加密KMS密钥)
  • 在AWS管理控制台打开KMS管理页面,确认处在us-west-2 区域;然后在左边的导航菜单中选择“客户管理的密钥”,在右边的操作配置界面中,点击“创建密钥”;

  • 保持默认配置,点击“下一步”;

  • 输入要创建的KMS密钥的名称:abc-KMS-key,然后点击“下一步”;

  • 选择哪个IAM用户和角色可以作为该密钥的管理员,然后点击“下一步”;

  • 选择哪个IAM用户和角色可以该密钥进行加密操作。这里要先选择您一会用于创建S3存储桶的那个用户,然后点击“下一步”;

  • 最后,点击“完成”按钮,即可完成密钥的创建工作。

以同样的方式,在目标账号xyz里创建KMS密钥:xyz-KMS-key。

S3存储桶创建

下面以源账号abc为例,说明如何创建S3存储桶:

  • 在AWS管理控制台打开S3管理页面,在右边的操作配置界面中,点击“创建存储桶”;
  • 在创建存储桶配置页面中:

输入存储桶名称:abc- crossaccount-bucket;

在 AWS 区域中选中:us-west-2。

启用存储桶版本控制。

在加密配置部分,选择启用服务器端加密、加密类型为SSE-KMS、密钥选择您刚才创建的abc-KMS-key。

存储桶密钥:选择“禁用”。

  • 最后,点击“创建存储桶”,完成S3存储桶的创建。

以同样的方式,在目标账号xyz里创建S3存储桶:

  • 存储桶名称:xyz- crossaccount-bucket;
  • AWS 区域为:eu-central-1;
  • 启用版本控制;
  • 加密密钥:xyz-KMS-key、存储桶密钥:禁用。

IAM策略和角色配置

  1. 创建跨账号复制S3加密对象的IAM策略

在abc账号的IAM下,创建一个IAM策略: abc-to-xyz-crr-kms-policy.

说明:json是不能添加注释的,所以当您在使用的时候,需要把#的注释全部清除掉。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Action": [
                "s3:ListBucket",
                "s3:GetReplicationConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetObjectVersionAcl",
                "s3:GetObjectVersionTagging",
                "s3:GetObjectRetention",
                "s3:GetObjectLegalHold"
            ],
            "Effect": "Allow",
            "Resource": [
                " arn:aws:s3:::abc-corssaccount-bucket",  #源存储桶名称
                " arn:aws:s3:::abc-corssaccount-bucket/*",  #源存储桶名称
            ]
        },
        {
            "Action": [
                "s3:ReplicateObject",
                "s3:ReplicateDelete",
                "s3:ReplicateTags",
                "s3:ObjectOwnerOverrideToBucketOwner"
            ],
            "Effect": "Allow",
            "Resource": [
                " arn:aws:s3:::xyz-corssaccount-bucket/*"  #目标存储桶名称
            ]
        },
        {
            "Action": [
                "kms:Decrypt"  #用于解密源对象的 KMS 密钥权限
            ],
            "Effect": "Allow",
            "Condition": {
                "StringLike": {
                    "kms:ViaService": "s3.us-west-2.amazonaws.com",
                    "kms:EncryptionContext:aws:s3:arn": [
                        "arn:aws:s3:::abc-corssaccount-bucket/*"
                    ]
                }
            },
            "Resource": [
                "arn:aws:kms:us-west-aaaaaaaa552:key/aaaa-aaa-aaaa-aaaa-aaaaaa569b"
               # 源账号abc下创建的abc-KMS-key这个密钥的arn
            ]
        },
        {
            "Action": [
                "kms:Encrypt"  #用于加密对象副本的 KMS 密钥的权限
            ],
            "Effect": "Allow",
            "Condition": {
                "StringLike": {
                    "kms:ViaService": [
                        "s3.eu-central-1.amazonaws.com"
                    ],
                    "kms:EncryptionContext:aws:s3:arn": [
                        "arn:aws:s3:::xyz-corssaccount-bucket/*"
                    ]
                }
            },
            "Resource": [
                "arn:aws:kms:eu-central-1:xxxxxxxx 631:key/xxxxxxx-xxxx-xxxx-xxxx-xxxxxx457e"
                # 目标账号xyz下创建的xyz-KMS-key这个密钥的arn
            ]
        }
    ]
}
  1. 创建跨账号复制S3加密对象的IAM角色

在abc账号的IAM下,创建一个IAM角色: s3crr_role_for_abc_to_xyz.

  • 在创建角色的使用案例里,确保选择了“S3”,然后点击“下一步”;

  • 选中上面刚刚创建的IAM策略:abc-to-xyz-crr-kms-policy,然后点击“下一步”;

  • 给该角色输入一个名称,这里为:s3crr_role_for_abc_to_xyz,然后点击“创建角色”。 这个IAM角色,将在我们接下来的创建S3存储桶复制规则里用到。

目标 xyz账号下的KMS密钥和存储桶配置

  1. xyz-KMS-key密钥配置
  • 打开KMS管理配置界面,点击左边导航菜单栏里的“客户管理的密钥”,然后点击此前创建的密钥“xyz-KMS-key”,打开密钥配置界面,然后再点击“切换到策略视图”按钮,将会以json格式展示密钥策略。

  • 在密钥策略那点击 “编辑”,打开策略编辑界面,然后在密钥策略里添加下面的权限策略:允许abc账号的用于存储桶复制的角色s3crr_role_for_abc_to_xyz能使用xyz账号的xyz-KMS-key去加密存储对象。
{
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::aaaaaaa552:role/s3crr_role_for_abc_to_xyz"
            },
            "Action": [
                "kms:Encrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:DescribeKey"
            ],
            "Resource": "*"
        },
  • 编辑完成后,点击“保存更改”,进行保存。
  1. S3存储桶xyz-crossaccount-bucket存储桶策略设置
  • 打开xyz-crossaccount-bucket存储桶,点击“权限”标签,然后在存储桶策略部分点击“编辑”。

  • 在编辑存储桶策略中,设置一下策略,以允许abc账号下的角色s3crr_role_for_abc_to_xyz执行复制任务。
{
    "Version": "2012-10-17",
    "Id": "PolicyForDestinationBucket",
    "Statement": [
        {
            "Sid": "Permissions on objects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::aaaaaaa552:role/s3crr_role_for_abc_to_xyz"
            },
            "Action": [
                "s3:ReplicateDelete",
                "s3:ReplicateObject",
                "s3:ObjectOwnerOverrideToBucketOwner",
                "s3:List*",
                "s3:GetBucketVersioning",
                "s3:PutBucketVersioning"
            ],
            "Resource": [
                "arn:aws:s3:::xyz-corssaccount-bucket",
                "arn:aws:s3:::xyz-corssaccount-bucket/*"
            ]
        }
    ]
}
  • 编辑完成后,点击“保存更改”,进行保存。

源账号abc下的S3存储桶复制规则配置

存储桶的复制,是通过复制规则来完成的。现在我们在源存储桶abc-crossaccount-bucket上创建一条复制规则。

  • 打开abc-crossaccount-bucket存储桶,点击“管理”标签,然后在复制规则部分点击“创建复制规则”。

  • 复制规则的各项配置

在上面“目标”部分的“账户ID”,为xyz账号的ID。

在上面“加密”部分的“AWS KMS 密钥 ARN”这里,输入xyz账号下xyz-KMS-key密钥的ARN。

  • 完成上述配置后,点击“保存”。
  • 最后确认复制规则处于“以启用”状态。

这样,跨账号复制S3加密对象的配置

验证

  • 我们在abc-crossaccount-bucket存储桶里上传一个文件,这里为:createstreamprocessor.json。该文件的具体信息如下。在“对象管理概述”中,可以看到复制状态为PENDING。

  • 稍等几分钟后,复制状态变为“COMPLETED”。表明该存储对象已经被复制到目标端的xyz-crossaccount-bucket存储桶。

  • 在xyz-crossaccount-bucket存储桶,可以看到createstreamprocessor.json已经存在。

  • 查看createstreamprocessor.json的具体信息,可以看到其Etag和abc-crossaccount-bucket里的那个文件是完全一样的;同时它的复制状态为“RPLICA”,说明它是一个副本。

总结

本文主要介绍了使用S3的复制功能,轻松完成跨AWS账号下S3的加密数据的复制和传输。使用这个功能,您可以将数据汇总聚合到单个存储桶,进而做数据的统一分析和展示;又或者在生产账号和测试账号之间复制数据。

本篇作者

何康明

AWS解决方案架构师,负责基于AWS的云计算方案架构的咨询和设计,致力于AWS云服务在国内和全球的应用和推广。在加入AWS之前,曾就职于IBM和VMware,对公有云、私有云架构设计和交付方面有着丰富的经验。