IAM 实体详解

深入理解 IAM 的四大核心实体:Root 用户、IAM 用户、IAM 组和 IAM 角色。

Root 用户

特性和风险

Root 用户的特殊性:

最高权限账户
├─ 创建 AWS 账户时自动创建
├─ 使用邮箱 + 密码登录
├─ 拥有完全、不受限制的访问权限
├─ 无法通过 IAM 策略限制
├─ 可以访问账单信息
└─ 可以关闭整个 AWS 账户

Root 用户独有权限:

仅 Root 用户可以执行的操作:
├─ 更改账户设置(名称、邮箱、密码)
├─ 查看税务发票
├─ 关闭 AWS 账户
├─ 恢复 IAM 用户权限
├─ 更改或取消 AWS Support 计划
├─ 注册为 Reserved Instances 卖家
├─ 配置 S3 bucket 以启用 MFA 删除
├─ 编辑或删除包含无效 VPC ID 的 S3 bucket 策略
└─ 注册 GovCloud

Root 用户安全加固

必须执行的安全措施:

1. 启用 MFA(多因素认证):

步骤:
1. 登录 AWS 控制台
2. 导航到 My Security Credentials
3. 选择 MFA 设备
4. 推荐:虚拟 MFA(Google Authenticator、Authy)
5. 扫描二维码,输入两个连续的 MFA 码
6. 验证成功后,记录设备序列号

2. 删除 Access Key:

检查和删除:
1. My Security Credentials → Access keys
2. 如果存在 Root Access Key:
   ├─ 立即停用
   ├─ 确认没有使用后删除
   └─ 永远不要创建新的 Root Access Key

为什么?
├─ Root Access Key 泄露 = 账户完全失控
├─ 无法限制 Root Access Key 权限
├─ 难以追踪和审计使用情况
└─ 违反所有安全最佳实践

3. 设置强密码:

密码要求:
├─ 最小长度:16 字符(推荐 20+)
├─ 包含大写字母
├─ 包含小写字母
├─ 包含数字
├─ 包含特殊字符
└─ 不使用常见词汇或个人信息

密码管理:
├─ 使用密码管理器(1Password、LastPass)
├─ 定期更换(90-180 天)
├─ 不与其他账户共享密码
└─ 启用密码恢复选项

4. 限制 Root 用户使用:

仅在以下情况使用 Root:
├─ 首次账户设置
├─ 更改账单信息
├─ 关闭账户
├─ 恢复 IAM 管理员权限(紧急情况)
└─ 其他 Root 专属操作

日常运维:
├─ 使用 IAM 管理员用户
├─ 遵循最小权限原则
├─ 启用 CloudTrail 审计
└─ 设置异常登录告警

IAM 用户

用户类型和场景

人类用户:

特征:
├─ 代表真实的人
├─ 需要控制台访问
├─ 需要 CLI/API 访问
├─ 长期凭证(相对角色)
└─ 一人一账户

适用场景:
├─ 开发人员
├─ 运维人员
├─ 数据分析师
├─ 业务管理员
└─ 第三方合作伙伴

服务账户:

特征:
├─ 代表应用程序或服务
├─ 仅需 API 访问(Access Key)
├─ 无需控制台访问
├─ 自动化脚本使用
└─ 需要定期轮换凭证

适用场景:
├─ CI/CD 系统(Jenkins、GitLab CI)
├─ 监控工具(Prometheus、Datadog)
├─ 自动化脚本
├─ 第三方集成
└─ 临时项目账户

⚠️ 注意:现代最佳实践推荐使用 IAM 角色替代服务账户

用户凭证管理

凭证类型:

1. 用户名和密码(控制台访问):

特性:
├─ 用于 AWS 管理控制台登录
├─ 可设置密码策略
├─ 可强制定期更换
├─ 可要求 MFA
└─ 登录 URL:https://<account-id>.signin.aws.amazon.com/console

最佳实践:
├─ 启用 MFA
├─ 使用强密码策略
├─ 定期更换密码(90 天)
├─ 监控异常登录
└─ 使用 AWS SSO(更好的选择)

2. Access Key(编程访问):

组成:
├─ Access Key ID:AKIA... (20 字符)
└─ Secret Access Key:40 字符密钥

特性:
├─ 用于 API、CLI、SDK 访问
├─ 每个用户最多 2 个 Access Key
├─ 可以轮换(保持服务不中断)
├─ 可以停用(不删除)
└─ 永久有效(除非删除)

安全风险:
├─ 泄露风险高(代码库、日志)
├─ 无法自动过期
├─ 难以追踪使用情况
└─ 权限范围大

轮换流程:
1. 创建第二个 Access Key
2. 更新应用程序使用新密钥
3. 测试验证
4. 停用旧密钥
5. 观察一段时间
6. 删除旧密钥

3. 临时安全凭证(推荐):

通过 STS 获取:
├─ Access Key ID
├─ Secret Access Key
├─ Session Token
└─ 过期时间

优势:
├─ 自动过期(15 分钟 - 12 小时)
├─ 无需长期存储
├─ 动态生成
├─ 审计友好
└─ 安全性更高

获取方式:
├─ AssumeRole(角色)
├─ GetSessionToken(MFA)
├─ GetFederationToken(联合身份)
└─ EC2 实例元数据(实例角色)

用户权限管理

权限来源:

用户的有效权限 = 
    用户策略
  + 用户所属组的策略
  + 内联策略
  - Deny 策略
  ∩ 权限边界(如果有)
  ∩ SCP(如果有)

权限附加方式:

直接附加到用户(不推荐):

缺点:
├─ 管理复杂
├─ 难以审计
├─ 不易标准化
└─ 扩展性差

何时使用:
└─ 用户需要特殊、临时的额外权限

通过组附加(推荐):

优点:
├─ 集中管理
├─ 易于审计
├─ 标准化
└─ 扩展性好

示例组结构:
├─ Admins 组
├─ Developers 组
├─ QA 组
├─ ReadOnly 组
└─ Finance 组

IAM 组

组的设计模式

按职能划分:

├─ Developers
│   ├─ 权限:开发环境完全访问
│   ├─ 权限:生产环境只读
│   └─ 权限:特定服务的管理权限
│
├─ DevOps
│   ├─ 权限:所有环境访问
│   ├─ 权限:基础设施管理
│   └─ 权限:部署权限
│
├─ DataScientists
│   ├─ 权限:EMR、Athena、SageMaker
│   ├─ 权限:S3 数据访问
│   └─ 权限:Redshift 查询
│
└─ Finance
    ├─ 权限:Cost Explorer
    ├─ 权限:账单访问
    └─ 权限:预留实例管理

按环境划分:

├─ Dev-FullAccess
│   └─ 开发环境的完全权限
│
├─ Staging-ReadWrite
│   └─ 预发布环境的读写权限
│
└─ Prod-ReadOnly
    └─ 生产环境的只读权限

组合模式:

用户可以属于多个组:

示例:Alice
├─ Developers 组(基础开发权限)
├─ Dev-FullAccess 组(开发环境)
└─ Prod-ReadOnly 组(生产只读)

有效权限 = 三个组的权限并集

组的限制

IAM 组限制:

限制:
├─ 组不能嵌套
├─ 用户最多属于 10 个组
├─ 每个账户最多 300 个组(可申请提升)
└─ 组本身没有凭证(无法登录)

替代方案:
├─ 使用权限边界
├─ 使用标签和 ABAC
└─ 使用 AWS SSO 的权限集

IAM 角色

角色的本质

角色 vs 用户:

IAM 用户:
├─ 代表一个特定的人或应用
├─ 有永久凭证
├─ 长期身份
└─ 固定权限

IAM 角色:
├─ 可以被任何人/服务承担
├─ 临时凭证(STS)
├─ 短期身份(15 分钟 - 12 小时)
└─ 动态权限

角色的四种类型

1. AWS 服务角色:

用途:AWS 服务代表你执行操作

常见服务角色:
├─ EC2 实例角色
│   └─ 让 EC2 实例访问 S3、DynamoDB 等
├─ Lambda 执行角色
│   └─ 让 Lambda 函数访问其他 AWS 服务
├─ ECS 任务角色
│   └─ 让容器访问 AWS 资源
└─ CloudFormation 角色
    └─ 让 CloudFormation 创建资源

优势:
├─ 无需在代码中硬编码凭证
├─ 凭证自动轮换
├─ 细粒度权限控制
└─ 审计友好

2. 跨账户角色:

用途:允许其他 AWS 账户访问你的资源

场景:
├─ 集中身份管理
│   └─ 用户在账户 A,访问账户 B 的资源
├─ 第三方服务集成
│   └─ SaaS 供应商访问你的 AWS 资源
├─ 合并/收购场景
│   └─ 临时访问其他公司的 AWS 账户
└─ 多环境管理
    └─ 从管理账户访问多个工作负载账户

安全机制:
├─ External ID(防止混淆代理攻击)
├─ 信任策略(显式授权)
├─ 会话策略(额外限制)
└─ MFA 要求(可选)

3. Web Identity 角色:

用途:允许通过 Web 身份提供商登录的用户访问 AWS

身份提供商:
├─ Amazon Cognito(推荐)
├─ Login with Amazon
├─ Facebook 登录
├─ Google 登录
└─ 任何 OpenID Connect (OIDC) 提供商

使用场景:
├─ 移动应用
├─ Web 应用
├─ 游戏应用
└─ 需要用户直接访问 AWS 的场景

优势:
├─ 无需创建 IAM 用户
├─ 支持数百万用户
├─ 用户自助注册
└─ 社交登录集成

4. SAML 2.0 联合角色:

用途:企业单点登录(SSO)

身份提供商:
├─ Active Directory FS (ADFS)
├─ Okta
├─ Azure AD
├─ Google Workspace
└─ OneLogin

工作流程:
员工 → 公司 IdP 认证 → SAML 断言 → AWS STS → 临时凭证 → AWS 资源

优势:
├─ 统一身份管理
├─ 无需同步用户到 AWS
├─ 支持现有企业目录
├─ 符合企业 SSO 策略
└─ 审计友好

角色的信任策略

信任策略的作用:

信任策略(Trust Policy):
├─ 定义"谁"可以承担这个角色
├─ 附加在角色上(不是策略)
├─ 使用 Principal 元素
└─ 独立于权限策略

权限策略(Permission Policy):
├─ 定义角色可以"做什么"
├─ 附加到角色
├─ 标准 IAM 策略
└─ 决定承担角色后的权限

信任策略示例:

允许 EC2 服务承担角色:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "ec2.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

允许特定用户承担角色:

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::123456789012:user/alice"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}

允许其他账户承担角色(跨账户):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": "arn:aws:iam::999999999999:root"
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "StringEquals": {
          "sts:ExternalId": "unique-external-id-12345"
        }
      }
    }
  ]
}

角色会话

会话参数:

承担角色时可以指定:

RoleSessionName:
├─ 会话的标识符
├─ 出现在 CloudTrail 日志中
├─ 用于审计追踪
└─ 最长 64 字符

DurationSeconds:
├─ 会话持续时间
├─ 最小:15 分钟(900 秒)
├─ 最大:12 小时(43200 秒)
├─ 默认:1 小时
└─ 可在角色中设置最大值

ExternalId:
├─ 用于跨账户场景
├─ 防止混淆代理攻击
├─ 必须与信任策略匹配
└─ 由承担方提供

SerialNumber + TokenCode:
├─ MFA 设备序列号
├─ 当前 MFA 码
├─ 用于增强安全性
└─ 可在信任策略中要求

服务链接角色

什么是服务链接角色:

Service-Linked Role:
├─ AWS 服务预定义的角色
├─ 自动创建(首次使用服务时)
├─ 权限由 AWS 定义(无法修改)
├─ 信任策略固定
└─ 只能删除(如果服务允许)

示例服务:
├─ AWS Config
├─ AWS CloudFormation StackSets
├─ Amazon ECS
├─ AWS Backup
└─ AWS Organizations

命名格式:
AWSServiceRoleFor<ServiceName>

示例:
AWSServiceRoleForECS
AWSServiceRoleForAutoScaling

为什么需要:

优势:
├─ 简化设置(自动创建)
├─ 安全(AWS 维护权限)
├─ 一致性(所有账户相同)
└─ 审计友好(标准化命名)

限制:
├─ 无法修改权限
├─ 无法修改信任策略
├─ 某些服务必须使用
└─ 删除可能影响服务功能

实体选择指南

何时使用什么

决策树:

需要 AWS 访问?
│
├─ 是人类用户?
│   ├─ 是 → 创建 IAM 用户 + 加入组
│   └─    (更好:使用 AWS SSO)
│
├─ 是 AWS 服务?
│   └─ 是 → 创建服务角色
│           └─ EC2、Lambda、ECS 等
│
├─ 是跨账户访问?
│   └─ 是 → 创建跨账户角色
│           └─ 使用信任策略 + External ID
│
├─ 是第三方应用?
│   └─ 是 → 创建角色
│           └─ 让第三方 AssumeRole
│
└─ 是自动化脚本?
    └─ 优先:在 EC2/Lambda 上运行 → 使用实例角色
       备选:使用 IAM 用户 + 定期轮换 Access Key
       最佳:迁移到容器/Lambda + 角色

安全性对比

安全性排序(从高到低):

1. IAM 角色(临时凭证)
   ├─ 自动过期
   ├─ 无需长期存储
   ├─ 动态权限
   └─ 推荐用于所有场景

2. IAM 用户 + MFA
   ├─ 双因素保护
   ├─ 需要定期轮换
   └─ 仅用于人类用户

3. IAM 用户(仅密码)
   ├─ 需要强密码策略
   ├─ 定期更换
   └─ 风险较高

4. IAM 用户 Access Key
   ├─ 泄露风险高
   ├─ 必须定期轮换
   └─ 尽量避免使用

5. Root 用户
   ├─ 风险极高
   ├─ 无法限制
   └─ 仅用于紧急情况

最佳实践总结

IAM 实体管理:

✅ 推荐做法:
├─ Root 用户仅用于账户管理
├─ 为每个人创建独立 IAM 用户
├─ 强制启用 MFA
├─ 使用组管理权限
├─ 优先使用角色而非用户
├─ 服务使用实例角色
├─ 跨账户使用信任关系
├─ 定期审查和清理未使用的实体
└─ 使用 AWS SSO 替代 IAM 用户

❌ 避免做法:
├─ 使用 Root 用户日常操作
├─ 共享 IAM 用户凭证
├─ 在代码中硬编码 Access Key
├─ 创建长期 Access Key(优先角色)
├─ 给用户过度权限
├─ 忽略 Access Key 轮换
├─ 不启用 CloudTrail 审计
└─ 忘记删除离职员工账户

理解 IAM 实体的特性和使用场景是构建安全 AWS 环境的基础!