两种方案任选,拿捏跨账户访问S3存储桶难题!

在亚马逊云科技多账户环境中,跨账户访问Amazon S3存储桶是一个常见需求,尤其是在集中式日志管理、共享数据仓库等场景下。而当Amazon S3存储桶启用了访问控制列表(ACL)时,跨账户访问可能会遇到复杂的权限问题。

本文将以一个真实的客户场景为例,深入探讨在存储桶所有者和对象所有者不同的情况下,如何解决Amazon S3存储桶的跨账号访问问题。
关于Amazon S3安全机制的概念介绍
Amazon S3提供了全面而精细的权限管理能力,让用户能够安全地控制对存储桶和对象的访问,比较常用的有以下3种。

1.Amazon IAM策略:这是一种基于身份的权限管理策略,需要将Amazon IAM策略附加到用户、组或者角色,来定义哪些身份可以对特定的Amazon S3资源执行哪些操作。
2.存储桶策略:这是一种基于资源的权限管理策略,需要在Amazon S3的存储桶策略中定义清楚谁可以对该存储桶及其中的对象执行哪些操作。
3.ACL方式:ACL是与资源关联的一系列授权,定义了哪些亚马逊云科技账户或预定义组有权访问资源以及允许的访问类型。
作为上一代的权限管理方式,ACL无法支持非常精细的权限控制,也无法与亚马逊云科技的其他服务完美集成,现在已经不推荐使用了。
至于是需要使用Amazon IAM策略,还是存储桶策略,您可以根据实际需求做选择,例如账号内同一身份需要多种资源的访问权限时,Amazon IAM策略就比较合适;需要授予其他亚马逊云科技账户访问您的存储桶时,存储桶策略就比较合适,当然也有复杂的场景可能需要二者结合使用。

*图片源自亚马逊云科技官网
当前的Amazon S3服务在新建存储桶时,您会看到有一个关于Object Ownership的选项,默认和推荐选项是“ACLs Disabled”,然后使用存储桶策略或者Amazon IAM策略都可以实现灵活安全的权限管理能力。
而上一代的权限管理方式,则主要是使用ACL实现的,它能够支持对象粒度的权限控制,但在跨账户场景下容易出现权限问题,当对象所有者与存储桶所有者不同时,存储桶拥有者可能无法控制其他账户上传的对象。本文就主要是为了解决这类ACL产生的历史遗留问题。
在Amazon S3中,存储桶所有者和对象所有者是两个不同的概念,特别是在启用ACL的场景下,这种区别尤为重要。
存储桶所有者(Bucket Owner)
创建Amazon S3存储桶的亚马逊云科技账户。
负责支付存储桶的存储和数据传输费用。
可以配置存储桶级别的设置(策略、生命周期规则等)。
可以删除整个存储桶及其内容。
对象所有者(Object Owner)
上传对象到存储桶的亚马逊云科技账户。
默认情况下拥有该对象的完全控制权。
可以设置对象级别的ACL权限。
可以删除或修改自己拥有的对象。
ACL场景下的关键挑战:
所有权分离:当其他亚马逊云科技账户将对象上传到您的存储桶时,默认情况下他们成为对象所有者,而非存储桶所有者。
权限限制:存储桶所有者对其他账户上传的对象可能只有有限权限,通常只能列出和删除。
跨账户挑战:这种所有权分离在跨账户访问场景中尤为棘手,可能导致“可列出但无法下载”的情况。
而本次客户遇到的问题就是“可列出但无法下载”的情况。
客户案例分析
问题背景
本次客户面临的正是典型的“可列出但无法下载”问题,涉及三个亚马逊云科技账户:
Account A:在Amazon EKS集群上运行Flink应用的大数据引擎的账号,需要访问Amazon CloudTrail Event日志进行安全分析。
Account B:集中日志存储账户,Amazon S3存储桶所在位置。
Account C:Amazon CloudTrail服务账户,将日志写入Account B的Amazon S3存储桶(客户实际场景中,有多个和Account C同样角色的Account,需要将Amazon CloudTrail日志写入Account B的Amazon S3存储桶中,这里仅以Account C为代表进行说明)。

Account A尝试下载Account B中的对象时,遇到了“可列出但无法下载”的情况,导致日志分析无法正常进行。
经确认,客户的Account B S3日志存储桶Bucket Policy中,已有关于Account A跨账户访问的配置,且在Account A中为Amazon EKS服务角色添加了正确的Amazon IAM策略。
问题根源
经过分析发现:
1.Account B中的Amazon S3存储桶创建于2022年,当时的存储桶默认启用了ACL,对应与当前服务设计中的Object writer。
2.存在所有权分离:Amazon S3存储桶的所有者是Account B,但对象由Account C的Amazon CloudTrail写入,因此对象所有者是Account C。
3.虽然通过Account B的存储桶策略授予了Account A访问权限,但由于对象所有者是Account C,Account A仍然无法下载这些对象。
解决方案
针对这个问题,本文提供两种解决方案。
方案一:禁用ACL(推荐)
前期准备
在禁用ACL之前,需要进行以下准备工作:
1.识别依赖ACL的访问模式,首先在控制台上可以看到存储桶级别的ACL。

2.然后确认对象级别的ACL:
开启Amazon S3服务器访问日志。
分析日志中的aclRequired字段,该字段指示请求是否需要ACL进行授权。
如果值为“Yes”,表示有请求依赖ACL;如果为“-“,则不依赖ACL。
确认没有关键访问依赖ACL后,才能安全地禁用ACL。
3.评估现有工作流程:
确认是否有应用程序依赖特定的ACL设置。
准备替代的存储桶策略,确保现有访问不受影响。
实施步骤
在Account B中,修改对象所有权设置:
1.登录亚马逊云科技管理控制台,导航至Amazon S3服务。
2.选择目标存储桶,点击“权限”选项卡。
3.在“对象所有权”部分,选择“编辑”。
4.选择“ACL已禁用”选项并保存更改。

效果分析
更改配置之前上传对象归属不发生变化,对象所有者依然是Account C,更改配置之后上传的对象都会自动归属于存储桶所有者(Account B)。
但是,Account B可以通过存储桶策略,授予Account A对于所有新老对象的访问权限(具体操作见存储桶策略与Amazon IAM配置详解)。

方案二:保持ACL启用,调整配置
如果由于某些原因无法禁用ACL,可以采用以下方案:
1.将对象所有权设置为“存储桶拥有者首选”(Bucket owner preferred)。

2.确保Amazon CloudTrail配置使用bucket-owner-full-control ACL上传对象,详细信息可参阅:Amazon S3 bucket policy for CloudTrail——Amazon CloudTrail,这样新上传的对象将由Account B拥有,可以通过存储桶策略授权给Account A进行下载(具体操作见存储桶策略与Amazon IAM配置详解)。
这里需要特别注意,在更改ACL配置前上传的对象,object owner还是Account C,且无法通过更新存储桶策略与Amazon IAM配置实现Account A的下载。
Amazon S3 bucket policy for CloudTrail——Amazon CloudTrail:
https://docs.aws.amazon.com/awscloudtrail/latest/userguide/create-s3-bucket-policy-for-cloudtrail.html

更改后上传的对象,object owner是Account B,可以通过更新存储桶策略与Amazon IAM配置实现Account A的下载。

存储桶策略与Amazon IAM配置详解
无论采用哪种方案,都需要正确配置存储桶策略和Amazon IAM权限。
在Account B中配置
Amazon S3存储桶策略
首先,需要在Account B中为Amazon S3存储桶添加策略,允许Account A中的Amazon EKS角色访问:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "AllowCrossAccountAccess", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::ACCOUNT-A-ID:role/EKS-SERVICE-ROLE-NAME" }, "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::BUCKET-NAME", "arn:aws:s3:::BUCKET-NAME/*" ] } ]}左右滑动查看完整示意
请替换:
ACCOUNT-A-ID:Account A的亚马逊云科技账户ID。
EKS-SERVICE-ROLE-NAME:Amazon EKS服务角色的名称。
BUCKET-NAME:Account B中的Amazon S3存储桶名称。
在Account A中为Amazon EKS
服务角色添加Amazon IAM策略
在Account A中,为Amazon EKS服务角色添加允许访问Account B中Amazon S3存储桶的策略。
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "s3:GetObject", "s3:ListBucket" ], "Resource": [ "arn:aws:s3:::BUCKET-NAME", "arn:aws:s3:::BUCKET-NAME/*" ] } ]}左右滑动查看完整示意
通过Amazon Web Services CLI附加策略
aws iam put-role-policy --role-name EKS-SERVICE-ROLE-NAME --policy-name S3CrossAccountAccess --policy-document file://s3-cross-account-policy.json —profile account-a-profile左右滑动查看完整示意
参数说明:
--role-name EKS-SERVICE-ROLE-NAME:指定要添加策略的Amazon IAM角色名称。
--policy-name S3CrossAccountAccess:为内联策略指定名称。
--policy-document file://s3-cross-account-policy.json:指定包含策略JSON的本地文件路径。
--profile account-a-profile:指定使用哪个亚马逊云科技配置文件的凭证,需要替换为您的亚马逊云科技配置文件名称,如果使用默认配置文件,可以完全删除此参数。
验证权限
在Amazon EKS Pod中测试访问权限:
列出存储桶内容。
aws s3 ls s3://BUCKET-NAME/下载对象。
aws s3 cp s3://BUCKET-NAME/path/to/object local-file左右滑动查看完整示意
总结
Amazon S3跨账户访问在启用ACL的环境中,确实面临独特的权限挑战,尤其当对象所有者与存储桶所有者不同时。本文通过分析实际客户案例,为您揭示了“可列出但无法下载”问题的根本原因,并提供了清晰的解决路径。
本文详细阐述了两种有效的解决方案:禁用ACL或优化ACL配置,并提供了完整的存储桶策略和Amazon IAM配置指南。对于大多数现代应用场景,推荐采用禁用ACL的方案,这不仅符合亚马逊云科技的最新最佳实践,还能显著简化权限管理并增强安全性。
值得一提的是,您也可以采用传统的Amazon IAM策略,结合assume role的方式实现跨账号访问。由于亚马逊云科技官方文档和其他博客已有详细介绍,本文不再赘述这一方法。
通过合理选择和实施这些策略,您可以轻松克服Amazon S3跨账户访问中的权限障碍,构建更加高效、安全的多账户亚马逊云科技环境。
五折认证,一次不过,免费重考,并享受官方备考服务。加入AWS AI/ML认证挑战,考取AWS AI认证为您的未来提供动力!

本篇作者

戴逸洋
亚马逊云科技数据存储资深架构师,致力于推广存储技术在云上的各种最佳实践。

任田田
亚马逊云科技解决方案架构师,负责基于亚马逊云科技云计算方案架构的咨询和设计,推广亚马逊云科技云技术和各种解决方案。

王泽耀
亚马逊云科技解决方案架构师,面向国内大型企业品牌出海,致力于亚马逊云科技云服务在国内的应用及推广。

张凯
亚马逊云科技解决方案架构师,主要负责基于亚马逊云科技的解决方案架构设计和方案咨询。具有多年的架构设计、项目管理经验。


星标不迷路,开发更极速!
关注后记得星标「亚马逊云开发者」
听说,点完下面4个按钮
就不会碰到bug了!

点击阅读原文查看博客!获得更详细内容!
更多推荐



所有评论(0)