我在存储桶之间设置了复制功能,但新对象无法复制。如何排查此问题?
上次更新日期:2022 年 3 月 30 日
我在 Amazon Simple Storage Service (Amazon S3) 存储桶之间设置了跨区域复制 (CRR) 或同区域复制 (SRR)。但是,对象无法复制到目标存储桶。如何解决此问题?
解决方案
要对未复制到目标存储桶的对象进行问题排查,请检查存储桶的不同权限类型。此外,请检查公有访问权限设置和存储桶所有权设置。
提示:确保在每次配置更改后通过将对象上传到源存储桶来测试复制。最佳实践是每次更改一个配置以发现任何复制设置问题。
解决了导致复制失败的问题后,源存储桶中可能存在未复制的对象。默认情况下,S3 复制不会复制现有对象或复制状态为 FAILED 或 REPLICA 的对象。使用 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/*"
}
]
}
注意:将 SourceBucket 和 DestinationBucket 替换为您的 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_NAME 和 DESTINATION_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_NAME 和 DESTINATION_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。