背景

AWS S3的权限设置一直是一个重难点,而且是比较混淆的一个概念。比较混淆的地方在于,用户可以通过三个不同的地方进行权限管理,这三个地方分别是 IAM Policy, Bucket Policy 以及 Bucket ACL。

首先简单的说明一下他们的应用场景,IAM Policy是global级别的,他是针对用户来设置的,比如一个用户对所有的S3Bucket拥有get和list权限,那他就可以浏览任何一个Bucket的内容; 相较而言,S3 Bucket Policy仅仅是针对单个Bucket 而言的,他可以控制不同用户对他本身的访问权限;Bucket ACL是一个早期的服务,现在用的比较少了,但是如果我们需要对Bucket其中的具体对象配置访问权限,我们需要使用Bucket ACL。

下面通过一些简单的例子来看看这三个东西到底是怎么用的,如果有了冲突的设置,顺序是怎么处理的。

例1 IAM Policy

首先在IAM里面创建一个 Group,我给这个Group attach一个AWS Managed的 Policy,这个自带的policy允许S3 的只读权限

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

测试一下,发现只能浏览,但是不能上传
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

接下来,自己自定义一个Policy,自定义这个Policy允许用户上传文件

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

把这两个Policy都attach到我们的Group上,这个Group里面的User就可以浏览所有的Bucket,也可以上传文件了,当多个Policy 都关联到一个用户或者组的时候,他的权限是并集集合。

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

测试一下 ,上传测试成功

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

例2 Bucket Policy

接下来,我新建一个Bucket ,随便取名叫做 beanxyzbucket1234, 确保全球的唯一性,所有权限都是默认设置

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

我们来创建一个Bucket Policy ,在这个Policy里面我定义指定用户可以上传文件。这个Policy可以通过 Policy Generator来创建

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

首先获取对应的Bucket的ARN和用户的ARN,保存在记事本上
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

执行创建向导,允许 user1 在 我这个测试的bucket上进行delete 操作

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

他会自动生成一个JSON 的配置文件
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

复制粘贴这个JSOn文件过去试试,居然报错!!
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

事实上,这是一个已知的bug,我们需要手动的修改Resource,后面添加/和星号 , 表示这个bucket里面所有的资源

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

接下来用user1 登录,进入这个Bucket,删除文件,测试成功

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

结论:这里可以看出来,我的两个IAM Policy 分别授予了user1 对所有的Bucket都有读取和上传的权限;我的Bucket Policy 授予了这个用户在这个 bucket上 删除文件的权限,然后他的最终权限是三者的并集。

例3 创建第二个bucket,在这个bucket上面,我也创建一个bucket policy,禁止所有人访问这个bucket

同样的,通过Policy Generator 来创建policy的JSON文件

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL
自动生成的JSON文件,这个就不需要手动修改了

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

User1访问这个Bucket看看,果然没有权限访问了

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

结论:Deny 的权限高于一切 Allow的权限。尽管我的IAM Policy允许用户访问和上传,但是Bucket Policy 禁止一切操作,因此最后的权限是Deny

例4 ACL

Bucket 级别的ACL一般不推荐使用,毕竟是一个过时的服务。我们这里是针对单个文件的ACL访问权限的设置。

回到我们的第一个Bucket,先上传一个测试文件
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

Block public Access这里需要关掉,不然ACL会提示Access Denied
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

点击 Object,选择test.txt的Permission 设定。注意我这里修改的是单个文件的ACL访问权限,而不是整个Bucket的ACL

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

把Everyone Object 权限改为 Read
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

这样我们就可以从Object URL的连接打开这个文件了

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

打开看看
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

值得一提的是,我们这里没有强制https的访问,因此我们用http也是可以打开这个文件的
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

如果回到S3的控制界面,我们可以看见这个Bucket的Access变成了 Objects can be public,意思是我们没有共享整个Bucket,而仅仅是共享了其中的一些对象文件

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

例5 强制 HTTPS访问

例4里面 我们通过配置对文件对象的ACL允许public访问单个文件,但是因为没有强制https的访问,用户通过http也是可以访问的。

我们在这个Bucket上创建一个新的Bucket Policy,如下所示

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

执行之后,发现我们的https链接仍然是工作的,但是http就不行了

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

例6 禁止

最后,如果我把之前我自定义的IAM Policy 修改一下,我 Deny 所有的 Read 和 Put 操作,这样我的User1用户应该无法访问任何Bucket了

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

测试看看,的确是这样
AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

但是有趣的是,我仍然可以通过http/https访问我的测试文档

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL

这是为什么?这是因为我们的test.txt 文件的 ACL设定是允许public 任何人访问,因此任何匿名访问都是允许的,这里不存在任何验证机制,因此我们的IAM Policy的限制没有起作用

最后,我们来看看如果我们同时启用了3种授权方式,如何判断最终的用户权限。基本规则如下所示:

1.默认初始权限都是Deny。比如我创建了一个用户 但是没有给他配置任何Policy,那么他什么都没法访问
2.明确定义的Deny比Allow的权限高,如果在任何一个服务里面配置了Deny,那么这个Deny的优先级最高
3.如果没有明确定义Allow,那么默认请求会被Deny
4.只有在没有明确定义Deny的情况下,又明确定义了Allow,才会放行

AWS权限冲突-IAM Policy, S3 Bucket Policy 和 Bucket ACL