Amazon Web ServicesCloud

一文搞懂 AWS IAM 权限 基础篇下 实战

环境(配置)


  • AWS 中国或 Global 帐号,可在官网申请,一年内使用指定资源免费
  • AWS cli,Win10 + terminal

实战步骤

1. user


这里我们创建的是 IAM user。

注意:AWS 中国区只有 IAM user 没有 root user

创建 user

用高权限用户登录 AWS,在 AWS 中控台选择“IAM”,进入 IAM 界面,选择“Users”,点击“Add user”

添加 user 名称“tstest1”,选择“AWS Management Console access”,点击“Next:Permissions”

提示:如果是配在 App 中的用户,不需要登录,则可以只选择“Programmatic access”

这里可以给新用户添加 group 和 policy,不过我们先不加 group 和 policy,直接点击“Next:Tags”

加 Tag,点击“Next:Review”

点击“Create user”

创建成功,点击“Close”

测试隐式拒绝

用新建的用户“tstest1”登录 AWS 控制台界面,进入 S3 和 EC2 两个界面观察,可以看到两个服务都没有权限查看

点击右上角用户名,点击“My Security Credentials”,进入“tstest1”用户界面

可以看到因为没有权限,连自己用户的 ARN 都看不到

说明:IAM user “tstest1”没有任何权限(policy)绑定,访问任何 AWS 服务时,被隐式拒绝。

2. policy


policy 有三种类型

  • AWS managed policy: 由 AWS 创建并管理的独立 policy
  • Customer managed policy: 由用户自行创建管理的独立 policy
  • inline policy: 由用户自行创建,只与某个 user,group,role 相绑定的 policy,是这些 user,group,role 的一部分

Customer managed policy 与 inline policy 的主要区别

  • 前者有独立的 ARN 可以绑定到不同的 identity(user,group,role)
  • 后者与特定 identity 相绑定,不能共享,随着 identity 的删除而删除
  • 在提供权限方面两者没有区别

绑定 AWS managed policy

下面我们给“tstest1”用户绑定一个 AWS managed policy

用高权限用户登录 AWS,在 IAM 界面,选择 Users,搜索“tstest1”,然后点击用户名称

点击“Add permissions”

选择“Attach existing policies directly”,搜索“IAM”,勾选“IAMReadOnlyAccess”,点击“Next:Review”

提示:这里勾选完某个 policy 后,再搜索其它的 policy 勾选,之前选择的 policy 还存在

点击“Add permissions”

可以看到 AWS managed policy 已经添加到用户“tstest1”

测试显式允许

这时在“tstest1”登录的界面刷新,已经可以看到自己的 ARN 和其它信息

说明:赋予 IAM 权限后,可以看到 ARN 等信息,显式允许。另外,这个 IAM policy 赋给了用户,所以这个 policy 属于“identity-based policy”

创建 inline policy

下面我们在用户“tstest1”中加一个访问 S3 bucket “tstest”的 inline policy,

用高权限用户登录 AWS,在 IAM 界面,选择 Users,搜索“tstest1”,然后点击用户名称

点击“Add inline policy”

选择 JSON,粘贴如下内容,后点击“Review policy”

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws-cn:s3:::tstest",
                "arn:aws-cn:s3:::tstest/*"
            ]
        }
    ]
}

除了直接粘贴 JSON,我们还可以选择“Visual editor”,这里可以直观的选择需要的服务权限

添加一个 inline policy 名称,点击“Create policy”

成功后可以在用户下看到新的 policy,这个 policy 也是 identity-based policy

创建 Customer managed policy

我们创建一条 Customer managed policy,赋予创建 access key 的权限

在 IAM 界面,选择 Policies,点击“Create policy”

选择 JSON,粘贴如下内容,后点击“Next:Tags”

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "iam:CreateAccessKey",
            "Resource": "arn:aws-cn:iam::XXXX:user/tstest1"
        }
    ]
}

点击“Next:Review”

添加名称“tstest1_custom_policy”,点击“Create policy”

创建成功,然后可以在 policy 搜索中查到此 policy

然后我们用和绑定 AWS managed policy 相同的方法,把 Customer managed policy 绑定到用户“tstest1”上

现在用户“tstest1”上绑定有三种 policy,每种各一个

3. 创建用户 access key


为了下面用 AWS Cli 进行 S3 上传测试,我们先在“tstest1”用户中建一个 access key

用“tstest1”用户登录 AWS,点击右上角用户名,点击“My Security Credentials”,进入“tstest1”用户界面,点击“Create access key”

创建成功,这里需要把 secret 记下来,或者下载.csv,因为这个窗口关闭后,我们就不能在界面上再次查看 secret 的内容

在 AWS Cli 中配置 access key

在本地 AWS CLI 环境中,打开~/.aws/credentials 文件加入以下内容,access_key 和 secret 是上面保存的 csv 文件中的内容

[XXXX:user/tstest1]
output = json
region = cn-north-1
aws_access_key_id = AKIAZEG****
aws_secret_access_key = Ujr3BaQ***gzq

用如下命令检查访问 AWS

export AWS_PROFILE=XXXX:user/tstest1
aws sts get-caller-identity

如果出现如下错误

可以在命令后面加“–no-verify-ssl”解决。(解决此问题详情可参考“AWS CLI SSL: CERTIFICATE_VERIFY_FAILED 错误分析与解决”一文)

访问 AWS 成功

4. identity-based policies 和 resource-based policies

我们用 S3 来测试 identity-based policy

测试 identity-based policy

用户“tstest1”的 identity-based policy(tstest1_inline_policy)中包含下列内容

            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws-cn:s3:::tstest",
                "arn:aws-cn:s3:::tstest/*"
            ]

我们运行命令测试

#列出bucket “tstest”中所有内容
aws s3 ls s3://tstest
#把本地文件a上传到bucket中
aws s3 cp a s3://tstest/a
#把bucket中a文件删除
aws s3 rm s3://tstest/a

可以看到,列出(ListBucket)和上传(PutObject)功能正常,但是删除(DeleteObject)文件时,报 AccessDenied 错,因为用户绑定的三个 policy 里都没有 DeleteObject 权限

创建 S3 resource-based policy

下面我们在 S3 bucket 中加入 resource-based policy 允许用户“tstest1”删除文件

用高权限用户登录 AWS,在 S3 中控台选择“Buckets”,搜索“tstest”,然后点击

选择“Permission”,拉到下面,在“Permission overview”块中,选择“Edit”

粘贴以下内容,点击“Save changes”

{
    "Version": "2012-10-17",
    "Id": "Policy1618883862847",
    "Statement": [
        {
            "Sid": "Stmt1618883859880",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws-cn:iam::XXXX:user/tstest1"
            },
            "Action": "s3:DeleteObject",
            "Resource": "arn:aws-cn:s3:::tstest/*"
        }
    ]
}

说明:这段 policy 允许用户“tstest1”删除 bucket “tstest”中的内容

测试 resource-based policy

现在我们再测试删除动作,可见删除成功

说明:

我们在 tstest1 的 tstest1_inline_policy(identity-based policy)中添加了上传权限,在 S3 bucket policy(resource-based policy)添加了用户删除的权限。

两种 policy 中一起作用,使得用户可以在 S3 中上传下载,总的权限如下图所示

5. identity-based policies 和 permissions boundaries


添加 permissions boundaries

我们在用户“tstest1”中添加 permissions boundary

首先,我们用第二节创建 Customer managed policy 的方法,新建 policy “tstest_permisson_boundary”,只允许列出 bucket

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws-cn:s3:::tstest"
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": "s3:CreateBucket",
            "Resource": "*"
        }
    ]
}

然后,进入“tstest1”用户界面,选择“Permission”,展开“Permissions boundary (not set)”,点击“Set boundary”

搜索新建的“tstest_permisson_boundary”,勾选后点击“Set boundary”

添加完成

测试 permissions boundaries

我们把和用户“tstest1”操作 S3 相关的三种 policy(与 IAM 相关的 policy 没有列出)再列一下,方便说明

  1. 用户绑定的 tstest1_inline_policy(identity-based policy)
            "Action": [
                "s3:PutObject",
                "s3:ListBucket"
            ],
            "Resource": [
                "arn:aws-cn:s3:::tstest",
                "arn:aws-cn:s3:::tstest/*"

说明:允许用户列出 Bucket “tstest”和上传文件

  1. S3 bucket “tstest”的 resource-based policy
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws-cn:iam::XXXX:user/tstest1"
            },
            "Action": "s3:DeleteObject",
            "Resource": "arn:aws-cn:s3:::tstest/*"

说明:bucket “tstest”允许用户删除文件

  1. 用户绑定的 tstest_permisson_boundary(permisson boundary)
{

            "Effect": "Allow",
            "Action": "s3:ListBucket",
            "Resource": "arn:aws-cn:s3:::tstest"
。。。
            "Effect": "Allow",
            "Action": "s3:CreateBucket",
            "Resource": "*"

说明:用户的最高权限是列出 Bucket 和创建任意 Bucket

identity-based policy 与 Permisson boundary 的关系如下图

提示:这个图只列出了 identity-based policy 与 Permisson boundary 的关系。评估顺序中 resource-based policy 优先级比 Permisson boundary 高,所以 Permisson boundary 不会限制 resource-based policy,下面的“删除文件”测试中检验此特性

下面是具体测试结果

  • 列出 Bucket

说明:identity-based policy 中允许列出 Bucket,Permisson boundary 中允许列出 Bucket,所以总权限允许列出,命令执行成功

  • 上传文件

说明:identity-based policy 中允许上传文件,但 Permisson boundary 中没有允许上传文件,超出权限边界,所以总权限拒绝,命令执行失败

  • 删除文件

说明:resource-based policy 中允许用户删除文件,虽然 Permisson boundary 中没有允许删除文件,但是在评估总体权限顺序时,resource-based policy 在 Permisson boundary 之前,当 resource-based policy 允许时,总权限允许,所以命令执行成功。(可参考上一篇“评估 policy 流程”一节)

  • 创建 Bucket

说明:identity-based policy 中没有允许建 Bucket,Permisson boundary 允许建 Bucket,但 Permisson boundary 只是设定权限的边界,并不实际授权,所以总权限拒绝,命令执行失败

总结


IAM 权限管理相对复杂,除非经常配置权限,否则非常容易搞混。

上面这个图清楚地显式了总体权限评估过程,把这个图看明白了,基本上就可以大体掌握 IAM 权限管理了。

引申


  • 绑定在 AWS 资源(Lambda,EC2)上的 Role,在创建和绑定 policy 的方法上与 User 类似,篇幅原因这里就没提。另外之前的每篇文章里几乎都有与 role 相关的权限配置内容
  • Delegation 允许其他用户访问你的 AWS 资源,这个功能非常有用,生产中常用于权限分离管理。把不同的操作人员(dev、admin)的 IAM user 建在另一个 account 下,然后通过 switch role 来管理不同人员使用的权限