1. AWS IAM 与 S3 概述
这一章咱们先把地基打好。IAM 和 S3 是 AWS 里最常用的两个服务,一个管「谁能做什么」,一个管「数据放哪儿」。很多初学者把权限配置搞混,往往是因为没理清这两者的关系。我刚开始接触 AWS 的时候,就被桶策略和 IAM 策略绕晕过——明明都写了 Allow,为什么访问还是被拒绝?嗯,踩过坑之后才明白,这两套权限体系是互相独立又必须配合的。
1.1 IAM 基本概念
IAM(Identity and Access Management)说白了就是 AWS 的「用户中心」加「权限管家」。它不负责存储数据,只负责回答三个问题:你是谁?你能访问哪些资源?你能对资源做什么操作?
核心组件就这几个:
- 用户(User):代表一个人或一个应用程序。每个用户有固定的凭证(密码或访问密钥)。
- 用户组(Group):把相同权限的用户归到一起,方便统一管理。比如把开发人员都加进 "Developers" 组,然后给这个组绑定策略。
- 角色(Role):一种临时身份,可以分配给用户、AWS 服务或外部身份。角色没有长期凭证,用的是临时安全令牌(STS)。
- 策略(Policy):定义权限的规则文档。策略用 JSON 格式写,核心字段是
Effect(Allow/Deny)、Action(允许或拒绝的操作)、Resource(操作对象)。
讲一个我项目里的例子。有一回我帮客户配置跨账号访问 S3,客户要求在账号 A 里用角色,账号 B 里放数据。当时我写完信任策略和权限策略,结果一直报 AccessDenied。排查了半天,发现是角色信任策略里 Principal 写成了用户 ARN 而不是账号 ID——这种细节特别容易漏。
1.2 S3 存储模型
S3(Simple Storage Service)是 AWS 的对象存储服务。我经常把它比喻成一个「无限大的硬盘」,不过存取用的是 HTTP API 而不是文件系统路径。
几个关键概念:
- 桶(Bucket):存储容器,名称全局唯一。每个桶属于一个 AWS 区域,但桶名在所有区域、所有账号里不能重复。你想想看,这设计是为了让 S3 的 URL 变成
https://bucket-name.s3.region.amazonaws.com/key这种统一格式。 - 对象(Object):文件 + 元数据。每个对象由键(Key)标识,相当于路径。
- 区域(Region):桶和对象的物理位置。跨区域访问会产生延迟和传输费用。
- ARN(Amazon Resource Name):资源的唯一标识。比如
arn:aws:s3:::my-bucket/*表示 my-bucket 里的所有对象。
我个人的习惯是:生产环境的桶一定开启「阻止公共访问」的默认设置,然后通过 IAM 策略或桶策略精确控制访问。除非明确需要公开静态网站内容,否则绝不打开「公有读取」。
1.3 两者权限体系的关系
IAM 和 S3 的权限体系是「双轨制」:一套基于身份,一套基于资源。
- 基于身份的策略(Identity-based Policy):附加给 IAM 用户、组或角色。它们指定「这个身份可以干什么」。比如“允许 Bob 列出所有桶”。
- 基于资源的策略(Resource-based Policy):附加给 S3 桶或对象。它们指定「这个资源允许谁访问」。比如“允许账号 123456789012 中的特定角色读取本桶”。
访问最终能否成功,取决于两者策略的交集。说白了,就像过两道门:IAM 策略是第一道门,桶策略是第二道门。两道门都必须放行,你才能进去。如果有任何一道门明确拒绝(Deny),你就进不去。
我曾经在排查一个跨账号访问问题时,发现 IAM 角色策略里写了对 S3 的 s3:GetObject 允许,桶策略里也写了允许那个角色 ARN 访问,但依然被拒。后来发现:桶策略里忘记加上 s3:ListBucket 权限。你想想看,没有 ListBucket 权限,客户端连桶里的文件列表都看不到,GetObject 自然也没法用。这就是一个典型的「权限组合漏洞」。
下面这张图能帮你直观理解 IAM 和 S3 权限体系的关系:
再来看一个对比表格,帮你快速区分两种策略:
| 维度 | 基于身份策略(IAM) | 基于资源策略(S3 桶策略) |
|---|---|---|
| 附加对象 | IAM 用户、组、角色 | S3 桶(直接贴在桶上) |
| 控制粒度 | 精细到操作和资源 ARN | 精细到操作、主体(Principal)和条件 |
| 跨账号支持 | 通过角色(AssumeRole)实现 | 直接在策略中指定其他账号的 Principal |
| 默认效果 | 隐式 Deny(未显式 Allow 则拒绝) | 隐式 Deny(但桶策略可以显式 Allow 公共访问) |
| 常见使用场景 | 管理内部员工或服务的权限 | 开放公共读取、跨账号共享数据 |
核心记忆点:IAM 策略管「谁」,S3 桶策略管「谁可以访问这个桶」。两者共同决定最终权限。如果 IAM 策略里写了 Deny,桶策略里写了 Allow,结果还是 Deny——因为 Deny 优先级最高。
实际配置时,我强烈建议你遵循最小权限原则:先不给任何权限,然后根据业务需求逐步添加。我见过很多开发者图省事,直接写了一个 s3:* 的 Allow,结果有一天不小心把数据删了才追悔莫及。所以,别偷懒。