3. AWS IAM 深度解析:用户、组、角色、策略、信任关系、跨账户访问
说到云上安全,IAM 是绕不开的核心。很多人觉得 IAM 就是个“创建用户、打勾权限”的地方,其实远没那么简单。我见过不少团队,因为 IAM 策略写得太松,结果一个开发账号能删整个 RDS 集群——嗯,那场面挺刺激的。
这一章,咱们把 IAM 的五个核心概念掰开揉碎:用户、组、角色、策略、信任关系。最后再聊聊跨账户访问怎么玩。你把这些搞明白了,多云数据湖的权限骨架就算搭起来了。
3.1 用户(User):谁在敲门?
IAM 用户代表一个实体,可以是人,也可以是应用。每个用户有唯一的 ARN(Amazon Resource Name),用来标识身份。
创建用户时,你通常会做两件事:
- 控制台密码:给真人用的,记得开 MFA。
- 访问密钥(Access Key):给程序用的,别硬编码在代码里。
3.2 组(Group):批量管理的好帮手
组就是用户的集合。你把权限挂到组上,用户加入组就继承权限。这样管理起来省心多了。
举个例子:
# 创建组
aws iam create-group --group-name DataEngineers
# 给组附加策略
aws iam attach-group-policy \
--group-name DataEngineers \
--policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess
# 把用户加入组
aws iam add-user-to-group \
--group-name DataEngineers \
--user-name zhangsan
你想想看,如果公司有 50 个数据工程师,每个人单独挂策略,改一次权限得改 50 次。用组的话,改一个地方就行。说白了,组就是权限的“模板”。
3.3 角色(Role):临时通行证
角色和用户最大的区别是:角色没有长期凭证。角色是一组权限的集合,谁需要谁“扮演”。扮演成功后,AWS 临时给你发一组密钥,有效期默认 1 小时,最长 12 小时。
角色常用于:
- EC2 实例访问 S3
- Lambda 函数操作 DynamoDB
- 跨账户访问
- 联合身份认证(比如用 Okta 登录)
| 特性 | 用户 | 角色 |
|---|---|---|
| 凭证类型 | 长期(密码/密钥) | 临时(STS ) |
| 适用场景 | 真人、长期应用 | 服务、跨账户、联合身份 |
| 管理复杂度 | 高(密钥轮转麻烦) | 低(自动轮转) |
| 安全风险 | 密钥泄露风险 | 相对更低 |
我个人强烈建议:能用角色就别用用户密钥。尤其是 EC2 和 Lambda,直接挂角色,AWS 帮你自动轮转临时凭证,省心又安全。
3.4 策略(Policy):权限的“法律条文”
策略就是 JSON 文档,定义了“谁能在什么条件下对什么资源做什么操作”。IAM 策略分两种:
- AWS 托管策略:AWS 帮你维护的,比如 AmazonS3FullAccess。
- 客户托管策略:你自己写的,更精细。
一个典型的策略长这样:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::data-lake-prod",
"arn:aws:s3:::data-lake-prod/*"
],
"Condition": {
"IpAddress": {
"aws:SourceIp": "10.0.0.0/16"
}
}
}
]
}
这里要注意几个关键点:
- Effect:Allow 或 Deny。Deny 优先级高于 Allow。
- Action:操作列表,支持通配符
s3:*。 - Resource:资源 ARN,精确到桶或对象。
- Condition:条件限制,比如来源 IP、时间、是否启用 MFA。
/*,结果 ListBucket 能过,GetObject 死活报 403。因为 arn:aws:s3:::bucket 只代表桶本身,桶里的对象要用 arn:aws:s3:::bucket/*。嗯,这个细节卡了我一下午。
3.5 信任关系(Trust Relationship):谁可以扮演角色?
角色本身不决定谁能用它。谁可以扮演角色,由角色的信任策略决定。信任策略也是一份 JSON,它定义了哪些主体(Principal)被允许调用 sts:AssumeRole。
举个例子:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::123456789012:user/cross-account-user"
},
"Action": "sts:AssumeRole",
"Condition": {
"Bool": {
"aws:MultiFactorAuthPresent": "true"
}
}
}
]
}
这个信任策略的意思是:只允许账号 123456789012 下的 cross-account-user 这个用户,在启用了 MFA 的情况下,扮演这个角色。
你想想看,信任关系就像一把锁,权限策略是锁里面的内容。锁本身不关心谁来开,但信任策略决定了谁有钥匙。
3.6 跨账户访问:打通不同 AWS 账号
在多云数据湖场景下,你经常需要让账号 A 的某个服务访问账号 B 的 S3 桶。跨账户访问的标准做法就是角色扮演。
流程分三步:
- 账号 B(资源账号):创建一个 IAM 角色,挂上允许访问 S3 桶的策略。
- 账号 B:在角色的信任策略中,把账号 A 的某个用户或角色设为 Principal。
- 账号 A(访问账号):调用
sts:AssumeRole,拿到临时凭证,然后用这个凭证去访问账号 B 的资源。
代码示例:
# 账号 A 上的操作
aws sts assume-role \
--role-arn "arn:aws:iam::222222222222:role/DataLakeAccessRole" \
--role-session-name "cross-account-session"
# 返回临时凭证,然后设置环境变量
export AWS_ACCESS_KEY_ID=ASIA...
export AWS_SECRET_ACCESS_KEY=...
export AWS_SESSION_=...
# 现在可以访问账号 B 的 S3 桶了
aws s3 ls s3://data-lake-bucket-in-account-b/
3.7 知识体系总览
下面这张图把 IAM 的核心概念串起来了。你一看就明白:用户和组是“谁”,角色是“临时身份”,策略是“能做什么”,信任关系是“谁可以来”。
3.8 避坑指南
最后,分享几个我亲身踩过的坑:
- 策略大小限制:每个 IAM 策略最大 6,144 个字符。别把所有权限写在一个策略里,拆成多个。
- 角色信任策略别写太宽:Principal 写成
"AWS": "*"等于把门敞开,任何人都能扮演。除非你明确知道自己在做什么,否则别这么干。 - 跨账户角色删除后遗症:如果你删除了角色,但账号 A 还在用旧的临时凭证,会一直报错。记得先停用凭证再删角色。
- 权限边界(Permissions Boundary):可以用它限制用户或角色的最大权限。我习惯给每个开发账号加一个权限边界,防止他们意外给自己提权。
IAM 这东西,看着简单,用好了是安全基石,用不好就是安全漏洞。你把这些概念吃透了,后面搭建多云数据湖的权限体系就会顺手很多。