QCon 演讲火热征集中,快来分享技术实践与洞见! 了解详情
写点什么

如何将亚马逊 AWS S3 存储桶的访问权限到一个特定 IAM 角色

  • 2019-10-23
  • 本文字数:6626 字

    阅读完需:约 22 分钟

如何将亚马逊 AWS S3 存储桶的访问权限到一个特定 IAM 角色

译自 Chris Craig 发布在 AWS 英文官方博客的文章 | 我是 AWS 的一名云支持工程师,客户经常问我如何将 Amazon S3 存储桶访问权限限制到特定的 AWS Identity and Access Management (IAM) 角色。通常,他们会尝试以对待 IAM 用户的相同方式执行此操作:使用存储桶策略显式 Deny 不想授予访问权限的所有 Principals(用户和角色)。这种方法的缺点是需要维护存储桶策略。如果将一个新的 IAM 用户添加到账户,并且其 Action 为 “s3:*”,则该用户将获得访问该存储桶的权限。您可以反转逻辑并在存储桶策略的 Deny 语句中利用 NotPrincipal 元素,而不必指定要阻止其访问的用户列表。此元素会为其值中未列出的任何用户创建一个显式的 Deny。


但事实证明,这种反转逻辑的方法在处理 IAM 角色时存在问题,因为这种角色的 Principal 值包含两个 Amazon 资源名称 (ARN),即 role ARN 和 assumed-role ARN。 role ARN 是 IAM 角色本身的标识符, assumed-role ARN 则用于标识日志中的角色会话。在使用 NotPrincipal 元素时,您必须同时包含两个 ARN,此方法才能正常工作,其中第二个 ARN 应包含一个变量名称。通常,您应指定一个通配符,用于表示变量字符串,但不允许在 Principal 或 NotPrincipal 元素中指定此通配符。在本博文中,我会向您展示如何使用 Conditions(而非 NotPrincipal 元素),将 S3 存储桶的访问权限限制到一个账户内的特定 IAM 角色或用户。即便相同账户中的另一个用户拥有 Admin 策略或带有 s3:* 的策略,只要未被显式列出,也同样会被拒绝。例如,您可以使用此方法配置存储桶,以供 Auto Scaling 组内的实例访问。您还可以使用此方法,限制对具有高级别安全需求的存储桶的访问。

解决方案概述

本文所述的解决方案使用存储桶策略来管理对 S3 存储桶的访问 – 即使实体可以访问完整的 S3 API。下图展示了此解决方案如何应用于同一账户内的存储桶。


展示此解决方案如何应用于同一账户内的存储桶的图解


  1. IAM 用户的策略和角色的用户策略授予对 “s3:*” 的访问权限。

  2. S3 存储桶策略将访问权限限制为仅限该角色。

  3. IAM 用户和角色都可以访问该账户中的存储桶。该角色可以访问这两个存储桶,但用户只能访问没有附加存储桶策略的存储桶。即使角色和用户都拥有完整的 “s3:*” 权限,存储桶策略仍会拒绝任何不具有该角色的人员访问该存储桶。


跨账户方法的主要不同之处在于,每个存储桶必须附加存储桶策略。下图展示了这种方法如何应用于跨账户部署场景。


展示此解决方案如何应用于跨账户部署场景的图解


  1. IAM 角色的用户策略和存储桶账户中的 IAM 用户策略均授予对“s3:*”的访问权限

  2. 如果任何人的 user:id 与角色的相应值不同,并且策略定义了允许角色对存储桶执行哪些操作,则存储桶策略会拒绝其访问。

  3. 存储桶策略允许从其他账户访问角色。

  4. IAM 用户和角色可以在存储桶策略中没有 Deny 的情况下访问存储桶。角色可以同时访问这两个存储桶,因为 Deny 仅适用于其 user:id 不等于角色的相应值的主体。

了解 NotPrincipal 元素及其用法

您可以使用 IAM 或 S3 存储桶策略的 NotPrincipal 元素,仅限特定用户组访问资源。此元素允许您阻止未在其值数组中定义的所有用户,即使他们自己的 IAM 用户策略中具有 Allow 也是如此。因此,如果您有一个用户应该可以访问除 S3 中的某个存储桶以外的所有存储桶,则可以在该存储桶本身上进行此定义,而无需编辑用户的 IAM 策略堆栈。


但对于 IAM 角色来说,这要更为复杂,因为角色是由 Principal 中的两个 ARN 定义的:role ARN 和 assumed-role ARN。role ARN (arn:aws:iam::ACCOUNTNUMBER:role/ROLE-NAME) 是静态的,独立于角色会话发起者。(在本文中,切记将 placeholder information 替换为您自己的账户信息。)assumed-role ARN (arn:aws:sts::ACCOUNTNUMBER:assumed-role/ROLE-NAME/ROLE-SESSION-NAME) 将因为角色会话名称定义的内容而异。对于具有一个角色的用户发出的 API 调用,您可以通过查看 AWS CloudTrail 条目中的以下 Identity 元素来了解此信息。


{  "type": "AssumedRole",  "principalId": "**AROAJI4AVVEXAMPLE:ROLE-SESSION-NAME**",  "arn": "arn:aws:sts::**ACCOUNTNUMBER:assumed-role/ROLE-NAME/ROLE-SESSION-NAME**",  "accountId": "**ACCOUNTNUMBER**",  "accessKeyId": "**ASIAEXAMPLEKEY**",  "sessionContext": {    "attributes": {      "mfaAuthenticated": "false",      "creationDate": "XXXX-XX-XXTXX:XX:XXZ"    },    "sessionIssuer": {      "type": "Role",      "principalId": "**AROAJI4AVV3EXAMPLEID**",      "arn": "arn:aws:iam::**ACCOUNTNUMBER:role/ROLE-NAME**",      "accountId": "**ACCOUNTNUBMER**",      "userName": "**ROLE-SESSION-NAME**"    }  }}
复制代码


在此 Identity 元素中,您可以看到 role ARN 和 assumed-role ARN。根据承担角色的用户不同,ROLE-SESSION-NAME 也可能会有所变化。principalId 值也包含此信息,但采用可以在存储桶策略的 Principal 元素以外使用的方式设置格式。在编写存储桶策略时,我会使用这些信息。

向特定角色授予同账户存储桶访问权限

在从同一账户访问存储桶时,在大多数情况下不必使用存储桶策略。这是因为存储桶策略定义了已由用户的直接 IAM 策略授予的访问权限。S3 存储桶策略通常用于跨账户访问,但您也可以使用它们,通过显式 Deny 来限制访问,这将应用于所有主体,无论是与存储桶位于相同账户中还是不同账户中的主体。


每个 IAM 实体(用户、组或角色)都有一个已定义的 aws:userid 变量。您需要在存储桶策略中使用此变量,才能在条件元素内以例外的形式指定角色或用户。assumed-role 的 aws:userId 值定义为 UNIQUE-ROLE-ID:ROLE-SESSION-NAME(例如 AROAEXAMPLEID:userdefinedsessionname)。


要获得 IAM 角色的 AROAEXAMPLEID,请执行以下操作:


  1. 务必安装 AWS CLI,并打开一个命令提示符或 shell。

  2. 运行以下命令:aws iam get-role -–role-name ROLE-NAME

  3. 在输出中,查找以 AROA 开头的 RoleId 字符串。您将在存储桶策略中使用它来将存储桶访问权限的范围仅限于此角色。


在前述 CloudTrail 代码示例中,此 ID 为 principalId 元素。此元素的值十分重要,因为 AWS 策略变量也可以在 IAM 策略中作为字符串进行检查。您不必在 NotPrincipal 元素中指定 role 和 assumed-role ARN,而是可以将 StringNotLike 条件中的 aws:userId 值与通配符字符串一起使用。在 aws:userId 值内,您还需要添加账户的 Root 用户,以便在删除定义的角色时,不会致使存储桶完全无法访问。Root 账户的 userId 是账户编号。


使用您刚刚通过 AWS CLI 检索的 AROAEXAMPLEID,即可创建条件逻辑,让存储桶策略将存储桶访问权限的范围仅限于访问存储桶时使用此角色的用户。使用条件逻辑而非 NotPrincipal 元素可支持使用通配符字符串,从而允许接受任何角色会话名称。


现在您已获得要允许其访问的角色 ID,接下来需要阻止与存储桶处于相同账户内的其他用户的访问。阻止未使用 IAM 角色或 Root 账户凭证的用户访问存储桶及其对象的策略如下所示。


{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Deny",      "Principal": "*",      "Action": "s3:*",      "Resource": [        "arn:aws:s3:::**MyExampleBucket**",        "arn:aws:s3:::**MyExampleBucket**/*"      ],      "Condition": {        "StringNotLike": {          "aws:userId": [            "**AROAEXAMPLEID:***",            "**111111111111**"          ]        }      }    }  ]}
复制代码


您也可以对 IAM 用户使用相同的策略。IAM 用户拥有一个以 AIDA 开头的唯一 ID,您可以将此 ID 用于此用途。要查找此唯一 ID,请执行以下操作:


  1. 安装 AWS CLI 后,打开命令提示符或 shell。

  2. 运行命令:aws iam get-user -–user-name USER-NAME

  3. 在输出中,查找以 AIDAEXAMPLEID 开头的 userId 字符串。


找到 userId 字符串之后,您可以将其置于“aws:userId”条件数组中,如以下示例所示。


{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Deny",      "Principal": "*",      "Action": "s3:*",      "Resource": [        "arn:aws:s3:::**MyExampleBucket**",        "arn:aws:s3:::**MyExampleBucket**/*"      ],      "Condition": {        "StringNotLike": {          "aws:userId": [            "**AROAEXAMPLEID:***",            "**AIDAEXAMPLEID**",            "**111111111111**"          ]        }      }    }  ]}
复制代码

向特定 IAM 角色授予跨账户存储桶访问权限

在上一节中,我向您展示了如何将 S3 存储桶访问权限限于同一个账户内的特定 IAM 角色或用户。现在,我将向您展示如何将访问权限限制到另一账户中的特定用户和角色。向 IAM 用户或角色授予跨账户存储桶访问权限时,您必须定义允许 IAM 用户或角色通过该访问权限执行哪些操作。在先前的 AWS 安全性博客中,Jim Scharf 撰文介绍了允许 IAM 实体通过 CLI/API 和控制台访问存储桶所需的权限。利用之前这篇博文中提供的信息,CLI/API 级访问存储桶策略应如下所示。


{    "Version": "2012-10-17",    "Statement": [        {            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::**111111111111**:role/**ROLENAME**"            },            "Action": "s3:ListBucket",            "Resource": "arn:aws:s3:::**MyExampleBucket**"        },        {            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::**111111111111**:role/**ROLENAME**"            },            "Action": [                "s3:GetObject",                "s3:PutObject",                "s3:DeleteObject"            ],            "Resource": "arn:aws:s3:::**MyExampleBucket**/*"        },        {            "Effect": "Deny",            "Principal": "*",            "Action": "s3:*",            "Resource": [                "arn:aws:s3:::**MyExampleBucket**",                "arn:aws:s3:::**MyExampleBucket**/*"            ],            "Condition": {                "StringNotLike": {                    "aws:userId": [                        "**AROAEXAMPLEID**:*",                        "**111111111111**"                    ]                }            }        }    ]}
复制代码


以下策略显示了控制台级访问所需的服务操作,例如与控制台的 IAM 切换角色功能配合使用的操作。


{    "Version": "2012-10-17",    "Statement": [        {            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::**111111111111**:role/**ROLENAME**"            },            "Action": [                "s3:ListAllMyBuckets",                "s3:GetBucketLocation"            ],            "Resource": "*"        },        {            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::**111111111111**:role/**ROLENAME**"            },            "Action": "s3:ListBucket",            "Resource": "arn:aws:s3:::**MyExampleBucket**"        },        {            "Effect": "Allow",            "Principal": {                "AWS": "arn:aws:iam::**111111111111**:role/**ROLENAME**"            },            "Action": [                "s3:GetObject",                "s3:PutObject",                "s3:DeleteObject"            ],            "Resource": "arn:aws:s3:::**MyExampleBucket**/*"        },        {            "Effect": "Deny",            "Principal": "*",            "Action": "s3:*",            "Resource": [                "arn:aws:s3:::**MyExampleBucket**",                "arn:aws:s3:::**MyExampleBucket**/*"            ],            "Condition": {                "StringNotLike": {                    "aws:userId": [                        "**AROAEXAMPLEID**:*",                        "**111111111111**"                    ]                }            }        }    ]}
复制代码


要向其他账户中的 IAM 用户授予 API/CLI 访问权限,您需要将 IAM 用户的 AIDAEXAMPLEID 添加到“aws:userId”条件,就像我们上一节所做的那样。除了“aws:userId”条件之外,您还需要将 IAM 用户的完整 ARN 添加到这些策略的 Principal 元素。请注意,您不能向 IAM 用户授予跨账户控制台访问权限,因为该用户需要具备目标账户中的角色,但您可以通过 API/CLI 授予对存储桶的访问权限。具体如下所示。


{    "Version": "2012-10-17",    "Statement": [        {            "Effect": "Allow",            "Principal": [                {                    "AWS": [                        "arn:aws:iam::**222222222222**:role/**ROLENAME**",                        "arn:aws:iam::**222222222222**:user/**USERNAME**"                    ]                }            ],            "Action": "s3:ListBucket",            "Resource": "arn:aws:s3:::**MyExampleBucket**"        },        {            "Effect": "Allow",            "Principal": [                {                    "AWS": [                        "arn:aws:iam::**222222222222**:role/**ROLENAME**",                        "arn:aws:iam::**222222222222**:user/**USERNAME**"                    ]                }            ],            "Action": [                "s3:GetObject",                "s3:PutObject",                "s3:DeleteObject"            ],            "Resource": "arn:aws:s3:::**MyExampleBucket**/*"        },        {            "Effect": "Deny",            "Principal": "*",            "Action": "s3:*",            "Resource": [                "arn:aws:s3:::**MyExampleBucket**",                "arn:aws:s3:::**MyExampleBucket**/*"            ],            "Condition": {                "StringNotLike": {                    "aws:userId": [                        "**AROAEXAMPLEID**:*",                        "**AIDAEXAMPLEID**",                        "**111111111111**"                    ]                }            }        }    ]}
复制代码


除了在存储桶策略中包含角色权限之外,您还需要在 IAM 用户或角色的用户策略中定义这些权限。这些权限可以添加到客户托管的策略附加到 IAM 控制台中的角色或用户,详见以下策略文档。


{  "Version": "2012-10-17",  "Statement": [    {      "Effect": "Allow",      "Action": [        "s3:ListAllMyBuckets",        "s3:GetBucketLocation"      ],      "Resource": "*"    },    {      "Effect": "Allow",      "Action": "s3:ListBucket",      "Resource": "arn:aws:s3:::**MyExampleBucket**"    },    {      "Effect": "Allow",      "Action": [        "s3:GetObject",        "s3:PutObject",        "s3:DeleteObject"      ],      "Resource": "arn:aws:s3:::**MyExampleBucket**/*"    }  ]}
复制代码


按照本文中的指导,即使用户拥有 Admin 策略或带有 s3:* 的策略,也可以将 S3 存储桶访问权限限于本地账户内和不同账户中的特定 IAM 角色或用户。这种逻辑有多种应用,各种使用案例的要求可能会有所不同。例如,您可以使用此方法设置存储桶,以供 Auto Scaling 组内的实例访问。如同在包含个人记录和账户信息的存储桶中一样,您还可以使用此方法限制对具有高级别安全需求的存储桶的访问。务必牢记,最好始终仅将权限授予执行必要任务所需的资源。


如果您对本博文有任何评论,欢迎在下方的“评论”部分提交。如果您有任何疑问,请在 IAM 论坛中开启一个新话题。


本文转载自 AWS 技术博客。


原文链接:


https://amazonaws-china.com/cn/blogs/china/securityhow-to-restrict-amazon-s3-bucket-access-to-a-specific-iam-role/


2019-10-23 08:001266

评论

发布
暂无评论
发现更多内容

树莓派4B安装docker-compose(64位Linux)

程序员欣宸

Docker 10月月更 树莓派4

经历了6个月的失踪,我将带着干货终究归来!【RocketMQ入门到精通】

洛神灬殇

1024 10月月更

【一Go到底】第二十天---闭包

指剑

Go golang 10月月更

优雅代码的秘密,都藏在这6个设计原则中

小小怪下士

Java 接口

基于强化学习的测试日志智能分析实践

华为云开发者联盟

人工智能 测试 华为云 强化学习 企业号十月 PK 榜

计算机体系结构“圣经”新版,图灵奖得主扛鼎之作,影响无数技术人

图灵社区

计算机体系结构

Redis的string内存消耗为何如此之大

芥末拌个饭吧

后端 redis 底层原理 10月月更

【LeetCode】连续子数组的最大和Java题解

Albert

算法 LeetCode 10月月更

命名规范与原则

Appleex

代码人生 命名规范

在线问题反馈模块实战(五):实现对通用字段内容自动填充功能

bug菌

springboot 项目实战 10月月更

Redis哨兵机制了解一下

芥末拌个饭吧

后端 redis 底层原理 10月月更

图解 | 聊聊 MyBatis 缓存

悟空聊架构

缓存 一级缓存 悟空聊架构 10月月更 myabtis

Linux下内存空间分配、物理地址与虚拟地址映射

DS小龙哥

10月月更

如果你看不懂别人画的 UML 类图,看这一篇文章就够了

跟着飞哥学编程

Java设计模式 10月月更 UML类图

数据中台坠落神坛,数据服务平台闪亮登场,阿里、快手又整烂活?

雨果

数据中台

数据湖(五):Hudi与Hive集成

Lansonli

10月月更 Hudi与Hive集成

Photoshop软件应用项目(三)

张立梵

设计师 ps 10月月更

在线问题反馈模块实战(六):接口文档定义

bug菌

springboot 项目实战 10月月更

群主发红包带你深入了解继承和super、this关键字

共饮一杯无

Java 关键字 10月月更

第K个语法符号

掘金安东尼

算法 10月月更

2022年8月银行APP月活跃人数盘点

易观分析

手机银行 8月

创建容器镜像:如何编写正确、高效的Dockerfile

okokabcd

Docker

Flash软件应用项目(三)

张立梵

设计师 Flash 10月月更

golang中的init初始化函数

六月的

golang init

华为云从入门到实战 | AI云开发ModelArts入门与WAF应用与部署

TiAmo

华为 华为云 云开发 10月月更

计算机体系结构“圣经”新版,图灵奖得主扛鼎之作,影响无数技术人

图灵教育

计算机体系结构 图灵奖

“程”风破浪的开发者|你真的会用Redis做消息队列吗

芥末拌个饭吧

学习方法 redis 底层原理 10月月更

golang中的接口

六月的

golang interface

在线问题反馈模块实战(四):封装通用字段类

bug菌

springboot 项目实战 10月月更

“全球金牌课程”【11月CSM认证】国际Scrum联盟认证导师CST授课 | 火热报名中

ShineScrum

Scrum CSM 敏捷项目 ScrumMaster认证

HashMap源码分析(二)

知识浅谈

hashmap 10月月更

如何将亚马逊 AWS S3 存储桶的访问权限到一个特定 IAM 角色_语言 & 开发_亚马逊云科技 (Amazon Web Services)_InfoQ精选文章