大家好,我是程序员柏风,AI 最全的 Vibecoding 学习地图 http://coderoadmap.cn 作者。
IAM
这一课你将能做到
- 创建 IAM 用户、组、角色,并给它们分配合适的策略
- 写出符合最小权限原则的自定义策略(Policy),限制只能访问特定 S3 桶
- 在 EC2 上使用 IAM Role 代替 Access Key,并解释为什么这是最佳实践
为什么要学
IAM 是 AWS 安全的「大门」。所有对 AWS 资源的操作都要经过 IAM 鉴权。本站如果迁到 AWS,后端服务要访问 S3、RDS、SES,每个服务用什么身份、有什么权限,全靠 IAM。面试必问「最小权限原则」「Role 和 User 的区别」。
人话:IAM 就是 AWS 的「门禁系统」。User 是员工工牌,Group 是部门,Role 是「临时通行证」——谁戴上这个通行证,谁就拥有对应的权限。Policy 是通行证上写的「允许进入哪些房间」。
先建立图像
IAM 核心概念关系图:
┌─────────────────────────────────────────┐
│ AWS 账号 (Root) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ User │ │ Group │ │ Role │ │
│ │(开发者A) │ │(开发组) │ │(EC2角色)│ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └────────────┴────────────┘ │
│ │ │
│ ┌─────┴─────┐ │
│ │ Policy │ │
│ │(权限策略) │ │
│ └───────────┘ │
└─────────────────────────────────────────┘
策略(Policy)结构示例:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": ["s3:GetObject", "s3:PutObject"],
"Resource": "arn:aws:s3:::codenav-uploads/*",
"Condition": {
"IpAddress": {"aws:SourceIp": "203.0.113.0/24"}
}
}
]
}
跟着做
步骤 1:创建 IAM 用户并加入组
# 创建用户
aws iam create-user --user-name developer-li
# 创建组
aws iam create-group --group-name developers
# 把用户加入组
aws iam add-user-to-group --user-name developer-li --group-name developers
# 给用户创建 Access Key(用于 CLI)
aws iam create-access-key --user-name developer-li
步骤 2:给组附加托管策略
# 附加只读策略到开发组
aws iam attach-group-policy --group-name developers --policy-arn arn:aws:iam::aws:policy/ReadOnlyAccess
# 附加 EC2 全权限到运维组(先创建 ops 组)
aws iam create-group --group-name ops
aws iam attach-group-policy --group-name ops --policy-arn arn:aws:iam::aws:policy/AmazonEC2FullAccess
步骤 3:创建自定义策略(最小权限示例)
创建文件 s3-codenav-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "AllowListCodenavBuckets",
"Effect": "Allow",
"Action": "s3:ListAllMyBuckets",
"Resource": "*"
},
{
"Sid": "AllowReadWriteCodenavUploads",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket"
],
"Resource": [
"arn:aws:s3:::codenav-uploads",
"arn:aws:s3:::codenav-uploads/*"
]
}
]
}
创建并附加策略:
# 创建策略
aws iam create-policy --policy-name codenav-s3-access --policy-document file://s3-codenav-policy.json
# 附加到组
aws iam attach-group-policy --group-name developers --policy-arn arn:aws:iam::123456789012:policy/codenav-s3-access
步骤 4:创建 EC2 用的 IAM Role
创建信任策略 trust-policy.json:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
# 创建 Role
aws iam create-role --role-name codenav-ec2-role --assume-role-policy-document file://trust-policy.json
# 附加策略(允许访问 S3 和 SES)
aws iam attach-role-policy --role-name codenav-ec2-role --policy-arn arn:aws:iam::aws:policy/AmazonS3FullAccess
aws iam attach-role-policy --role-name codenav-ec2-role --policy-arn arn:aws:iam::aws:policy/AmazonSESFullAccess
# 创建 Instance Profile
aws iam create-instance-profile --instance-profile-name codenav-ec2-profile
aws iam add-role-to-instance-profile --instance-profile-name codenav-ec2-profile --role-name codenav-ec2-role
步骤 5:验证 EC2 上的临时凭证
SSH 到绑定了该 Role 的 EC2 实例:
# 查看临时凭证(自动轮换,每小时过期)
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/codenav-ec2-role
# 用 AWS CLI 测试(不需要配置 Access Key)
aws s3 ls s3://codenav-uploads
步骤 6:使用 AWS CLI 模拟权限测试
# 模拟用户能不能执行某个操作
aws iam simulate-principal-policy --policy-source-arn arn:aws:iam::123456789012:user/developer-li --action-names s3:PutObject --resource-arns arn:aws:s3:::codenav-uploads/test.txt
讲清楚要点
- User vs Group vs Role:User 是具体的人或程序,Group 是权限集合(人属于组,组挂策略),Role 是「帽子」——谁戴上谁就有权限,EC2、Lambda、其他账号都能戴。
- Policy 评估逻辑:默认拒绝(Implicit Deny)→ 显式拒绝(Explicit Deny)→ 显式允许(Allow)。有 Deny 就一票否决。
- 最小权限原则:只给完成工作必需的权限,不多给。
s3:*是偷懒,s3:GetObjecton 特定桶才是专业。 - Access Key vs IAM Role:Access Key 是长期凭证,泄露风险大。IAM Role 是短期凭证(自动轮换),EC2/Lambda 首选。
- 资源级权限:尽量用
Resource字段限定到具体资源(如arn:aws:s3:::codenav-uploads/*),不要用*。
你可能会懵的地方
-
IAM 是全局服务还是区域服务? IAM 是全局服务,用户/组/角色/策略在所有区域通用。不需要每个区域单独创建。
-
Role 和 User 都能登录控制台吗? 不能。User 可以设密码登录控制台,Role 不能登录控制台,只能被「Assume」(担任)。EC2、Lambda、跨账号访问都用 Role。
-
策略里的
*和?有什么区别?*匹配任意字符序列(包括空),?匹配单个字符。s3:Get*匹配 GetObject、GetBucketLocation 等。 -
怎么知道某个用户到底有哪些权限? 用
aws iam list-user-policies、aws iam list-attached-user-policies,再加上所在组的策略,合并起来看。或者直接用 IAM 控制台的「Access Advisor」。 -
Service-linked Role 是什么? AWS 服务自动创建的 Role,比如 RDS 自动创建
AWSServiceRoleForRDS,用来代表 RDS 服务操作其他资源。不要删。
错法对照
| 错法 | 问题 | 正解 |
|---|---|---|
| 用 root 账号 Access Key 调 API | root 权限无限,泄露即灾难 | 创建 IAM 用户,只给必要权限 |
给所有人 AdministratorAccess | 权限过大,误操作风险 | 按职能分组,只给工作所需权限 |
策略里 Resource: "*" | 能访问所有资源,横向移动风险 | 限定到具体 ARN,如 arn:aws:s3:::codenav-uploads/* |
| 把 Access Key 提交到 Git | 公开泄露,被挖矿 | 用 IAM Role,或至少用环境变量 + gitignore |
| 长期不轮换 Access Key | 泄露后长期有效 | 定期轮换(90 天),用 aws iam rotate-access-key |
卡点急救
- 报
AccessDenied但策略明明允许:检查是否有显式 Deny;检查 SCP(Service Control Policy,组织层面限制);检查资源 ARN 是否写对(区分大小写)。 - EC2 上 AWS CLI 报
Unable to locate credentials:没绑 IAM Role,或者 IMDSv2 被禁用。用curl -H "X-aws-ec2-metadata-token: ..." http://169.254.169.254/latest/meta-data/iam/security-credentials/检查。 - 跨账号访问 S3 失败:需要目标账号的 S3 桶策略(Bucket Policy)显式允许源账号的 Role。IAM 策略 + 资源策略 两者都要允许。
面试常问
-
什么是最小权限原则?怎么落地? 只授予完成特定任务所必需的最小权限集合。落地方法:按职能建组,组挂策略;策略里限定 Resource 到具体 ARN;定期用 Access Advisor 审查未使用的权限并回收。
-
IAM Role 和 IAM User 的区别?使用场景? User 是长期身份,有固定凭证(密码/Access Key),给人用。Role 是临时身份,凭证自动轮换,给服务用(EC2、Lambda、跨账号)。最佳实践:EC2 上永远用 Role,不放 Access Key。
-
Policy 评估逻辑是什么? 默认拒绝 → 显式拒绝(Deny)优先 → 显式允许(Allow)生效。任何一条 Deny 都会否决所有 Allow。评估顺序:SCP → 权限边界 → 会话策略 → 身份策略 → 资源策略。
自测三问
- IAM Role 和 IAM User 的核心区别是什么?为什么 EC2 推荐用 Role?
- 策略评估时,如果一条 Allow 和一条 Deny 同时匹配,结果是什么?
- 写一个策略,允许用户只能读取
codenav-uploads桶里的public/前缀下的对象。
小结一句话
IAM 是 AWS 安全的基石,User 给人、Role 给服务、Policy 定权限,最小权限原则是唯一准则。
延伸
- AWS IAM 官方文档
- IAM 最佳实践
- 下一课:弹性伸缩与 ELB——让本站自动应对流量高峰。