我在存储桶之间设置了复制功能,但新对象无法复制。如何排查此问题?

上次更新日期:2022 年 3 月 30 日

我在 Amazon Simple Storage Service (Amazon S3) 存储桶之间设置了跨区域复制 (CRR) 或同区域复制 (SRR)。但是,对象无法复制到目标存储桶。如何解决此问题?

解决方案

要对未复制到目标存储桶的对象进行问题排查,请检查存储桶的不同权限类型。此外,请检查公有访问权限设置和存储桶所有权设置。

提示:确保在每次配置更改后通过将对象上传到源存储桶来测试复制。最佳实践是每次更改一个配置以发现任何复制设置问题。

解决了导致复制失败的问题后,源存储桶中可能存在未复制的对象。默认情况下,S3 复制不会复制现有对象或复制状态为 FAILEDREPLICA 的对象。使用 S3 批量复制来复制这些对象。

Amazon S3 最低权限

确认 AWS Identity Access Management (IAM) 角色具有正确的权限。如果源存储桶和目标存储桶位于不同的账户中,请确认目标账户的存储桶策略也向复制角色授予了足够的权限。

以下示例显示了具有复制所需的最低权限的 IAM 策略。    根据复制规则选项,您可能需要授予其他权限

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetReplicationConfiguration",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws:s3:::SourceBucket"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:GetObjectVersionForReplication",
                "s3:GetObjectVersionAcl",
                "s3:GetObjectVersionTagging"
            ],
            "Resource": [
                "arn:aws:s3:::SourceBucket/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "s3:ReplicateObject",
                "s3:ReplicateTags"
            ],
            "Resource": "arn:aws:s3:::DestinationBucket/*"
        }
    ]
}

注意:将 SourceBucketDestinationBucket 替换为您的 S3 存储桶的名称。

IAM 角色必须具有信任策略,该策略允许 Amazon S3 代入复制对象的角色。例如:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "s3.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

如果目标存储桶位于其他账户中,则目标存储桶策略必须授予以下权限:

{
    "Version": "2012-10-17",
    "Id": "Policy1644945280205",
    "Statement": [
        {
            "Sid": "Stmt1644945277847",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::123456789101:role/s3-replication-role"
            },
            "Action": [
                "s3:ReplicateObject",
                "s3:ReplicateTags"
            ],
            "Resource": "arn:aws:s3:::DestinationBucket/*"
        }
    ]
}

注意:将 arn:aws:iam::123456789101:role/s3-replication-role 替换为您的复制角色的 ARN。    

其他 Amazon S3 权限

如果复制规则设置为将对象所有权更改为目标存储桶拥有者,则 IAM 角色必须具有 s3:ObjectOwnerOverrideToBucketOwner 权限。此权限放置在 S3 对象资源上。例如:

{
    "Effect":"Allow",
         "Action":[
       "s3:ObjectOwnerOverrideToBucketOwner"
    ],
    "Resource":"arn:aws:s3:::DestinationBucket/*"
}

目标账户还必须通过存储桶策略授予 s3:ObjectOwnerOverrideToBucketOwner 权限:

{
  "Version": "2012-10-17",
  "Id": "Policy1644945280205",
  "Statement": [
    {
      "Sid": "Stmt1644945277847",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789101:role/s3-replication-role"
      },
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateTags",
        "s3:ObjectOwnerOverrideToBucketOwner"
      ],
      "Resource": "arn:aws:s3:::DestinationBucket/*"
    }
  ]
}

注意:如果目标存储桶的对象所有权设置包括存储桶拥有者强制,则无需在复制规则中将对象所有权更改为目标存储桶拥有者。默认情况下会发生此更改。

如果复制规则已激活删除标记复制,则 IAM 角色必须具有 s3:ReplicateDelete 权限。如果目标存储桶位于其他账户中,则目标存储桶拥有者还必须通过存储桶策略授予此权限。例如:

{
    "Effect":"Allow",
         "Action":[
       "s3:ReplicateDelete"
    ],
    "Resource":"arn:aws:s3:::DestinationBucket/*"

}

注意:将 DestinationBucket 替换为您的 S3 存储桶的名称。

还必须通过目标存储桶上的存储桶策略授予相同的权限:

{
  "Version": "2012-10-17",
  "Id": "Policy1644945280205",
  "Statement": [
    {
      "Sid": "Stmt1644945277847",
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789101:role/s3-replication-role"
      },
      "Action": [
        "s3:ReplicateObject",
        "s3:ReplicateTags",
        "s3:ObjectOwnerOverrideToBucketOwner",
        "s3:ReplicateDelete"
      ],
      "Resource": "arn:aws:s3:::DestinationBucket/*"
    }
  ]
}

AWS KMS 权限

如果存储桶的源对象使用 AWS Key Management Service (AWS KMS) 密钥加密,则必须将复制规则配置为包含 KMS 加密的对象。

要包含使用 AWS KMS 加密的对象:

1.    打开 Amazon S3 控制台

2.    选择包含源对象的 S3 存储桶。

3.    在 Management(管理)选项卡上,选择复制规则。

5.    选择 Edit(编辑)。

6.    在加密下,选择 Replicate objects encrypted with AWS KMS(复制使用 AWS KMS 加密的对象)。

7.    在 AWS KMS key for encrypting destination objects(用于加密目标对象的 AWS KMS 密钥)下,选择一个 AWS KMS 密钥。默认选项是使用 AWS KMS 密钥 (aws/S3)。

重要提示:如果目标存储桶位于其他 AWS 账户中,请指定目标账户拥有的 KMS 客户托管密钥。请勿使用默认的 aws/S3 密钥。这会使用源账户拥有的 AWS 托管密钥对对象进行加密,且无法与其他账户共享。因此,目标账户无法访问目标存储桶中的对象。

要使用属于目标账户的 AWS KMS 密钥加密目标对象,目标账户必须在 KMS 密钥策略中授予复制角色:

{
    "Sid": "AllowS3ReplicationSourceRoleToUseTheKey",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::123456789101:role/s3-replication-role"
    },
    "Action": ["kms:GenerateDataKey", "kms:Encrypt"],
    "Resource": "*"
}

注意:如果您将星号 (*) 用于 AWS KMS 密钥策略中的资源,则该策略仅向复制角色授予 KMS 密钥的权限。该策略不允许复制角色提升其权限。

此外,源账户必须向复制角色的 IAM 策略添加以下最低权限:

{
    "Effect": "Allow",
    "Action": [
        "kms:Decrypt",
        "kms:GenerateDataKey"
    ],
    "Resource": [
        "SourceKmsKeyArn"
    ]
},
{
    "Effect": "Allow",
    "Action": [
        "kms:GenerateDataKey",
        "kms:Encrypt"
    ],
    "Resource": [
        "DestinationKmsKeyArn"
    ]
}

默认情况下,KMS 密钥策略向根用户授予对密钥的完全权限。这些权限可以委派给同一账户中的其他用户。除非源 KMS 密钥策略中有 deny 语句,否则使用 IAM 策略向复制角色授予源 KMS 密钥的权限就足够了。

显式拒绝和有条件允许语句

如果验证权限后,对象仍未进行复制,请检查是否有任何显式拒绝语句:

  • 目标存储桶策略或限制访问特定 CIDR 范围、VPC 终端节点或 S3 访问点的 KMS 密钥策略中的 Deny 语句可能会导致复制失败。
  • 附加到 IAM 角色的 Deny 语句或权限边界可能导致复制失败。
  • 附加到源账户或目标账户的 AWS Organizations 服务控制策略中的 Deny 语句可能会导致复制失败。

提示:在删除任何显式拒绝语句之前,请确认使用 deny 的原因并确定该语句是否对数据安全有影响。

如果源或目标 KMS 密钥根据加密上下文授予权限,请确认已为存储桶开启 S3 存储桶密钥。如果存储桶开启了存储桶密钥,则加密上下文必须针对存储桶级资源:

"kms:EncryptionContext:aws:s3:arn": [
     "arn:aws:s3:::SOURCE_BUCKET_NAME"
     ]
"kms:EncryptionContext:aws:s3:arn": [
     "arn:aws:s3:::DESTINATION_BUCKET_NAME"
     ]

注意:将 SOURCE_BUCKET_NAMEDESTINATION_BUCKET_NAME 替换为您的源和目标存储桶的名称。    

如果未为源存储桶或目标存储桶启用存储桶密钥,则加密上下文必须是对象级资源:

"kms:EncryptionContext:aws:s3:arn": [
     "arn:aws:s3:::SOURCE_BUCKET_NAME/*"
     ]
"kms:EncryptionContext:aws:s3:arn": [
     "arn:aws:s3:::DESTINATION_BUCKET_NAME/*"
     ]

注意:将 SOURCE_BUCKET_NAMEDESTINATION_BUCKET_NAME 替换为您的源和目标存储桶的名称。

对象 ACL 和阻止公有访问

检查源存储桶和目标存储桶是否在使用 ACL。如果对象附加了允许公有访问的 ACL,但目标存储桶正在使用阻止公有访问,则复制将失败。

源对象所有权

如果源存储桶中的对象是由另一个 AWS 账户上传的,则源账户可能没有访问这些对象的权限。检查源存储桶以查看 ACL 是否已停用。如果源存储桶已停用 ACL,则源账户是该存储桶中所有对象的拥有者。如果源存储桶未停用 ACL,请检查对象所有权是否设置为对象拥有者首选存储桶拥有者首选。如果将存储桶设置为存储桶拥有者首选,则源存储桶对象需要存储桶拥有者的 bucket-owner-full-control ACL 才能成为对象拥有者。

源账户可以通过停用 ACL 获得其存储桶中所有对象的所有权。大多数使用案例不需要使用 ACL 来管理访问权限。最佳实践是使用 IAM 和存储桶策略来管理对 S3 资源的访问权限。要停用 S3 存储桶上的 ACL,请参阅控制对象的所有权并禁用存储桶的 ACL。请务必评估存储桶和对象上的 ACL 的当前使用情况。您当前的存储桶和 IAM 策略必须授予足够的权限,以便您可以在不影响 Amazon S3 访问的情况下停用 ACL。


这篇文章对您有帮助吗?


您是否需要账单或技术支持?