AWS共有三种方式用来管理S3的访问权限

  • IAM policy
  • Bucket Policy
  • S3 ACL

此处深挖一下这三种访问控制的用法和区别

三种访问控制的介绍

S3的三种访问控制如下:

  • IAM Policy, 是基于用户层面的控制,attach to IAM实体(User, Role或Group),规定了谁能对哪些S3做什么操作
  • Bucket Policy, 是基于Bucket层面的控制, attach to Bucket, 规定了哪些人能对我这个Bucket中的resource做什么操作。
  • S3 ACL, 是基于Bucket或单个对象的,规定了谁能对我这个Bucket或对象做什么操作。

IAM Policy

IAM Policy 是实施在IAM层面的,规定了某个AWS IAM实体(User, Group或者Role)可以对S3所能做的操作。

IAM Policy由多个Statement组成,每个Statement都规定了允许/禁止某个AWS资源(包括但不限于S3)进行哪些操作这样的一组策略。

如下是一个IAM Policy的例子,在这个Policy中,允许对名为my_bucket的S3的bucket做任何s3的操作。

1
2
3
4
5
6
7
8
9
10
{
"Version": "2012-10-17",
"Statement":[{
"Effect": "Allow",
"Action": "s3:*",
"Resource": ["arn:aws:s3:::my_bucket",
"arn:aws:s3:::my_bucket/*"]
}
]
}

其中,

  • Effect定义了允许/禁止
  • Resource定义了AWS资源(包括但不限于S3)
  • Action定义了哪些操作

IAM Policy中没有代表Principal,因为IAM Policy是需要Attach给某个实体的,被Attach的实体(可以是User,Group或者Role)就承担了的这个属性,所以IAM Policy中是没有Principal的。

IAM Policy可以定义某个User,Group或者Role对所有AWS Resource的访问控制。针对S3的控制只是IAM Policy的子集而已

IAM Policy可以定义对多个S3 Bucket的控制,这是Bucket Policy无法做到的。

Bucket Policy

Bucket Policy是实施在S3 Bucket层面的,只能定义本Bucket中资源的访问权限,无法定义对其他Bucket的访问权限。如果定义了其他Bucket的访问权限,保存Policy的时候会报错。

Bucket Policy定义了可以被允许/禁止本bucket进行哪些操作.

如下是一个经典的Bucket Policy, 意思是允许任何人对bucket carl-test-at-seoul中的任意Object执行s3:GetObject的操作, 也就是将Bucket中的Object设置为Public Read。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
"Version": "2012-10-17",
"Id": "Policy1512465896017",
"Statement": [
{
"Sid": "Stmt1512465891857",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::carl-test-at-seoul/*"
}
]
}

Effect,Principal,Action,Resource的含义同IAM Policy中的意思相同。

S3 ACL

S3 ACL可以实施在Bucket层面,也可以实施在Object层面。

AWS为ACL设置了一些预定义的组

  • AWS account Access - 代表的是账户级别的设置,可以设置本账户和授权某个账户来访问S3的资源
  • Authenticated Users group - 代表的是AWS中任意验证过的账户,对这个组授权后,是世界上任何经过身份验证的AWS用户都可以访问你的Bucket
  • All Users group - 代表世界上的任何人
  • Log Delivery group - 针对服务器访问日志记录,用来允许AWS将某个S3的访问请求写入本Bucket

针对每个组,在Bucket或者Object层面上,有如下四种访问权限可以设置

  • List objects
  • Write objects
  • Read bucket permissions
  • Write bucket permissions

使用ACL来实施权限控制已经不被推荐, 有些设计例如Authenticated Users group, 设置后就会公开给所有AWS account,现在看来是很奇怪的设计。但系统都是逐渐完善的,S3是最早的一批服务,在没有IAM的当年,可能确实是有这类的需求。现在可以使用IAM Policy和Bucket Policy来设置更细粒度的控制。

关于ACL的使用,有一个常用的用法,当你要设置部分Object为Public-Read的时候,通过设置基于Object的All Users group的List objects权限,会很方便。而不需要在Bucket Policy中对每个Object 进行显式的配置。在AWS SDK中,表现为设置Object的s3_permissions为public_read

多个访问控制之间的判断规则

当用户访问或操作S3的资源时,S3会综合考虑IAM policy, S3 Bucket Policy和S3 ACL三者的设置,从而得出是否允许用户的操作。

总共有三种类型的Effect

  • default Deny - 基于最小权限原则,所有的Object默认都是私有的,也就是拒绝访问的
  • explicit Deny - 显式拒绝, IAM Policy或S3 Bucket Policy中Effect字段中显式声明为”Deny”,注意ACL中没有显示拒绝
  • explicit Allow - 显式允许, IAM Policy或S3 Bucket policy中Effect字段中显式生命为”Allow”的,ACL中设置的允许权限也是显式允许。

整体判定规则为:

  • 当有显式拒绝时,会被判定为拒绝访问。
  • 没有显式拒绝,有显示允许时,会被判定为允许访问。
  • 没有显式拒绝也没有显示允许时,就适用默认拒绝规则,会被判定为拒绝访问。
    s3_authz_diagram

例子

下面通过一个故事来大概讲解下IAM Policy,Bucket Policy和S3 ACL的使用和互相之间的作用。

有一位土豪(AWS Account), 拥有数不尽的家产,旗下产业不计其数,拥有万千工厂(EC2),仓库(S3)以及其他资产。为了便于管理仓库,每个仓库都是独立的房子,并且有着不同的名字和编号(S3 Bucket), 每个仓库有独立的管理员(Bucket Policy)管理。仓库里各个房间里存放着不计其数的物品(Object), 物品都是私有的(private object by default deny)。但是有些物品有对外展示的需要,因此就在仓库在第一层开了一些玻璃橱窗,用来展示一些公开的物品(ACL public-read object)。

情形1 - 单独设置Object ACL

没有IAM Policy,没有Bucket Policy, Object有部分被设置为Public-read ACL时

一天,来了个叫小明(anonymous user)的家伙,闯进了仓库(S3), 叫嚣乎说要进入仓库A(Bucket A)来查看其中的物品(Object), 仓库A的管理员老王(Bucket Policy)一看,压根不认识小明这哥们(Bucket Policy中没有匹配的规则),立马就把他挡在了仓库大门外(access deny),小明(anonymous user)在仓库周围晃悠了一圈,只看见了在玻璃橱窗里展示的一些物品(ACL public-read object), 其他什么也没看到,只能灰溜溜的走了。

情形2 - 设置Bucket Policy允许访问

没有IAM Policy,Bucket Policy设置为explicit allow,Object有部分被设置为Public-read ACL时

第二天,员工小毛(IAM User)来参观仓库A, 仓库A管理员老王(Bucket Policy)一看小毛在允许访问的名单内(匹配到Bucket Policy中explicit allow的规则),就打开大门放了小毛进仓库, 小毛进来把各个房间的物品(private object)和橱窗里的物品(ACL public-read object)都看了个遍, 临走还说没看够,明天还要再来参观。

情形3 - 设置Bucket Policy禁止访问某些资源

没有IAM Policy,Bucket Policy设置部分资源为explicit allow,部分资源为explicit deny, Object有部分被设置为Public-read ACL时

小毛参观仓库的事情被分管仓库的副总知道了,叮嘱仓库A管理员老王说,6号房间和6号橱窗的东西是贵重物品,不能给小毛参观(update Bucket Policy to add explicit deny)。

第三天小毛(IAM User)来仓库A参观,仓库A管理员老王(Bucket Policy)帮小毛开了门,但吩咐小毛说,从今天起,6号房间划归为贵重物品存放室了,不对你开放了(explict deny), 而且公开展示的6号橱窗里面的东西暂时也不能对你开放了,已经用布挡起来了(explict deny), 小毛进来参观了一天,除了不能参观的的6号房间(explicit deny)和被挡起来的6号橱窗(explicit deny override explicit allow),把其他物品都参观了一遍。

情形4 - 无法设置Bucket Policy来允许/禁止访问其他Bucket

Bucket Policy 无法设置其它Bucket的访问控制

第四天,小毛(IAM User)找到仓库A管理员老王说他想参观仓库B的物品,老王说自己只管理仓库A, 仓库B的东西归老张管。小毛只能悻悻地回家,没参观成仓库B。

情形5 - 设置IAM Policy来访问多个Bucket

设置IAM Policy来允许访问多个Bucket Policy

第五天,小毛(IAM User)发现,好朋友小强(IAM User)是土豪家(AWS Account)亲戚,便和小强找到董事长土豪,想要土豪批个通行证(IAM Policy)来参观仓库A和仓库B, 土豪二话不收就写了个允许参观仓库A和仓库B的批条(IAM Policy), 并在上面添加上了小毛和小强的名字(attach IAM Policy to IAM User), 小毛和小强拿着批条顺利的进入了仓库A和仓库B。

有了批条,小强就可以参观仓库A和仓库B的所有物品啦。至于小毛,因为分管仓库的副总嘱咐过,所以他还是没有权利参观仓库A的6号房间和6号橱柜(explicit deny override explicit allow)的物品,但可以被允许参观仓库B的物品了。

Reference

留言