背景
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]()