S3 网站跨账户权限不起作用

S3 Website Cross Account Permissions Not Working

快速总结:

如果对象从不同的帐户(“帐户 B”)放入“帐户 A”拥有的存储桶中,则您无法从“帐户 A”(存储桶所有者)通过 S3 静态网站 (http) 访问文件。

无论在所有对象上授予 GetObject 的存储桶策略如何,也无论对象是否启用了 bucket-owner-full-control ACL,都是如此。

问题概述

我有一个独特的设置,我需要将文件从不拥有存储桶的帐户发布到 S3 存储桶。

上传操作正常。我的问题是,如果文件是从另一个帐户发布的(403 禁止响应),我无法通过 S3 静态网站从存储桶所有者帐户访问文件

仅当文件从其他帐户推送到 S3 时才存在问题。因为问题仅针对那些文件,所以问题似乎出在对象中所有权 ACL 配置。我已经确认我可以通过 S3 静态网站端点访问存储桶中的其他文件(不是由其他帐户上传的),所以我知道我的存储桶策略和 VPC 端点配置是正确的。

如果我完全禁用对象 ACL 它工作正常,但是我不能这样做,因为有两个问题:

  • Ansible 不支持将文件发布到禁用 ACL 的存储桶。 (禁用 ACL 是一个相对较新的 S3 功能,Ansible 不支持它)
  • 我用来发布文件的主要实用程序 (Aptly) 也不支持发布到禁用 ACL 的存储桶。 (禁用 ACL 是一个相对较新的 S3 功能,Aptly 不支持它)

由于上述限制,我必须在存储桶上启用对象 ACL。 我已经尝试了“Object Writer”和“Bucket owner preferred”这两个设置,都没有用。所有文件都使用 bucket-owner-full-control 对象 ACL 上传。

如前所述,禁用 ACL 可以解决所有问题,但由于我的客户端工具(Ansible 和 Aptly)无法在没有设置 ACL 的情况下上传到 S3,因此 ACL 必须保持启用状态。 (禁用 ACL 是一项相对较新的 S3 功能,于 2021 年底添加)

环境说明:

  • 存储桶 test-bucket-a 在“账户 A”中,它不是“私有”存储桶,但不允许 public 访问。访问权限是通过政策授予的(下面的片段)。

  • 桶对象(文件)从“账户 B”角色推送到 test-bucket-a

    • 通过策略(此处未显示)授予从“帐户 B”将文件放入存储桶的访问权限。文件上传没有问题。
    • 上传时为对象提供 bucket-owner-full-control ACL。
  • 我已验证 ACL 看起来正确并且“帐户 A”和“帐户 B”都具有对象访问权限。 (问题底部的屏幕截图)

  • 我正在尝试通过 S3 静态网站访问(通过 http)从存储桶所有者帐户(帐户 A)访问文件。我可以访问不是由“B 账号”上传但由“B 账号”上传的文件 return 403 Forbidden

以下是如何使用 Ansible 上传此文件的示例:

提醒:执行上传的角色不是存储桶所有者帐户的一部分。

- name: "publish gpg pubkey to s3 from Account B"
  aws_s3:
    bucket: "test-bucket-a"
    object: "/files/pubkey.gpg"
    src: "/home/file/pubkey.gpg"
    mode: "put"
    permission: "bucket-owner-full-control"

我是用VPC Endpoint访问,这个是加到bucket policy中的。所有需要的路由和端点配置都已就位。我知道我的策略配置很好,因为如果我禁用对象 ACL,一切都会正常运行。

{
    "Sid": "AllowGetThroughVPCEndpoint",
    "Effect": "Allow",
    "Principal": "*",
    "Action": "s3:GetObject",
    "Resource": "arn:aws:s3:::test-bucket-a/*",
    "Condition": {
      "StringEquals": {
        "aws:sourceVpce": "vpce-0bfb94<scrubbed>"
      }
    }
},

一些关键的故障排除说明:

  • 从“帐户 A”登录控制台后,我可以下载文件。这很奇怪,表明对 GetObject 的 API 请求正在运行。 S3 网站配置是否遵循一些不同的规则结构?
  • 当从 HTTP 端点(S3 网站)访问文件时,从“帐户 A”returns HTTP 403 禁止访问
  • 我已经尝试多次删除并重新上传文件。
  • 我尝试通过 aws cli 手动设置对象 ACL(例如:aws s3api put-object-acl --acl bucket-owner-full-control ...
  • 提供“public”ACL,例如 public-readpublic-read-write 可解决访问问题,但存储桶内容只能从 VPC 内访问
  • 查看“object”ACL时,我确认“账户A”和“账户B”都可以访问。请参见下面的屏幕截图。请注意,它确认对象所有者是外部帐户。

这个问题一直都是 Ansible 的错。

即使在上传期间设置了 permission: "bucket-owner-full-control",该设置也无法正常工作。我认为这个问题的副作用是:https://github.com/ansible-collections/amazon.aws/issues/219

修复:

我最终做了 ansible-galaxy collection install --upgrade amazon.aws 并尝试了 re-uploading 文件,一切都按预期工作。