跳至内容

在存储桶之间设置复制时,为什么我的 Amazon S3 对象不复制?

3 分钟阅读
0

我在我的 Amazon Simple Storage Service (Amazon S3) 通用存储桶之间设置了复制。但是,这些对象不会复制到位于同一 AWS 区域或其他区域的目标存储桶。

简短描述

**注意:**您只能对通用存储桶使用 Amazon S3 复制。您不能对目录存储桶和表存储桶使用复制。

要对无法进行跨区域复制 (CRR) 或同区域复制 (SRR) 的 Amazon S3 对象进行故障排除,请检查您的目标存储桶权限。此外,请检查公共访问权限设置和存储桶所有权设置。

解决了导致复制失败的问题后,源存储桶中可能存在仍然不复制的对象。默认情况下,Amazon S3 复制不复制现有对象或复制状态FAILEDREPLICA 的对象。要检查对象的复制状态,请参阅如何查看从一个 Amazon S3 存储桶复制到另一个 Amazon S3 存储桶失败的对象?对于这些对象,使用 S3 批量复制

解决方法

确定复制设置问题

每次配置更改后,请将对象上传到源存储桶,以测试复制。最佳做法是每次更改一个配置,以确定是否存在任何复制设置问题。

此外,启用 s3:Replication:OperationFailedReplication 事件类型通知以确定失败原因。

授予 Amazon S3 的最低权限

确认您在复制规则中使用的 AWS Identity Access Management (IAM) 角色具有正确的权限。如果源存储桶和目标存储桶位于不同的 AWS 账户,请确认目标账户的存储桶策略向复制角色授予权限。以下示例 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 替换为您的目标存储桶。

根据复制规则选项,您可能需要授予其他权限

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

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

授予其他 Amazon S3 权限

如果您将复制规则设置为 Change object ownership to the destination bucket owner(将对象所有权更改为目标存储桶所有者),则必须配置其他权限。

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

要向 IAM 角色授予 s3:ObjectOwnerOverrideToBucketOwner 权限,请在 Amazon S3 对象策略中添加以下权限:

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

**注意:**将 DestinationBucket 替换为您的目标存储桶。

此外,在目标账户的存储桶策略中添加以下 s3:ObjectOwnerOverrideToBucketOwner 权限:

{    "Sid": "1",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::SourceBucket-account-ID:role/service-role/source-account-IAM-role"
    },
    "Action": [
        "s3:ObjectOwnerOverrideToBucketOwner"
    ],
    "Resource": "arn:aws:s3:::DestinationBucket/*"
}

**注意:**将 SourceBucket-account-ID 替换为源存储桶账户,将 source-account-IAM-role 替换为源账户 IAM 角色,将 DestinationBucket 替换为目标存储桶。

如果您在复制规则上激活了删除标记复制,则 IAM 角色必须具有以下 s3:ReplicateDelete 权限:

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

**注意:**将 DestinationBucket 替换为您的目标存储桶。

如果目标存储桶位于其他账户中,则目标存储桶拥有者还必须在存储桶策略中添加以下权限:

{    "Version": "2012-10-17",
    "Id": "PolicyForDestinationBucket",
    "Statement": [
        {
            "Sid": "Permissions on objects",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::SourceBucket-account-ID:role/service-role/source-account-IAM-role"
            },
            "Action": [
                "s3:ReplicateObject",
                "s3:ReplicateTags",
                "s3:ObjectOwnerOverrideToBucketOwner",
                "s3:ReplicateDelete"
            ],
            "Resource": "arn:aws:s3:::DestinationBucket/*"
        },
        {
            "Sid": "Permissions on bucket",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::SourceBucket-account-ID:role/service-role/source-account-IAM-role"
            },
            "Action": [
                "s3:GetBucketVersioning",
                "s3:PutBucketVersioning"
            ],
            "Resource": "arn:aws:s3:::DestinationBucket"
        }

    ]
}

**注意:**将 arn:aws:iam::SourceBucket-account-ID:role/service-role/source-account-IAM-role 替换为您的复制角色的 Amazon 资源名称 (ARN),将 DestinationBucket 替换为您的目标存储桶。

授予 AWS KMS 权限

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

要配置所需的权限,请完成以下步骤:

  1. 打开 Amazon S3 控制台
  2. 选择源存储桶。
  3. 选择 Management(管理)选项卡,然后在 Replication rules(复制规则)下选择复制规则。
  4. 选择 Edit(编辑)。
  5. Encryption(加密)下,选择 Replicate objects encrypted with AWS KMS(复制使用 AWS KMS 加密的对象)。
  6. AWS KMS key for encrypting destination objects(用于加密目标对象的 AWS KMS 密钥)下,选择 AWS KMS 密钥。默认选项是使用 AWS KMS 密钥 (aws/S3)。

有关复制策略的示例,请参阅策略示例 - 将 SSE-S3 和 SSE-KMS 与复制结合使用

**注意:**如果目标存储桶位于其他账户中,请指定目标账户拥有的 AWS KMS 客户自主管理型密钥。默认 aws/S3 密钥使用源账户拥有的 AWS 托管式密钥加密对象。但是,您不能与其他账户共享 AWS 托管式密钥。

针对跨账户场景授予额外的 AWS KMS 权限

要使用目标账户的 AWS KMS 密钥加密目标对象,目标账户必须在密钥策略中允许复制角色。策略示例:

{    "Sid": "AllowS3ReplicationSourceRoleToUseTheKey",
    "Effect": "Allow",
    "Principal": {
        "AWS": "arn:aws:iam::SourceBucket-account-ID:role/service-role/source-account-IAM-role"
    },
    "Action": [
        "kms:GenerateDataKey",
        "kms:Encrypt"
    ],
    "Resource": "*"
}

**注意:**请将 arn:aws:iam::SourceBucket-account-ID:role/service-role/source-account-IAM-role 替换为复制角色 ARN。如果您对 Resource(资源)使用星号 (*),则该策略仅向复制角色授予权限。但是,该策略不允许复制角色扩展其权限。

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

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

默认情况下,AWS KMS 密钥策略向根用户授予对密钥的完全权限。您可以将这些权限委托给同一账户中的其他用户。您还可以使用 IAM 策略向复制角色授予源 KMS 密钥的权限。除非源 AWS KMS 密钥策略中存在 Deny 语句,否则此配置允许所需的访问权限。

检查是否存在显式拒绝语句和有条件允许语句

**重要事项:**在删除显式 Deny 语句之前,请确认其存在的原因以及这些语句是否影响数据安全。

如果在验证权限后,您的对象仍无法复制,请检查是否存在可能导致复制失败的显式 Deny 语句。

移除目标存储桶策略或 AWS KMS 密钥策略中限制访问以下资源的 Deny 语句:

  • 特定的 CIDR 范围
  • 虚拟私有云 (VPC) 端点
  • Amazon S3 接入点

此外,从源账户和目标账户的 IAM 角色策略和 AWS Organizations 服务控制策略 (SCP) 中移除 Deny 语句或权限边界。

检查 S3 存储桶密钥

如果源或目标 AWS KMS 密钥根据加密上下文授予权限,请检查是否使用了 S3 存储桶密钥。如果存储桶使用 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 替换为目标存储桶。

如果未对源存储桶或目标存储桶使用 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 替换为目标存储桶。

检查您的对象 ACL

检查源存储桶和目标存储桶是否使用屏蔽访问权限的访问控制列表 (ACL)。如果对象包含允许公共访问的 ACL,但目标存储桶使用 S3 屏蔽公共访问权限,则复制将失败。

确认源对象所有权

如果其他账户上传了源存储桶中的对象,则源账户可能没有对这些对象的访问权限。检查源存储桶是否已启用 ACL。

如果源存储桶已停用 ACL,则源账户为该存储桶中所有对象的拥有者。如果源存储桶已启用 ACL,请检查对象所有权是设置为 Object owner preferred(首选对象拥有者)还是 Bucket owner preferred(首选存储桶拥有者)。如果所有权设置为 Bucket owner preferred(首选存储桶拥有者),则源存储桶对象必须具有 bucket-owner-full-control ACL 权限。

源账户可以通过停用 ACL 来获得其存储桶中所有对象的所有权。大多数使用案例不需要 ACL 来管理访问权限。最佳做法是使用 IAM 和存储桶策略来管理对 Amazon S3 资源的访问。在停用 ACL 之前,请确保您的存储桶和 IAM 策略授予保留现有 Amazon S3 访问权限所需的权限。

指定正确的复制规则筛选条件

确保您正确指定了复制规则筛选条件

如果您指定的规则筛选条件是密钥前缀和对象标签的组合,则 Amazon S3 会执行逻辑 AND 操作。该规则适用于具有特定密钥前缀和特定标签的对象子集。

相关信息

配置实时复制的示例

AWS 官方已更新 6 个月前