在 Amazon IAM 上编写用户组和用户授权策略

管理用户和资源访问是云管理员工作的一部分。本教程将介绍一些基本概念,并演示如何使用 Amazon Identity and Access Management (IAM) 服务管理用户访问云资源。
2023 年 8 月 30 日
Amazon IAM
IT 专家
安全
教程
亚马逊云科技
Olawale Olaleye
亚马逊云科技使用经验
200 - 中级
完成所需时间
45 分钟
所需费用

亚马逊云科技免费套餐配额或 1.01 美元

前提条件
上次更新时间
2023 年 8 月 30 日

通过 Amazon Organizations 管理整体资源安全和成本文档中,我们介绍了 Amazon Organizations,这是一种集中管理账单、服务和资源的服务。Amazon Organizations 可以和 Amazon Identity and Access Management (IAM) 结合使用。 Amazon IAM 用于验证和授权组织成员。Amazon Organizations 与 Amazon IAM 的区别在于:Amazon Organizations 可以实现对服务和资源的全局限制,而 Amazon IAM 可以进行账户身份验证并实现细化权限管理。本教程将介绍 Identity and Access Management 服务,如何创建用户和用户组以及如何使用策略分配资源权限。

学习内容

  • 账户安全最佳实践
  • 什么是亚马逊云科技身份和策略?
  • 如何编写和应用策略控制资源访问?

前提条件

本文将介绍 Amazon Identity and Access Management (IAM)。亚马逊云科技服务和资源的访问和权限管理较为复杂,因为可以在不同的组织级别创建策略,且策略可能重叠和交叉。我们先讨论管理账户的最佳实践,然后介绍 IAM 服务。我们首先介绍 IAM 的主要概念,以建立术语基础及其相互关系。

账户安全最佳实践

如果您是您的组织的亚马逊云科技账户的管理员或管理员之一,负责管理资源以及资源访问权限。管理员的首要任务都是采用最佳方式确保组织账户安全。您需要采取以下措施来尽可能减少恶意攻击造成的数据泄露和资源滥用。

  1. 责任共担。创建包含主要联系人和备用联系人的亚马逊云科技管理员电子邮件通讯组。通过群组通知消除单点故障的影响,并增加添加和删除管理员的灵活性。此外,创建运营、安全通知和账单相关通知的电子邮件列表。
  2. 亚马逊云科技账户的根用户具有完全访问权限。为了保护账户安全,创建 IAM 用户用于日常操作,尽量减少使用根用户。
  3. 尽可能使用联合身份。使用 Active Directory、Okta 或 Amazon IAM Identity Center 等集中身份提供者平台管理用户账户。如果您的组织没有身份提供者解决方案,可以直接使用 IAM 创建用户账户。但建议您尽量少创建,因为 IAM 用户凭证都是不会过期的长期凭证。
  4. 使用多因素身份验证 (MFA)。设备需要响应身份验证调用请求才能完成登录。为根用户或 IAM 用户账户等长期凭证启用 MFA。
  5. 使用强密码策略,以抵御暴力破解或社会工程攻击。
  6. 使用 Amazon CloudTrail 记录事件日志以便对使用情况进行审计。

这些是保护亚马逊云科技账户安全的部分重要做法。请务必查看 Amazon Startup Security Baseline,了解更多信息。

身份

身份是提供亚马逊云科技账户以及相关服务和资源访问权限的基础。亚马逊云科技账户可以访问所有资源。IAM 用户(简称用户)是指具有特定资源访问权限的人员或应用程序。用户具有密码和访问密钥等长期凭证,能够永久访问指定的资源。

用户可以属于一个组。组是用户的逻辑集合。例如,您可以为会计部门设置一个账单用户组,以便他们可以监控费用和使用情况。使用用户组可以帮助您简化用户权限管理。

角色是具有特定权限的身份,但角色本身不与某个用户关联。角色具有临时性,用户可以担任通过担任角色来以执行任务。角色的一个常见用途是跨账户访问,即允许另一个账户用户访问您账户中的资源,例如,您是数据库管理员,但是运营团队的工程师需要根据备份还原数据库。在这种情况下,您可以授予这个工程师担任数据库管理员角色,以访问 S3 存储桶中的备份,并使用备份还原数据库。

上图展示了用户组、用户和角色之间的关系。策略可以添加到身份上。用户可以属于某个组,并继承该组的策略。用户是具有密码和访问密钥的长期凭证,因此用户是永久身份。此外,用户可以担任附加了策略的角色,以访问策略指定的资源。角色具有临时性,由用户担任以执行特定任务。本文简要介绍了身份之间的基本关系。有关更多信息,请参见《用户指南》。《用户指南》对 IAM 身份(用户、用户组和角色)进行了深入讨论。

IAM 策略相关概念

IAM 策略是指定可以访问哪些资源、谁可以访问以及在何种条件下访问的文档。与任何配置文档一样,各个部分和操作都有特定的术语加以描述:

  • Sid:Sid(即,语句 ID)是策略语句的一种标识符,是描述性的驼峰式的语句名称。
  • 主体:主体可以是请求访问亚马逊云科技资源执行操作的人员或角色。
  • 身份验证:亚马逊云科技支持三种身份验证,验证请求使用云资源的主体身份。
    1. IAM 用户可以通过提供账户 ID、用户名和密码进行身份验证。此外,最好在登录时使用 MFA。
    2. 联合用户是指使用 Amazon、Facebook、Google 或 Microsoft Active Directory 等身份提供者提供的身份登录亚马逊云科技。
    3. 您可以以根用户身份登录(不推荐),但务必使用多因素验证和临时凭证来保护账户安全。
  • 请求:当您使用 Amazon CLI、亚马逊云科技管理控制台或 Amazon API 时,会向对应的服务发送 Amazon API 调用请求。API 调用请求中包含要对资源执行的操作。请求 context 中包括谁发出了请求(主体)、IP 地址等环境数据和标签等资源数据。
  • 资源:资源是服务中的对象,例如,存储桶是 S3 中的资源。
  • 操作:操作是可以对资源执行的操作,操作类型根据资源定义。例如,S3 具有 CreateBucket 操作。

策略剖析

IAM 策略是附加到资源上的文档,其定义了主体可以对指定资源执行的操作。请求发送到对应的服务上后,服务评估请求,并确定是允许还是拒绝该请求。IAM 策略通常通过 JSON 文档定义。策略语法:

{
 "Version": "version"
 "Statement":[{
 "Effect":"effect",
 "Action":"action",
 "Resource":"arn",
 "Condition":{
 "condition":{
 "key":"value"
 }
 }
 }
 ]
}

一个策略可以包含一条或多条语句。语句中包含:

  • Effect:可选值为 Allow 或 Deny。默认策略为拒绝所有请求,但显式允许策略会覆盖默认策略。反之,显式拒绝策略会覆盖所有允许策略。
  • Action:特定于服务的操作。指被允许或拒绝的操作。
  • Resource:资源是服务中的对象。请求中指定的操作对象资源。
  • Condition:条件是可选项。可以根据条件值触发 effect 定义的效果。亚马逊云科技定义了几个通用条件,各服务也有本身定义的条件。

以下是一个指定特定用户访问 S3 存储桶的策略。

{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Sid": "AllowRootAndHomeListingOfCompanyBucket",
 "Principal": {
 "AWS": [
 "arn:aws:iam::111122223333:user/JohnDoe"
 ]
 },
 "Effect": "Allow",
 "Action": ["s3:ListBucket"],
 "Resource": ["arn:aws:s3:::DOC-EXAMPLE-BUCKET"],
 "Condition": {
 "StringEquals": {
 "s3:prefix": ["", "home/", "home/JohnDoe"],
 "s3:delimiter": ["/"]
 }
 }
 },
 {
 "Sid": "AllowListingOfUserFolder",
 "Principal": {
 "AWS": [
 "arn:aws:iam::111122223333:user/JohnDoe"
 ]
 },
 "Action": ["s3:ListBucket"],
 "Effect": "Allow",
 "Resource": ["arn:aws:s3:::DOC-EXAMPLE-BUCKET"],
 "Condition": {
 "StringLike": {
 "s3:prefix": ["home/JohnDoe/*"]
 }
 }
 },
 {
 "Sid": "AllowAllS3ActionsInUserFolder",
 "Effect": "Allow",
 "Principal": {
 "AWS": [
 "arn:aws:iam::111122223333:user/JohnDoe"
 ]
 },
 "Action": ["s3:*"],
 "Resource": ["arn:aws:s3:::DOC-EXAMPLE-BUCKET/home/JohnDoe/*"]
 }
 ]
}

此策略包含多条语句,但这些语句都应用于特定用户 JohnDoe。第一条语句允许主体查询 S3 资源根目录和主目录中的存储桶。第二条语句允许主体查询路径为 home/JohnDoe/* 的主目录中的对象。

该策略遵循最低权限原则(即,完成任务所需的最小权限)。第一条语句只允许主体查询所拥有的存储桶。第二条语句只允许查询主体所拥有的存储桶中的对象。最后一条语句允许主体在主目录中请求任何操作。

实践操作

下面将所学知识付诸实践。我们将创建 IAM 用户、创建 S3 存储桶作为资源、创建用户组并创建策略以实现控制访问。这些操作都可以在亚马逊云科技管理控制台上完成,但我们将使用 Amazon CLI 来完成,以便您可以直观了解该过程。

步骤 1:运行以下命令创建两个 IAM 用户:

aws iam create-user --user-name yeemin
aws iam create-user --user-name alicia

为这两个用户授予亚马逊云科技管理控制台的访问权限。在此实验中,我们将设置密码,并且不要求在首次登录时重置密码。但是,在实际使用中,最好要求用户在首次登录时重置密码。注意:IAM 用户凭证是永久性凭证。

aws iam create-login-profile --user-name yeemin --password pcgUser#1 --no-password-reset-required
aws iam create-login-profile --user-name alicia --password pcgUser#2 --no-password-reset-required

接下来,创建用户组,并将用户添加到该组:

aws iam create-group —group-name pcg-experts
aws iam add-user-to-group --user-name yeemin --group-name pcg-experts
aws iam add-user-to-group --user-name alicia --group-name pcg-experts

IAM 用户是在主账户下创建的。要使用 IAM 用户要登录控制台,需要使用包含主账户 ID 的 URL。如果您不知道账户 ID,可以使用以下命令查询:

aws sts get-caller-identity

{
"UserId": "AI334FYWB3ZZKE53QA4OP",
"Account": "123456789101",
"Arn": "arn:aws:iam::123456789101:user/default"
}

例如,账户 ID 是 123456789101。IAM 用户使用的登录地址 URL 格式是 https://<account id>.signin.aws.amazon.com/console,例如,https://123456789101.signin.aws.amazon.com/console。

如果您现在以其中的任何一个用户身份登录,您都不能访问任何资源,因为用户还没有任何权限。

步骤 2:创建一个资源。我们将创建一个 S3 存储桶,并在存储桶中存入几个文件夹和文件。请注意,S3 存储桶的名称必须唯一。请务必将以下命令中的 my-unique-bucket-name 替换为您的存储桶名称。

aws s3api create-bucket --bucket my-unique-bucket-name --region us-east-1

接下来,我们将在本地创建文件夹和文件,并将存入存储桶。在您的计算机上创建一个目录,进入该目录,然后运行以下命令:

mkdir Development/ Finance/ Private/
touch ./Development/project1.xls ./Development/project2.xls
touch ./Finance/Tax2023/document1.pdf ./Finance/Tax2023/document2.pdf
touch ./Private/privDoc1.pdf ./Private/privDoc2.pdf
touch s3-info.txt

使用 Amazon CLI,运行 put-object 命令,将目录和文件复制到 S3 存储桶。请务必将 my-unique-bucket-name 替换为您的存储桶名称。

aws s3api put-object --bucket my-unique-bucket-name --key Development/project1.xls
aws s3api put-object --bucket my-unique-bucket-name --key Development/project1.xls
aws s3api put-object --bucket my-unique-bucket-name --key Development/project2.xls
aws s3api put-object --bucket my-unique-bucket-name --key Finance/Tax2023/document1.pdf
aws s3api put-object --bucket my-unique-bucket-name --key Finance/Tax2023/document2.pdf
aws s3api put-object --bucket my-unique-bucket-name --key Private/privDoc2.txt
aws s3api put-object --bucket my-unique-bucket-name --key Private/privDoc1.txt
aws s3api put-object --bucket my-unique-bucket-name --key s3-dg.pdf

步骤 3:创建策略。我们已经创建了两个用户、一个用户组和一个 S3 存储桶,下面将创建第一个策略。第一个策略允许查询账户根目录下的所有存储桶:

{
 "Version": "2012-10-17",
 "Statement": [
 {
 "Sid": "AllowGroupToSeeBucketListInTheConsole",
 "Action": ["s3:ListAllMyBuckets"],
 "Effect": "Allow",
 "Resource": ["arn:aws:s3:::*"]
 }
 ]
}

将该策略复制到文本编辑器中,并将其保存为 GroupPolicy.json。运行以下命令创建该策略:

aws iam create-policy --policy-name GroupPolicy --policy-document file://GroupPolicy.json
{
 "Policy": 
 {
 "PolicyName": "GroupPolicy",
 "PolicyId": "ANPA4XYZU3UAF7HXTVH43",
 "Arn": "arn:aws:iam::123456789101:policy/GroupPolicy",
 "Path": "/",
 "DefaultVersionId": "v1",
 "AttachmentCount": 0,
 "PermissionsBoundaryUsageCount": 0,
 "IsAttachable": true,
 "CreateDate": "2023-08-09T01:04:51+00:00",
 "UpdateDate": "2023-08-09T01:04:51+00:00"
 }
}

运行以下命令将该策略附加到用户组:

aws iam attach-group-policy --policy-arn arn:aws:iam::123456789101:policy/GroupPolicy --group-name pcg-experts 

以 Yeemin 身份登录,测试该策略。在浏览器的地址栏中,输入您的登录 URL(https://.signin.aws.amazon.com/console)。

在亚马逊云科技管理控制台中,选择 S3。

S3 控制台页面上将显示属于主账户的所有存储桶,包括刚才创建的存储桶。但是,此时该用户没有权限访问存储桶。如果您选择存储桶并尝试打开,将显示收到以下报错消息:Insufficient permissions to list objects。

步骤 4:更新用户组策略,允许所有用户查看存储桶根目录下的文件夹和对象。将以下语句添加到策略定义中。请注意,resource 指定的是之前创建的存储桶,并且添加了一个条件,满足该条件才会列出存储桶中的对象。
{
 "Sid": "AllowRootLevelListingOfBucket",
 "Action": ["s3:ListBucket"],
 "Effect": "Allow",
 "Resource": ["arn:aws:s3:::<my-unique-bucket-name>"],
 "Condition":{ 
 "StringEquals":{
 "s3:prefix":[""], "s3:delimiter":["/"]
 }
 }
}

将该语句添加到 GroupPolicy.json 文件并保存该文件。更新后的策略如下所示:

{
 "Version": "2012-10-17", 
 "Statement": [
 {
 "Sid": "AllowGroupToSeeBucketListAndAlsoAllowGetBucketLocationRequiredForListBucket",
 "Action": [ "s3:ListAllMyBuckets", "s3:GetBucketLocation" ],
 "Effect": "Allow",
 "Resource": [ "arn:aws:s3:::*" ]
 },
 {
 "Sid": "AllowRootLevelListingOfBucket",
 "Action": ["s3:ListBucket"],
 "Effect": "Allow",
 "Resource": ["arn:aws:s3:::<my-unique-bucket-name>"],
 "Condition":{ 
 "StringEquals":{
 "s3:prefix":[""], "s3:delimiter":["/"]
 }
 }
 }
 ] 
}

接下来,更新策略并创建新版本。更新后的策略将成为默认策略,IAM 将保留该策略以前的版本。

aws iam create-policy-version --policy-arn arn:aws:iam::123456789010:policy/GroupPolicy --policy-document file://GroupPolicy.json --set-as-default

返回浏览器,进入以 Yeemin 身份登录并打开的 S3 控制台页面。现在,您就可以查看存储桶根目录的文件夹和对象。

尽管组中的所有用户都可以查看存储桶根目录下的内容,但无法查看文件夹中的对象。在下一步中,我们将为用户定义一个策略,允许他们在文件夹中查看、获取和存入对象。

步骤 5:例如,Alicia 是一名开发人员,工作中需要访问 Development 文件夹。为此,我们将创建一个内联策略。一个内联策略只能绑定一个 IAM 身份,该身份可以是用户、组或角色。身份和内联策略之间是严格的一对一关系。

Alicia 需要查看存储桶和 Development 文件夹中的对象。此外,她还必须能够从 Development 文件夹中获取对象和存入对象。不过,她在工作中不需要访问其他文件夹。以下第一条策略语句中,使用 "s3:prefix":[“Development/*”] 作为条件,允许 Alicia 查看包含 Development 文件夹的存储桶,而没有允许查看其他文件夹。第二条语句允许在 Development 文件夹中查看、存入和获取对象。

复制该策略,并保存为 AliciaDevPolicy.json(请务必替换存储桶名称)。

{
 "Version": "2012-10-17",
 "Statement":[
 {
 "Sid":"AllowListBucketIfSpecificPrefixIsIncludedInRequest",
 "Action":["s3:ListBucket"],
 "Effect":"Allow",
 "Resource":["arn:aws:s3:::your-unique-bucket-name"],
 "Condition":{
 "StringLike":{"s3:prefix":["Development/*"]
 }
 }
 },
 {
 "Sid":"AllowUserToReadWriteObjectDataInDevelopmentFolder", 
 "Action":["S3:ListObject","s3:GetObject", "s3:PutObject"],
 "Effect":"Allow",
 "Resource":["arn:aws:s3:::your-unique-bucket-name/Development/*"]
 }
 ]
}

运行以下命令将该策略与 S3 存储桶绑定:

aws iam put-user-policy --user-name alicia --policy-name AliciaDevPolicy --policy-document file://A1liciaDevPolicy.json

按照前面以 Yeemin 身份所执行的登录操作步骤,以 Alicia 身份登录亚马逊云科技管理控制台。

进入 S3 控制台,选择存储桶,然后选择 Development 文件夹。您可以看到 Alicia 可以在 Development 文件夹中查看、获取和存入文件对象。

但是,如果尝试以 Alicia 身份打开 Finance 文件夹,您将收到 Insufficient permissions 错误消息。

清理资源

为了避免产生额外费用,需要及时清除本试验过程创建的 S3 存储桶、用户、用户组和策略。

首先,删除附加到 Alicia 用户的内联策略。

aws iam delete-user-policy --user-name alicia --policy-name AliciaDevPolicy

删除用户组的授权策略。需要执行的步骤:必须先将策略与组分离。请注意,这需要策略 ARN,其格式为 arn:aws:iam:::policy/policy-name。

aws iam detach-group-policy --group-name pcg-experts --policy-arn arn:aws:iam::123456789010:policy/GroupPolicy

由于我们启用了版本控制,因此删除默认策略之前必须先删除以前的版本。

aws iam delete-policy-version --policy-arn arn:aws:iam::837028011264:policy/GroupPolicy --version-id v1
aws iam delete-policy --policy-arn arn:aws:iam::123456789010:policy/GroupPolicy

删除用户。需要执行的步骤:首先,必须将用户从组中移除。然后,删除其登录配置文件。最后,删除 IAM 身份。

aws iam remove-user-from-group --group-name pcg-experts --user-name yeemin
aws iam remove-user-from-group --group-name pcg-experts --user-name alicia
aws iam delete-login-profile --user-name yeemin
aws iam delete-login-profile --user-name alicia
aws iam delete-user --user-name yeemin
aws iam delete-user --user-name alicia

接下来,删除组。

aws iam delete-group --group-name pcg-experts

最后,删除 S3 存储桶。由于我们没有为存储桶启用版本控制,因此可以使用 —force 参数删除存储桶及其包含的内容。请注意,为了方便,示例中我们使用了更高级别的 s3 rb 命令删除存储桶。但是,s3api 不支持 --force 参数,所以如果使用 s3api,需要先删除存储桶中的对象。

aws s3 rb s3://your-unique-bucket-name —force

总结

我们创建了两种策略。第一个策略是一个客户管理型策略,应用于组,进而应用于该组的所有成员。我们使用了 S3 作为示例资源,但其他亚马逊云科技资源也适用,例如,Amazon EC2。此策略是一对多策略,即该策略可以应用于多个 IAM 身份。与该策略绑定的任何用户都可以查看根账户下的 S3 存储桶和 S3 存储桶根目录中的内容。

第二个策略是一个内联策略。策略和 IAM 身份之间必须是一对一关系。在示例中,我们将该策略附加到了 IAM 用户 Alicia,因此该用户可以访问指定文件夹。请注意,IAM 身份可以是个用户、用户组或角色。如果您有多位开发人员,可以创建一个开发人员组,将用户添加到该组,并使用 attach-group-policy 命令将策略附加到该组。这样,该组中的每个成员都可以访问 Developers 文件夹。

后续步骤

我们讨论了很多主题,从保护亚马逊云科技账户安全的方法,到身份概念及其相互关系,我们还探讨了策略的结构。为了在实际使用场景中了解 IAM 服务,我们练习了创建组和用户,并且练习了创建访问授权策略。但是,我们没有探讨如何使用角色和临时凭证跨账户访问资源。在下一篇文章中,我们将介绍如何使用 IAM 角色

在《实用云指南》的下一篇文章发布之前,可以登录 Amazon Skill Builder,观看 Amazon Identity and Access Management 简介这个短视频。Skill Builder 上提供了大量的培训和认证视频及教程;其中许多都可以免费观看。