通过 HTTP 通过具有适当 ACL 的 VPC 终端节点将对象放入 AWS S3?



我正在使用 HTTPS 客户端将对象从配置了 S3 VPC 终端节点的 VPC 中的 EC2 实例放入 Amazon S3。目标存储桶的存储桶策略仅允许从特定 VPC 进行访问,因此无法通过 IAM 进行身份验证;我必须使用 HTTPS GET 和 PUT 来读取和写入对象。

如上所述,这工作正常,但是当我将其放入存储桶时,我遇到了应用于对象的ACL的问题。我已经尝试使用如下所示的HTTP标头设置Canned ACL,但都没有导致正确的行为:

x-amz-acl: private

如果我设置此标头,则对象是私有的,但只能由根电子邮件帐户读取,因此这不好。其他人需要能够通过 HTTPS 访问此对象。

x-amz-acl: bucket-owner-full-control

我完全认为这个罐头 ACL 可以解决问题,但是,它导致了意外的行为,即对象变得世界可读!我也不确定对象的所有者是如何决定的,因为它是通过 HTTPS 创建的,在控制台中,所有者被列为一个看似随机的值。这是文档说明:

对象拥有者和存储桶拥有者都会FULL_CONTROL通过 对象。如果您在创建存储桶时指定此标准 ACL,亚马逊 S3 会忽略它。

这完全让我感到困惑,因为根据存储桶策略,只有已批准的 VPC 的网络资源才能列出对象,更不用说读取对象了!也许这与 ACL 和存储桶策略的联合有关,我只是没有看到什么。

无论哪种方式,也许我无论如何都错了。如何通过 HTTPS 将对象放入 S3 并设置该对象的权限以匹配存储桶策略,或以其他方式使存储桶策略在 ACL 上具有权威性?

以下是存储桶策略,用于良好衡量:

{
"Version": "2008-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": [
"s3:AbortMultipartUpload",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:GetObject",
"s3:GetObjectTagging",
"s3:GetObjectTorrent",
"s3:GetObjectVersion",
"s3:GetObjectVersionTagging",
"s3:GetObjectVersionTorrent",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions",
"s3:ListMultipartUploadParts",
"s3:PutObject",
"s3:PutObjectTagging"
],
"Resource": [
"arn:aws:s3:::my-bucket",
"arn:aws:s3:::my-bucket/*"
],
"Condition": {
"StringEquals": {
"aws:SourceVpc": "vpc-12345678"
}
}
}
]
}

S3 ACL 和存储桶策略的工作方式是"最小权限"的概念。

您的存储桶策略仅为指定的 VPC 指定 ALLOW。没有其他人被授予允许访问权限。这与拒绝访问不同。

这意味着您的存储桶或对象 ACL 正在授予访问权限。

在 S3 控制台中,仔细检查 PUT 后的文件所有者是谁。

仔细检查存储桶的 ACL。您在存储桶级别授予了哪些权限?

仔细检查您用于 PUT 操作的权限。除非您已授予公有写入访问权限或存储桶策略允许 PUT,否则 PUT 必须使用签名。此签名将确定 PUT 操作的权限以及 PUT 之后文件的所有者。这由用于签名的访问密钥决定。

您的 x-amz-acl 应包含存储桶拥有者完全控制。

[在下面多次评论后编辑]

我看到的问题是您在示例中错误地接近安全性。我不会使用存储桶策略。相反,我将创建一个 IAM 角色,并将该角色分配给正在写入存储桶的 EC2 实例。这意味着随后将使用 IAM 角色访问密钥对 PAT 进行签名。这将保留对象的所有权。然后,您可以让 ACL 成为存储桶拥有者完全控制和公有读取(或您想要的任何受支持的 ACL 权限)。

最新更新