Amazon Web ServicesCloud

一文搞懂 AWS IAM 权限 基础篇上 理论

简介


在之前的文章中,我们多次提到赋予权限时需要用 Role,Policy。

事实上在利用 AWS 任何资源之前,都需要为使用者设置相应的权限。AWS 通过 IAM 对资源进行访问控制和权限设置。

本文做为 IAM 的上篇,主要介绍术语,基本概念及权限检证流程。

本文纯理论,实战检验安排在下一篇文章中。

IAM 介绍


IAM 介绍

AWS Identity and Access Management(IAM)负责控制 AWS 资源的访问,通过控制登录用户以及控制用户的权限来实现其功能。

AWS 用户主要分两大类

  • AWS account root user: 第一次注册 AWS 服务时创建的用户,具有对 AWS 所有资源的访问权限。此用户一般不做为平时的工作用户,而只用来管理部分帐号相关的工作,比如 Billing
  • AWS IAM user: 由 root user 创建的用户,用来做平时具体工作,需要赋予需要的权限。做为 AWS 管理员,一般也不会用 root 用户,而是用 IAM user 进行日常工作。

1. 主要元素


下面的元素是在 IAM 的语境下

  • Resources: 在这里指的是 IAM 中的对象,比如 user,group,Role,Policy 等,并不是 AWS EC2/Lambda 这种 AWS 资源
  • Identities: 可以把 policy 赋给的对像,具体指 user,group,Role
  • Entities: 指用来验权的对像,具体指 user,federated user(联合用户)和 assumed IAM roles
  • Principals: 是指利用 root 用户或 IAM user/role 进行登录并请求(Request)使用 AWS 服务的个人或者应用

上面后三个概念很相似,我们举个具体的例子

AWS 管理员小王(Principal)用他的 IAM user 帐号“xiaowang001”(Entity)登录 AWS 控制台。

小王的帐号“xiaowang001”属于 administrator 组(Identity),administrator 组被赋予了“AdministratorAccess”的 policy。

小王的帐号“xiaowang001”即是 Entity 也是 Identity,因为“xiaowang001”即是被验权的对象,也可以被直接赋予 policy。

2. account、user、group、role


account

AWS account 是你拥有所有 AWS 资源的一个容器。

在注册 AWS 帐号时创建了 AWS account,之后所有的操作均在此 account 中进行,对 AWS account 管理的根用户就是 AWS account root user。

AWS 控制台,右上角可以看到当前登录的 IAM user 和 account 信息

user

上面提到了用户分成 AWS account root user 和 IMA user 两大类,下面主要用到的是 IMA user。

IAM user 是一个 entity,具有一个唯一的 Amazon Resource Name (ARN),在下文 policy 的 Principal 中指定的就是 IAM user 的 ARN。

IAM user 既可以是一个具体人的帐号,也可能是 application 用户(用在 AWS API 中的用户)。

IAM user 有两种验证方式来访问 AWS

  • Console password 交互式登录 AWS 界面时输入用户名和密码
  • Access keys 在用户下可以创建 Access key 同时自动生成 secret,Acess Key 用于 AWS Cli 和 AWS API 的场合

新建 IAM user 是没有权限使用 AWS 资源的,这时需要通过下面介绍的 policy 把使用 AWS 资源的权限赋给 IAM user 或相应的 group。

group

group 是 IAM user 的集合,主要功能是集中管理用户权限,通过把 policy 赋给 group 的方式,把权限赋予 group 中的用户。

提示:下文介绍的 resource-based policy 中 Principal 只能指定为 IAM user 不能指定为 group

group 有如下一些特点

  • 一个 group 可以包含多个 user,一个 user 也可以属于多个 group
  • group 中只能包含 user,不能包含 group
  • 没有 default group 包含所有用户

role

IAM role 是一个 IAM identity,与 user 相似,也可以被赋予 policy,但是没有 password。

role 可以被需要的用户、应用或者 AWS 服务代入(assume),通过代入(assume)的方式间接提供权限。

比如,我们在前几篇关于 CICD 的文章中给 Lambda 函数建了 role,role 中加入了调用 Codedeploy 的 policy。Lambda 函数通过代入(assume)这个 role 得到了使用 Codeploy 资源的权限。

role 可以被以下用户、资源使用(assume)

  • 和 role 处在同一个 account 的 IAM user
  • 和 role 处在不同 account 的 IAM user
  • AWS 资源,比如 Lambda,EC2
  • 由外部 IdP(SAML 2.0 or OpenID Connect)授权的外部用户

下面介绍一些和 role 相关的术语

  • AWS service role: AWS 服务代入(assume)的 role,为 AWS 服务提供必要权限。比如上文中给 Lambda 创建的 role
  • AWS service role for an EC2 instance: 一种特殊的 role,赋给 EC2(又称为 EC2 Profile),使运行在 EC2 上的 application 可以从此 role 中获得操作 AWS 资源的权限
  • AWS service-linked role: 这种 role 与 AWS 服务直接相关,由 AWS 服务预先定义好,可由 AWS 服务自动创建,有些可以人为修改,有些则不行,由具体 AWS 服务决定
  • Delegation: 允许其他用户访问你的 AWS 资源。Delegation 涉及到两个 account,拥有 AWS 资源的 trusting account 和想访问 AWS 资源的用户所在的 trusted account

在 trusting account 中(拥有 AWS 资源)

创建 role,绑定 policy 允许访问 AWS 资源,设置 trust relationship 允许 trusted account 中的 user 代入(assume)role

在 trusted account 中(想访问 AWS 资源)

需要给用户绑定一个 policy 允许用户做 switch 或 assume role。

提示:当用户代入 role 后,原用户的权限暂时取消,由 role 中的权限代替。当用户退出 role 后,原用户权限恢复

  1. Federation: 在 AWS 和外部 IdP(identity provider)间建立信任关系后,用户在外部 IdP 验证后,AWS 赋予用户 IAM role 实现操作 AWS 资源,支持 OpenID Connect(OIDC)和 SAML 2.0
  2. Federated user: Federation 中的用户,通过外部 IdP 验证后访问 AWS 资源

3. Request


当 Principal 利用 AWS 控制台界面,AWS API 或者 AWS Cli 对 AWS 服务进行访问/调用时,Principal 发送给 AWS 的信息称为 Request。

Request 包括以下信息

  • Actions or operations:对 AWS 服务的具体操作,比如停止 EC2
  • Resources: 这里是指 AWS 的资源,比如 EC2,S3,不是上面说的 Resources(IAM 中的对象)
  • Principal: 与上面定义的 Principal 相同,是指利用 root 用户或 IAM user/role 进行登录并请求(Request)使用 AWS 服务的个人或者应用
  • Environment data: 包括 Principal 所在的 ip,用户代理,是否 SSL 及发送 request 的时间等
  • Resource data:和想操作的 AWS 资源相关的信息,比如要停的 EC2 的 instaince id 或者 tag

AWS 收到 Request 后,会把这些信息收集起来组成 Request context,用来评估和授权 Request。

4. 鉴权(Authentication)


Authentication 鉴权,是检查你是否有权利发送 Reqeust。

比如,用户登录 AWS 界面,输入 IAM 用户和密码后登录成功,就是 Authentication,说明这个 IAM 用户有权登录 AWS 界面(可以发送 Request)。

当使用 AWS CLi 前,我们要先在 profile 中配置 access key 和 secret key,然后才能使用 AWS CLi 操作 AWS。

通过 AWS CLi 操作 AWS 时,AWS 先验证 access key 和 secret key 的正确性(Authentication),然后才会对 Request 作出响应(有权或者无权)。

5. 授权(Authorizaion)


Authorizaion 授权,是检查你的 Request 被允许还是拒绝,即对 AWS 服务使用的权限。

比如你用 IAM 用户成功登录了 AWS 界面(Authentication 成功),现在你想停掉一个 EC2,AWS 会评估你的用户是否有停掉这个 EC2 的权限,只有被授权了,才能完成这个动作。

下面列出评估一个 Request 是否有权限执行的几个主要原则

  • 默认情况下,所有 Request 都被拒绝,除了用 Root 用户发出的 Request。所有新建的 IAM user,如果没有显式的赋予权限(policy),则此用户除了登录(在创建时选择了 console 登录),什么操作也不能做
  • 只有用户被显示授权,才能进行相应的操作
  • 如果存在 Organizations SCP, IAM permissions boundary, 或者 a session policy 的话,这几项必须全部显式赋权,可以进行相应的操作
  • 如果多个 policy 存在,只要其中一个 policy 中含有拒绝某项操作,则无论其它 policy 中是否存在显式赋权,这项操作都认为是没有权限

6. Policy 和 permission(权限)


AWS 中 permission(权限)通过 policy 赋予用户、组、Role 或者 AWS 资源实现。policy 是 permission 的集合,通常以 Json 文件形式显示。

AWS 中支持 6 种 policy

  • identity-based policies: 赋予给用户、组或者 role 的 policy,指定其对 AWS 资源的使用权限
  • resource-based policies: 赋予给 AWS 资源的 policy,比如赋给 S3 的,用来指定哪些用户可以访问某个 bucket 的 policy
  • permissions boundaries: 赋给用户或者 role 的 policy,用来指定其最大权限,但 permissions boundaries 本身并没有提供允许的权限。它只是限制可用的 identity-based 权限的最大值。

注意:permissions boundaries 对于 resource-based policy 中给用户或 role 提供的权限不做限制

例子:

  1. 用户的 identity-based policy 允许对 S3 进行全部操作,permissions boundaries 的 policy 中只允许用户 list Bucket,则用户只能进行 list bucket 操作
  2. 用户的 identity-based policy 允许对 S3 进行 list Bucket 操作,permissions boundaries 的 policy 中允许用户对 S3 进行全部操作,则用户只能进行 list Bucket 操作
  • Organizations SCPs: AWS Organizations service control policy (SCP) 可以为一个组织的全部帐号或者 OU(organizational unit)设定可用的最大权限,与 permissions boundaries 相似
  • Access control lists: (ACLs)控制其它帐号(AWS account)中的用户访问本帐号资源的 policy,这种 policy 只对其它 account 中的用户有效,对自己 account 中用户无效
  • session policies: 高级 policy,当用 AWS Cli 或者 AWS API 时需要用到 assume role 或者 federated user。session policies 限制了 role 或者用户传递给 session 的权限,与 permissions boundaries 相似,起的是限制作用

7. policy 评估逻辑


当 principal 利用 AWS 控制台、AWS CLi 或者 AWS API 进行操作时,principal 发送 request 到 AWS。

AWS 接到 request 并执行以下步骤,决定是否执行 request

  1. Authentication
  2. Processing the request context
  3. Evaluating policies within a single account
  4. Determining whether a request is allowed or denied within an account

我们重点介绍后两步,当存在多种 policy 时,如何决定最终权限?

评估 identity-based policies 和 resource-based policies

identity-based policies 赋予 user、group 或 role,指定它们是否有操作 AWS 资源的权限。

resource-based policies 赋予 AWS 资源,指定 user、group 或 role 可以对自身的 AWS 资源进行操作。

当存在两种 policy 时,总的允许权限是两种 policy 的中允许权限的和,即只要其中一种 policy 允许一个操作,那么总的权限就是允许这个操作。

对于拒绝权限,只要一种 policy 中存在拒绝权限,则即使另一种 policy 中存在允许权限,总的权限也是拒绝。(拒绝权限高于允许权限)

举个例子

AWS 管理员小王(Principal)的帐号“xiaowang001”(Entity)中存在一个 policy(identity-based policies),这个 policy 只允许小王 Put(上传)S3 “bucket1”。(这里简化起见,先不考虑还要 list bucket 的权限)

S3 “bucket1”的 policy(resource-based policies)只允许小王对“bucket1”中对像进行 delete 操作。

这时小王访问 S3 时,在两种 policy 的作用下,小王既可以上传也可以删除 S3 “bucket1”中的对象。

如果小王的用户的 policy 允许对 S3 “bucket1”做 Put(上传),但 S3 “bucket1”的 policy 中禁止小王的用户 Put(上传),则小王没有上传这个 S3 Bucket 的权限。

评估 identity-based policies 和 permissions boundaries

permissions boundaries 的作用是限制权限,两种 policy 在一起的总权限是两种 policy 权限的交集。

identity-based policies 中定义的权限,如果超出了 permissions boundaries 定义的权限,则超出的部分不起作用。

评估 identity-based policies 和 Organizations SCPs

Organizations SCPs 与 permissions boundaries 类似,两种 policy 在一起的总的允许权限是两种 policy 权限的交集。任一 policy 中存在拒绝权限,则总体权限拒绝。

评估 policy 流程(单 AWS Account 内)

account 内部 policy 权限评估流程如下

说明:

  1. Deny evaluation: 默认所有 request 都是拒绝(隐式拒绝)。AWS 评估所有与 request 相关的 policy(Organizations SCPs, resource-based policies, IAM permissions boundaries, role session policies, and identity-based policies),如果在任一 policy 中发现一条拒绝权限,则这个 request 被拒绝掉(显式拒绝),评估流程终止。如果没有发现显式拒绝,则评估流程继续
  2. Organizations SCPs: 评估流程开始检查 SCP,如果 SCP 中没有发现允许的权限,则 request 被隐式拒绝掉,评估流程终止。如果没有启用 SCP,或者 SCP 中存在允许的权限,则评估流程继续
  3. Resource-based policies: 如果 request 的 AWS 资源存在 Resource-based policies 并且其中存在允许的权限,则 request 允许执行,评估流程结束,如果 Resource-based policies 中没有允许的权限,则评估流程继续
  4. IAM permissions boundaries: AWS 检查 entity(用户、组或 role)是否设置 permissions boundaries。如果其中中没有发现允许的权限,则 request 被隐式拒绝掉,评估流程终止。如果没有启用 permissions boundaries,或者其中存在允许的权限,则评估流程继续
  5. Session policies: AWS 检查用户是否用 AWS CLi 或者 AWS API 启动了 session。如果 session policy 存在并且其中没有发现允许的权限,则 request 被隐式拒绝掉,评估流程终止。如果没有启用 session policy,或者 session policy 中存在允许的权限,则评估流程继续
  6. Identity-based policies: AWS 检查用户及用户所在的组绑定的 policy,如果任一 policy 存在允许的权限,则 request 允许执行,评估流程结束。如果任一 policy 不存在允许的权限,则 request 被隐式拒绝掉,评估流程终止
  7. Errors: 如果 AWS 在评估流程中发生错误,则产生 exception 并中止

8. identity-based policies 和 resource-based policies 例子


identity-based policies 和 resource-based policies 是平时用的最多的 policy。(之前我们文章中配置的全部是 identity-based policies)

以下例子来自 AWS 官网

假设用户 Carlos 有一个 AWS IAM user “carlossalazar”,用户 Carlos 想存文件到 S3 Bucket “carlossalazar-logs”中

AWS IAM user “carlossalazar”中绑定了如下identity-based policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "AllowS3ListRead", #可选项,内容任意写
            "Effect": "Allow", #允许下列动作(操作)
            "Action": [
                "s3:ListAllMyBuckets", #列出S3中所有bucket的动作
                "s3:HeadBucket" #与ListAllMyBuckets配合使用
            ],
            "Resource": "*" #通配符是指所有AWS资源,因为Action中的两个动作都是针对S3的,所以这里就是所有S3的资源
        },
        {
            "Sid": "AllowS3Self",
            "Effect": "Allow",
            "Action": "s3:*", #指对S3的所有动作
            "Resource": [
                "arn:aws:s3:::carlossalazar/*", #AWS资源为S3 Bucket “carlossalazar”中的所有对象
                "arn:aws:s3:::carlossalazar" #AWS资源为S3 Bucket “carlossalazar”
            ]
        },
        {
            "Sid": "DenyS3Logs",
            "Effect": "Deny", #拒绝下列动作
            "Action": "s3:*",
            "Resource": [
                "arn:aws:s3:::*log*", #AWS资源为S3 Bucket名称中包含“log”的所有Bucket
                "arn:aws:s3:::*log*/*" #AWS资源为S3 Bucket名称中包含“log”的所有Bucket中的所有对象
            ]
        }
    ]
}

说明:

  • Sid: 可选项,区分不同的权限语句
  • Effect: 表示允许或者拒绝权限
  • Action: 列出一系列动作(操作)
  • Resource: 对于 identity-based policy,是指可操作的 AWS 资源;对于 resource-based policies 是可选项,没有指定的话,指被绑定这个 policy 的 AWS 资源
  • “AllowS3ListRead”这段语句允许 IAM user “carlossalazar”列出 S3 中的所有 Buckets 名称
  • “AllowS3Self”这段语句允许“carlossalazar”对 S3 Bucket “carlossalazar”做所有操作
  • “The DenyS3Logs”这段语句拒绝“carlossalazar”对 S3 中名称里含有“log”的 Bucket 的任何操作(所以即使“AllowS3ListRead”中允许列出所有 Bucket 名称,实际上“carlossalazar”也看不到含有“log”的 Bucket)

S3 Bucket “carlossalazar”中绑定了如下resource-based policy

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow", #允许
            "Action": "s3:*", #对S3的任何操作
            "Principal": { "AWS": "arn:aws:iam::111122223333:user/carlossalazar" }, #指定动作允许或拒绝的对像是IAM user “carlossalazar”
            "Resource": "*" #AWS资源S3 Bucket “carlossalazar”
        }
    ]
}

说明:

  • Principal 只在 resource-based policy 中出现,指定允许或拒绝的用户,role 或联合用户(federated user)
  • 这段语句允许 IAM user “carlossalazar”对 S3 Bucket “carlossalazar”进行任何动作

现在假设没有 permissions boundaries,用户 Carlos 利用 AWS IAM user “carlossalazar”存文件到 S3 Bucket “carlossalazar-logs”中,评估流程如下

说明:

因为 identity-based policy 中“The DenyS3Logs”这段语句存在显示拒绝,所以评估结果为拒绝,Carlos 无法上传文件到 Bucket “carlossalazar-logs

现在用户 Carlos 发现自己搞错了,实际上是想存文件到 S3 Bucket “carlossalazar”中,评估流程如下

说明:

两种 policy 中都没有拒绝操作,并且存在允许操作,所以用户 Carlos 存文件到 S3 Bucket “carlossalazar”成功

9. 显式拒绝和隐式拒绝


最后再说一下显式拒绝和隐式拒绝的区别。

如果 request 被拒绝是因为评估时用到的任一 policy 中有一条拒绝的语句,这种情况就是显式拒绝

对一种操作,如果 policy 中既存在允许语句,又存在拒绝语句,则拒绝高于允许,最终结果为拒绝。

对一种操作,如果 policy 中既没有允许语句,也没有拒绝语句,则最终结果为拒绝,这种就是隐式拒绝

当设计授权 policy 时,可以综合利用允许、显式拒绝和隐式拒绝

比如可以把下面 identity-based policy 绑定在 Administor group 中,这样所有此 group 下的管理员用户,除了不能访问 billing,有 AWS 的全部权限。

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": "*",
            "Resource": "*"
        },
        {
            "Effect": "Deny",
            "Action": "aws-portal:*",
            "Resource": "*"
        }
    ]
}

可以把下列 polic 赋予给某个用户,让这个用户可以管理用户,但是不能管理 group 和其它 AWS 资源(隐式拒绝)

{
    "Version": "2012-10-17",
    "Statement": {
        "Effect": "Allow",
        "Action": [
            "iam:AttachUserPolicy",
            "iam:CreateUser",
            "iam:DeleteUser",
            "iam:DeleteUserPolicy",
            "iam:DetachUserPolicy",
            "iam:GetUser",
            "iam:GetUserPolicy",
            "iam:ListAttachedUserPolicies",
            "iam:ListUserPolicies",
            "iam:ListUsers",
            "iam:PutUserPolicy",
            "iam:UpdateUser"
        ],
        "Resource": "*"
    }
}

总结


IAM 检查权限的整个过程比较复杂,但是平时使用接触多的一般是 identity-based policy 和 resource-based policy,把这两个弄明白了,基本上可以解决大部分问题。