相关文章:"朕亦甚想你"——从后宫管理看阿里云访问控制(下)
由后宫开始
后宫是一个江湖,这里有锦衣玉食的生活、汉宫秋月的孤寂、生杀予夺的权势、鸡犬升天的恩宠。后宫是皇上的私人港湾,皇上拥有后宫的所有资源,并自主分配这些资源。用之不尽后宫的资源怎么分配呢?历代都制定了严格的后宫制度。比如清朝后宫嫔妃定制如下:
封号 | 人数 | 待遇 |
---|---|---|
皇后 | 1 | 居中宫,年例1000两,宫女10名,理六宫 |
皇贵妃 | 1 | 居东西宫,年例800两,宫女8名 |
贵妃 | 2 | 居东西宫,年例600两,宫女8名 |
妃 | 4 | 居东西宫,年例300两,宫女6名 |
嫔 | 6 | 居东西宫,年例200两,宫女6名 |
贵人 | 不定 | 居殿,年例100两,宫女4名 |
常在 | 不定 | 居殿,年例50两,宫女3名 |
答应 | 不定 | 居殿,年例50两,宫女1名 |
按照封号分配资源,在后宫就是权利和利益的分配。皇后、嫔妃等每个封号都有它的资源内容和边界。封号其实就是资源分配策略(Policy),每个封号就是一种资源分配策略。后宫的娘娘、小主们被册封后,就拥有了封号的规定资源。从利益角度,册封就是资源授权。
后宫中皇上通过册封和废黜,控制资源的分配。从用户视角,皇上是当之无愧的超级用户。娘娘、小主们被册封后,拥有封号对应的资源;她们的资源是皇上赐予的,并依附于皇上,她们只是皇上的子用户,代替皇上行使部分资源的权限。甄嬛传中的嫔妃和封号如下图所示。
后宫中有一些角色(Role),职位固定,人员流动性较大,对后宫有一定的安全隐患,比如御医、御厨、宦官、宫女、侍卫等。这些角色上的人员需要严格的审核,颁发职位令牌、出入令牌,才能在角色规定的范围内活动。后宫角色的令牌有效期一般是一年,年审后重新颁发。角色按照后宫定制享有特定的资源,清后宫部分角色定制如下表。
角色 | 待遇 |
---|---|
御医 | 正五品 |
宦官 | 月例、月米、公费钱和恩加银 |
宫女 | 正七品,一等宫女(端茶倒水等); 从七品,二等宫女(做饭煎药等); 正八品,三等宫女(烧煤守夜等) |
侍卫 | 正七品,皇后/太后贴身侍卫; 正八品,各宫小主/娘娘/太妃/太嫔贴身侍卫; 正九品,侍卫 |
御厨 | 从七品 |
后宫角色天然附带资源的分配策略,其实后宫的角色设置更多,分配策略也更复杂、更细致。由于这些角色的流动性、安全性特点,我们称充当角色的人员为临时用户。皇后管理整个后宫日常事务,后宫的各角色人员由皇后甄选、决定。甄嬛传中温实初、苏培盛、流朱、夏刈、华妃厨等人员,及充当角色如下图。
阿里云的访问控制
阿里云也是一个江湖。这里有安全稳定的云计算产品、有宾至如归的贴心服务;但是也有一些有意无意的非法访问,企图侵占他人资源。阿里云访问控制(Resource Access Management, RAM)的目的是,保障合法用户的正常访问,拒绝非法用户的非法访问;达到阿里云用户拥有该有的资源,绝不能拥有不该有的资源。
阿里云有丰富的产品,每种产品提供一类服务,每类服务可以称为一类资源。每类资源都有严格的访问控制。只有被授权后,用户才能访问授权的资源。访问权限即是资源的使用权限。
下面是一个典型的应用场景。您在注册了阿里云账号,开通了某些云服务,您拥有开通的资源的所有访问权限,并可以授权给其它用户,您就是主用户或根用户(Root User)。您的公司很大,有多个部门,每个部门拥有部分服务的访问权限,每个部门就是您的一个子用户,您可以给他们相应的服务授权。您的公司推出一款手机App应用,用户手机工作在安全系数较低的公共网络上。手机App需要访问您的阿里云服务。App使用主用户或子用户访问,都是不合适的,因为访问密钥有泄漏风险。手机App可以用临时用户,临时用户可以赋予特定权限,并且有过期时间,安全性较高。
从上面典型场景看,阿里云的访问控制(RAM),三个因子:用户(User)、权限(Privilege)、资源(Resource)。
用户
阿里云的访问控制中,有三类用户:主用户(Root User),子用户(User),临时用户(Temporary User)。
用户类别 | 权限 | 创建 | 使用场景 |
---|---|---|---|
主用户 | 开通服务的所有权限 | 开通阿里云服务的用户 | 小的单位和个人,安全敏感度低的应用 |
子用户 | 授予的权限 | 主用户创建 | 企事业单位的部门、二级组织,安全性数较高的环境 |
临时用户 | 授予的特定资源部分权限 | 子用户创建,临时用户持有 | 第三方组织或个人、安全系数较低的环境 |
有三个问题需要说明:
- 阿里云访问控制中子用户也叫用户,本文章中为了区分用户级别,子用户含义的用户都称为子用户;
- 阿里云访问控制中临时用户也称为演员,比较专业,本文章采用比较普遍的称呼¬¬——临时用户;
- 上表中的扮演,其实就是充当意思,扮演看起来更专业、更文艺。
即 用户=子用户,演员=临时用户,充当=扮演。
资源
资源即阿里云服务,如下图所示,想了解更多请请登录 阿里云官网。
权限
访问权限可以根据不同的应用场景,形成不同权限策略(Policy),分配给子用户、临时用户。为了方便管理权限和用户,访问控制引入了群组(Group)和角色(Role)的概念。群组可以拥有一个或多个权限策略,子用户可以加入一个或多个群组;子用户加入群组后,即拥有了加入群组的所有权限。角色也可以拥有一个或多个权限策略,临时用户可以扮演角色;临时用户扮演角色后,即拥有了角色的权限。
子用户可以接受多个授权策略的授权,同时也可以加入一个或多个群组,子用户拥有的权限是策略授权和群组权限的并集,即子用户同时拥有授权策略和群组的权限。
临时用户能且只能扮演一个角色,临时用户的权限即角色权限。
阿里云存储产品OSS,存储空间里的文件(Object),有读(Get)、写(Put)、查看(List)、删除(Delete)等访问权限。您有一个视频网站,使用OSS存放视频文件,可以有以下权限分配。
权限策略 | 用户级别 | 拥有权限 | 应用场景 |
---|---|---|---|
PolicyRoot | 主用户 | 所有权限 | 不作为业务使用 |
PolicyAll | 子用户 | 拥有OSS的所有权限 | 后台管理人员使用 |
PolicyPull | 子用户 | OSS文件(Object)的读、写、查看权限 | 视频片源推入人员使用 |
PolicyPublic | 临时账号 | OSS文件(Object)的读、查看权限 | 视频受众使用 |
我们回过头来再看后宫,也有一套严格的权限控制体系。后宫与访问控制的对应关系,再看看下表,是不是有点醍醐灌顶的感觉。
后宫 | 访问控制 |
---|---|
皇上 | 主用户、根用户 |
宜修、端妃、甄嬛、沈眉庄、叶澜依等 | 子用户 |
皇后、皇贵妃、贵妃、妃、嫔等 | 授权策略 |
御医、宦官、宫女、侍卫、御厨 | 角色 |
温实初、苏培盛、流朱、夏刈、华妃厨等 | 临时用户 |
册封 | 授权 |
统理后宫权利 | 角色扮演权限 |
授权
访问
阿里云的资源都放在上锁的仓库中,防止被非法使用。正常用户要想访问,需要仓库的钥匙才能进入使用。用户的钥匙其实是一个密钥,每一个用户可以有多个密钥。一个密钥由AccessKeyID和AccessKeySecret组成,AccessKeyID用来标志用户,AccessKeySecret用来加密访问消息。
密钥怎么生成的呢?主用户进入https://ak-console.aliyun.com/
,可以创建、禁用、删除密钥,如下图。
子用户和临时用户怎么生成密钥呢?后面的授权章节中会说明。
授权
后宫的册封,即授权,过程极其繁琐,大致分为以下几个步骤。
- 择名,选择好吉利花名;
- 做宝,制作印玺;
- 行礼,行册封礼仪,主要是宣读圣旨;
- 谢恩,谢主隆恩;
- 朝拜,以新封号朝拜太后等后宫前辈们;
阿里云访问控制的授权,可没这么复杂哦,应该说是非常简单的。在阿里云控制台上,通过图形化界面即可完成授权。访问控制的主页https://ram.console.aliyun.com/
,界面如下。
子用户授权,就是把权限策略授给子用户,或者子用户加入群组。请看下图子用户管理界面,子用户授权应该了然于胸了吧。子用户管理常用操作路径如下:
- 授权路径:访问控制 -> 用户管理 -> 授权
- 查看授权策略路径:访问控制 -> 用户管理 -> 管理 -> 用户授权策略 -> 查看权限
- 解除授权策略路径:访问控制 -> 用户管理 -> 管理 -> 用户授权策略 -> 解除授权
- 加入群组:访问控制 -> 用户管理 -> 管理 -> 用户加入的组 –> 编译用户组
- 退出群组:访问控制 -> 用户管理 -> 管理 -> 用户加入的组 –> 退出该组
角色的授权,即把授权策略授给角色。在角色管理操作,请看下图角色管理界面。授权按钮中授权。管理按钮中可以查看角色的基本信息,如Arn、权限策略等。Arn是角色标志符,即角色的身份证,临时用户扮演角色时需要使用。角色管理常用操作路径如下:
- 授权路径:访问控制 -> 角色管理 -> 授权
- 查看授权路径:访问控制 -> 角色管理 -> 管理 -> 角色授权策略 -> 查看权限
- 解除授权路径:访问控制 -> 角色管理 -> 管理 -> 角色授权策略 -> 解除授权
角色有两种类型:
- 用户角色,允许访问控制临时用户扮演的角色。扮演角色的临时用户可以属于自己云账号,也可以是属于其他云帐号。用户角色主要用来解决跨帐号访问和临时授权的问题。
- 服务角色允许云服务所扮演的角色,被称为服务角色。服务角色主要用于授权云服务代理您进行资源操作。
上面角色分类的定义,有些晦涩难懂,请看下列场景角色授权:
- 主帐号A有个App应用,需要访问A的阿里云服务,A怎么授权为自己的临时用户授权呢?A创建一个
用户角色
,受信云账号为当前云账号
,并授权。然后通过角色扮演完成临时用户授权。角色扮演下面会讲到。 - A、B都申请了阿里云服务,且业务关联, B需要访问A的云服务,A怎么为B授权呢?首先A创建
用户角色
,受信云账号为其它云账号
,并在受信云账号ID中填写B的账号ID ,并用授权策略授权角色,即完成了服务角色授权。
B的账号ID可以在控制台的“账号管理->安全设置->账号ID”查到。 - A有个视频文件放在阿里云的存储系统OSS,需要使用转码服务MTS转码该文件,MTS服务需要访问用户的OSS文件,怎么授权MTS呢?A创建
服务角色
,选择受信任服务MTS
,并授予系统权限AliyunMTSRolePolicy,即完成了服务角色授权。
群组管理包括群组授权、子用户加入/退出群组。请看下图群组管理界面,群组授权及管理,是so easy吧。
授权策略
授权策略语言
授权策略定义了一种或多种资源的访问权限,可以由授权策略语言描述。先看一个简单的授权策略:
{
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": ["oss:List*", "oss:Get*"],
"Resource": [
"acs:oss:*:1234567890123456:samplebucket",
"acs:oss:*:1234567890123456:samplebucket/*"
],
"Condition": {
"IpAddress": {
"acs:SourceIp": "42.160.1.0"
}
}
}
]
}
该授权策略描述的含义是,允许对OSS的samplebucket有只读权限,且请求的来源IP为42.160.1.0。
授权策略,用JSON格式描述,包括策略版本号(Version)及授权语句列表(Statement)。每个授权语句包括授权类型Effect、操作方法Action、操作对象Resource以及限制条件Condition,其中Condition是可选项。授权策略大小写敏感,Action与action是不同的哦。
比如授权策略允许张三在2016年12月31日之前,可以对OSS存储空间SampleBucket执行ListObject操作
,该语句中授权元素说明如下。
元素 | 含义 | 示例 |
---|---|---|
Effect授权类型 | 授权类型包括两种:允许Allow和拒绝Deny。 | Effect是Allow |
Resource操作对象 | 指被授权的具体访问对象,即操作需要的资源。 | Resource是SampleBucket |
Action操作方法 | 指对具体资源的操作,及访问方法,或访问方式。 | Action是ListObject |
Condition限制条件 | 指授权生效的限制条件。 | Condition是2016.12.31前 |
更详细的授权策略语言说明,请参看 授权策略语言 。
OSS权限列表
OSS是阿里云的存储服务,包括存储空间(Bucket)和文件(Object)两类资源。
Effect授权类型,包括Allow和Deny,分别是通过和禁止。
Resource访问对象,分两类Bucket级别、Object级别。Bucket级别的Resource书写规则是“acs:oss:{region}:{bucketOwnerID}:{bucketName}”;Object级别的Resource书写规则是“acs:oss:{region}:{bucketOwnerID}:{bucketName}/{objectName}”。Resource是一个列表,可以有多个Resource。
上述规则中的region字段暂时不支持,设置为“\*”
。bucketOwnerID存储空间拥有者的ID,即用户的云账号ID;可以在控制台的“账号管理 -> 安全设置 -> 账号ID”查看到,如下图所示。bucketOwnerID也可以使用“\*”
。
Action访问方法,分两类;一类是bucket级别的操作,比如oss:ListBuckets 、oss:PutBucketAcl、oss:PutBucketLifecycle等,操作的对象是bucket,名称和相应的API接口基本对应。另一类是object级别的操作,如oss:GetObject、oss:PutObject、oss:DeleteObject、oss:PutObjectAcl等。所有的Action前面都必须加上“oss:”。Action是一个列表,可以有多个Action。具体的Action和API接口的对应关系如下。
OSS Bucket级别Action如下表。
OSS API | Action | Java SDK |
---|---|---|
GetService(ListBuckets) | oss:ListBuckets | OSSClient.listBuckets |
GetBucket( ListObjects ) | oss:ListObjects | OSSClient.listObjects |
ListMultipartUploads | oss:ListMultipartUploads | OSSClient.listMultipartUploads |
PutBucket | oss:PutBucket | OSSClient.createBucket |
DeleteBucket | oss:DeleteBucket | OSSClient.deleteBucket |
PutBucketAcl | oss:PutBucketAcl | OSSClient.setObjectAcl |
GetBucketAcl | oss:GetBucketAcl | OSSClient.getObjectAcl |
GetBucketLocation | oss:GetBucketLocation | OSSClient.getBucketAcl |
GetBucketLogging | oss:GetBucketLogging | OSSClient.getBucketLogging |
PutBucketLogging | oss:PutBucketLogging | OSSClient.setBucketLogging |
DeleteBucketLogging | oss:DeleteBucketLogging | OSSClient.deleteBucketLogging |
GetBucketWebsite | oss:GetBucketWebsite | OSSClient.getBucketWebsite |
PutBucketWebsite | oss:PutBucketWebsite | OSSClient.setBucketWebsite |
DeleteBucketWebsite | oss:DeleteBucketWebsite | OSSClient.deleteBucketWebsite |
GetBucketReferer | oss:GetBucketReferer | OSSClient.getBucketReferer |
PutBucketReferer | oss:PutBucketReferer | OSSClient.setBucketReferer |
GetBucketLifecycle | oss:GetBucketLifecycle | OSSClient.getBucketWebsite |
PutBucketLifecycle | oss:PutBucketLifecycle | OSSClient.setBucketWebsite |
DeleteBucketLifecycle | oss:DeleteBucketLifecycle | OSSClient.deleteBucketWebsite |
PutBucketCors | oss:PutBucketCors | OSSClient.setBucketCORS |
GetBucketCors | oss:GetBucketCors | OSSClient.getBucketCORSRules |
DeleteBucketCors | oss:DeleteBucketCors | OSSClient.deleteBucketCORSRules |
PutBucketReplication | oss:PutBucketReplication | OSSClient.addBucketReplication |
GetBucketReplication | oss:GetBucketReplication | OSSClient.getBucketReplication |
DeleteBucketReplication | oss:DeleteBucketReplication | OSSClient.deleteBucketReplication |
GetBucketReplicationLocation | oss:GetBucketReplicationLocation | OSSClient.getBucketReplicationLocation |
GetBucketReplicationProgress | oss:GetBucketReplicationProgress | OSSClient.getBucketReplicationProgress |
OSS Object级别Action如下表。
OSS API | Action | Java SDK |
---|---|---|
GetObject | oss:GetObject | OSSClient.getObject |
HeadObject | oss:GetObject | OSSClient.getObjectMetadata |
PutObject | oss:PutObject | OSSClient.putObject |
AppendObject | oss:PutObject | OSSClient.appendObject |
PostObject | oss:PutObject | / |
InitiateMultipartUpload | oss:PutObject | OSSClient.initiateMultipartUpload |
UploadPart | oss:PutObject | OSSClient.uploadPart |
CompleteMultipart | oss:PutObject | OSSClient.completeMultipartUpload |
AbortMultipartUpload | oss:AbortMultipartUpload | OSSClient. abortMultipartUpload |
DeleteObject | oss:DeleteObject | OSSClient.deleteObject |
DeleteMultipartObjects | oss:DeleteObject | OSSClient.deleteObjects |
CopyObject | oss:GetObject,oss:PutObject | OSSClient.copyObject |
UploadPartCopy | oss:GetObject,oss:PutObject | OSSClient.uploadPartCopy |
GetObjectAcl | oss:GetObjectAcl | OSSClient.getObjectAcl |
PutObjectAcl | oss:PutObjectAcl | OSSClient.setObjectAcl |
ListParts | oss:ListParts | OSSClient.listParts |
Condition限制条件,可以限制访问IP、访问日期等;也可以限制List操作的前缀prefix、分隔符delimiter。OSS支持的Condition如下表:
Condition | 功能 | 合法取值 | 示例 |
---|---|---|---|
acs:SourceIp | 指定IP网段 | 字符串,普通的ip,支持* 通配 |
10.101.168.111 10.101.169.111/24 |
acs:UserAgent | 指定http useragent头 | 字符串,字符串 | Java sdk v2.2.3 |
acs:CurrentTime | 指定合法的访问时间 | 字符串,ISO8601格式 | 2016-01-01T00:00:00+08:00 |
acs:SecureTransport | 是否是https协议 | 布尔,true或者false | True,false |
oss:Prefix | 用作ListObjects时的prefix | 字符串,合法的object name | foo,bar |
oss:Delimiter | 用作ListObject时的delimiter | 字符串,合法的delimiter值 | / |
OSS Condition类型操作符见下表:
类型 | 操作符 | 示例 |
---|---|---|
String | StringEquals StringNotEquals StringEqualsIgnoreCase StringNotEqualsIgnoreCase StringLike StringNotLike |
"Condition": { "StringLike": { "oss:Prefix": "hangzhou/2015/*" } } |
Numeric | NumericEquals NumericLessThan NumericLessThanEquals NumericGreaterThan NumericGreaterThanEquals |
OSS暂时未使用 |
Date and time | DateEquals DateNotEquals DateLessThan DateLessThanEquals DateGreaterThan DateGreaterThanEquals |
"Condition": { "DateLessThan": { "acs:CurrentTime": "2016-01-01T00:00:00+08:00" } } |
Boolean | Bool | "Condition": { "Bool": { "acs:SecureTransport": "true" } } |
IP address | IpAddress NotIpAddress |
"IpAddress": { "acs:SourceIp": [ "10.101.168.111", "10.101.169.111/24" ] } |
您的视频网站公司,来了一个美女实习生。您想让她熟悉一下业务,删除一批过期视频练练手吧。您跟她下达了一个的任务:2016年12月31号前,删除存储空间ccav里的,2012年体育类型的视频文件sport/old/2012。她初来乍到,出错的可能性极高哦。通过授权控制她的权限,不给她犯错机会,这是上上策,您怎么给她授权呢?
首先,她需要查看ccav里sport/old/2012的权限。
- Effect是Allow;
- Action是oss:ListObjects;
- Resource是acs:oss:::ccav,注意ListObjects是Bucket级别的操作,所有Resource是这种格式,操作目录用Condition前缀指定;
- Condition指定目录前缀oss:Prefix,是sport/old/2012/*,操作符是StringLike,即左匹配模式即有权限查看sport/old/2012/cba、sport/old/2012/nba等;
授权语句如下:
{
"Effect": "Allow",
"Action": [
"oss:ListObjects"
],
"Resource": [
"acs:oss:*:*:ccav"
],
"Condition":{
"StringLike":{
"oss:Prefix":"sport/old/2012/*"
}
}
}
然后,有删除sport/old/2012下文件的权限。
- Effect是Allow;
- Action是oss:DeleteObject;
- Resource是acs:oss:::ccav/sport/old/2012/*;
- Condition暂无;
授权语句如下:
{
"Effect": "Allow",
"Action": [
"oss:DeleteObject"
],
"Resource": [
"acs:oss:*:*:ccav/sport/old/2012/*"
],
"Condition": {}
}
最后,2016年12月31号前完成任务后不再拥有该权限。
限制条件语句如下:
"Condition": {
"DateLessThan": {
"acs:CurrentTime": "2016-12-31T23:59:59+08:00"
}
}
列举权限、删除权限、日期限制合并后,最终的授权策略如下:
"Version": "1",
"Statement": [
{
"Effect": "Allow",
"Action": [
"oss:DeleteObject"
],
"Resource": [
"acs:oss:*:*:ccav/sport/old/2012/*"
],
"Condition": {
"DateLessThan": {
"acs:CurrentTime": "2016-12-31T23:59:59+08:00"
}
}
},
{
"Effect": "Allow",
"Action": [
"oss:ListObjects"
],
"Resource": [
"acs:oss:*:*:ccav"
],
"Condition":{
"StringLike":{
"oss:Prefix":"sport/old/2012/*"
},
"DateLessThan": {
"acs:CurrentTime": "2016-12-31T23:59:59+08:00"
}
}
}
]
}
OSS常用的授权策略,请参考 对象存储(OSS)授权 ;
更多进阶的权限策略,请参看 OSS上做RAM主子账号的授权 。
生成OSS授权策略
手写OSS授权策略是件有趣的工作,但是授权策略细致琐碎,人难免会出错嘛。针对OSS的授权策略,请使用自动化生成工具 RAM Policy Editor 完成。该工具是自帮助的哦,可以点击More
或?
查看对应帮助。
生成OSS的授权策略,强烈推荐使用RAM Policy Editor,而不是手工书写。
如果您觉该工具有需要改进的地方,请提建议到 Github。