第 5 章

IAM 实战指南

⏱️ 45 分钟
📝 20 题练习
备考助手

📌 核心知识点

策略编写技巧最小权限原则角色设计模式安全审计

IAM 实战指南

📖 IAM 基础知识

AWS Identity and Access Management (IAM) 是 AWS 安全的基础,控制谁可以访问什么资源。每个 AWS 管理员都需要了解和使用 IAM。

📒 官方文档用户指南FAQAWS 安全博客

🖼️ IAM 图解补充

EC2 Security Group 基础示意(AWS 官方)

看图重点:网络层控制不能替代 IAM 身份授权,两者要协同设计。

VPC 基础网络架构(AWS 官方)

看图重点:跨子网访问被拒时,要同时排查 IAM 和网络策略。

RDS 数据库实例架构(AWS 官方)

看图重点:数据库访问权限应通过 IAM + DB 认证分层控制。

ALB 组件架构(AWS 官方)

看图重点:入口层接入权限与后端服务调用权限应分离管理。

ECS 分层架构(AWS 官方)

看图重点:容器任务角色(Task Role)与执行角色(Execution Role)权限边界要清晰。

成本分配标签示例(AWS 官方)

看图重点:标签是权限与成本治理的共同维度,应统一命名。

成本分配报表示例(AWS 官方)

看图重点:权限收敛后结合报表可识别异常资源使用行为。

IAM 组件

IAM 身份体系
├── 用户 (Users) - 真实的人或程序
│   ├── 密码 - 控制台登录
│   └── Access Keys - CLI/API 访问
├── 组 (Groups) - 用户的集合
├── 角色 (Roles) - 临时权限,用于服务
├── 策略 (Policies) - 权限定义文档
└── 身份提供商 (Identity Providers) - SSO/SAML 集成

IAM 管理的认证类型

认证类型说明使用场景
密码用户名 + 密码控制台登录
Access KeysID + SecretCLI、API、SDK
MFA二次验证增强安全性
临时凭证STS 生成角色扮演

Access Key 前缀含义

# Access Key ID 前缀说明
AKIA... → 永久 Access Key(标准密钥)
ASIA... → 临时 Access Key(来自 STS)
         → 需要额外的 SessionToken 参数

# 完整的 Access Key 格式
Access Key ID: AKIAIOSFODNN7EXAMPLE (20 个字符)
Secret Access Key: wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY (40 个字符)

策略语言

策略结构

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowS3Read",
      "Effect": "Allow",
      "Action": [
        "s3:GetObject",
        "s3:ListBucket"
      ],
      "Resource": [
        "arn:aws:s3:::my-bucket",
        "arn:aws:s3:::my-bucket/*"
      ],
      "Condition": {
        "IpAddress": {
          "aws:SourceIp": "203.0.113.0/24"
        }
      }
    }
  ]
}

🔸 注意: 策略语言的 JSON 语法复杂且容易出错。除非你是专家,否则最好基于可信的示例或 AWS 预定义的 托管策略 来创建。

权限评估层次

IAM 权限按以下顺序评估:

1. 显式拒绝 (Explicit Deny) - 最高优先级,任何拒绝都会生效
        ↓
2. 显式允许 (Explicit Allow) - 必须明确授予权限
        ↓
3. 隐式拒绝 (Implicit Deny) - 默认情况下拒绝所有

# 示例:
用户策略: Allow s3:*
资源策略: Deny s3:DeleteObject
结果: 用户可以读取但不能删除(显式拒绝优先)

IAM 策略生效逻辑(AWS 官方)

看图重点:排查权限问题时按“显式拒绝 > 显式允许 > 默认拒绝”的顺序定位。

策略类型

类型附加位置用途
身份策略用户/组/角色定义身份的权限
资源策略S3/SQS/Lambda 等定义资源的访问控制
权限边界用户/角色限制最大权限
会话策略AssumeRole 时临时限制权限
SCPAWS Organizations组织级别限制

IAM Permission Boundary 作用范围(AWS 官方)

看图重点:Permission Boundary 不是授权本身,而是给身份策略设置“最大可授权上限”。

策略测试工具

# 使用 IAM Policy Simulator 测试策略
# https://policysim.aws.amazon.com/home/index.jsp

# 这个工具特别有用于:
# - 测试自定义策略
# - 调试权限问题
# - 验证策略变更的影响

💡 推荐资源: IAM Policies In A Nutshell - IAM 策略概念的高质量概述。

最小权限原则

这是安全的基础原则:给每个用户或服务只授予完成其职责所需的最小权限。

实践方法

# 1. 使用 Access Analyzer 分析权限
aws accessanalyzer create-analyzer \
  --analyzer-name my-analyzer \
  --type ACCOUNT

# 2. 使用 Access Advisor 查看实际使用的权限
# IAM Console -> 用户 -> Access Advisor

# 3. 避免使用通配符
# ❌ 不推荐
"Action": "s3:*"

# ✅ 推荐
"Action": [
  "s3:GetObject",
  "s3:PutObject"
]

常见最小权限示例

只读 S3 访问:

{
  "Effect": "Allow",
  "Action": [
    "s3:GetObject",
    "s3:GetObjectVersion"
  ],
  "Resource": "arn:aws:s3:::bucket-name/*"
}

EC2 实例管理(按标签限制):

{
  "Effect": "Allow",
  "Action": [
    "ec2:StartInstances",
    "ec2:StopInstances"
  ],
  "Resource": "arn:aws:ec2:*:*:instance/*",
  "Condition": {
    "StringEquals": {
      "ec2:ResourceTag/Environment": "development"
    }
  }
}

💡 IAM 最佳实践

1. 从一开始就使用 IAM 用户

# ❌ 错误做法:共享一个账户凭证
# 这是非常常见的错误!

# ✅ 正确做法:
# 1. 为每个用户创建单独的 IAM 账户
# 2. 按职能创建组(管理员、开发者、只读等)
# 3. 使用组来管理权限

# 好处:
# - 可以撤销单个用户的凭证
# - 员工离职时可以快速禁用
# - 凭证泄露时影响范围可控

2. 启用 MFA(必须!)

# ❗ 所有用户都应启用 MFA,越早越好
# 后期给大量用户启用 MFA 是额外的工作

# 推荐的 MFA 应用:
# - Google Authenticator (iOS/Android)
# - Authy

# Root 账户:考虑使用硬件 MFA 设备

# 检查未启用 MFA 的用户
aws iam list-users --query 'Users[?MFADevices==`[]`].UserName'

3. 保护 Root 账户

# ❗ 除了初始创建账户,永远不要使用 Root 账户!

# Root 账户安全措施:
# 1. 启用 MFA(最好是硬件设备)
# 2. 不创建 Access Keys
# 3. 物理保管 MFA 设备
# 4. 极少使用

# Root 账户是 "game over" 级别的凭证
# 一旦泄露,整个 AWS 账户都会受到威胁

4. 启用 CloudTrail

# ❗ 这应该是你创建 AWS 账户后做的第一件事!

aws cloudtrail create-trail \
  --name my-trail \
  --s3-bucket-name my-cloudtrail-bucket \
  --is-multi-region-trail

aws cloudtrail start-logging --name my-trail

# CloudTrail 记录所有 API 调用,用于:
# - 安全审计
# - 故障排查
# - 合规性要求

5. 为 EC2 使用 IAM 角色

# ❌ 错误:在 EC2 上存储 Access Keys
# ✅ 正确:使用 IAM 角色

# 1. 创建角色
aws iam create-role \
  --role-name EC2-S3-Access \
  --assume-role-policy-document file://trust-policy.json

# 2. 附加策略
aws iam attach-role-policy \
  --role-name EC2-S3-Access \
  --policy-arn arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess

# 3. 创建实例配置文件
aws iam create-instance-profile \
  --instance-profile-name EC2-S3-Access-Profile

# 4. 添加角色到配置文件
aws iam add-role-to-instance-profile \
  --instance-profile-name EC2-S3-Access-Profile \
  --role-name EC2-S3-Access

6. 按环境分配角色

# 为开发、测试、生产环境创建不同的角色
# 防止开发实例连接到生产数据库

Role: Dev-App-Role
  → 只能访问开发资源

Role: Staging-App-Role
  → 只能访问测试资源

Role: Prod-App-Role
  → 只能访问生产资源

7. 多账户策略

对于大型组织,考虑使用多个 AWS 账户:

AWS Organizations
├── 管理账户 (Master)
├── 生产账户 (Production)
├── 开发账户 (Development)
├── 安全账户 (Security/Audit)
└── 共享服务账户 (Shared Services)

考虑因素:

  • 隔离级别需求
  • 资源配额限制
  • API 调用限流(每个账户独立)
  • 合规性要求
  • 成本分摊

角色设计模式

跨账户访问

Account A (信任方)              Account B (被访问方)
     |                                |
     | AssumeRole                     |
     |------------------------------->|
     |                                | 返回临时凭证
     |<-------------------------------|
     |                                |
     | 使用临时凭证访问资源

Account B 的角色信任策略:

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

Lambda 执行角色

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

安全审计工具

AWS 原生工具

工具用途
IAM Access Analyzer分析外部访问权限
AWS Inspector自动化安全评估
Trusted Advisor安全最佳实践检查
AWS Config配置合规性监控
CloudTrailAPI 调用审计

开源工具

# Security Monkey (Netflix)
# https://github.com/Netflix/security_monkey
# 持续监控 AWS 安全配置

# Scout2 / ScoutSuite
# https://github.com/nccgroup/ScoutSuite
# AWS 环境安全态势评估

# git-secrets
# https://github.com/awslabs/git-secrets
# 防止凭证提交到 Git 仓库

定期检查清单

# 1. 生成凭证报告
aws iam generate-credential-report
aws iam get-credential-report --output text --query Content | base64 -d

# 2. 检查未使用的凭证
# 查看 90 天未使用的 Access Keys

# 3. 审计策略权限
aws iam get-account-authorization-details

# 4. 检查 Access Keys 年龄
aws iam list-access-keys --user-name USERNAME

⚠️ IAM 常见陷阱

1. 共享用户凭证

# ❗ 这是非常常见的错误!

# ❌ 错误:
# 创建一个账户,多人共享使用

# 问题:
# - 无法追踪谁做了什么
# - 无法单独撤销某人的权限
# - 员工离职后凭证无法安全清理
# - 凭证泄露影响所有人

# ✅ 正确:每人一个独立的 IAM 账户

2. 实例元数据服务限流

# ❗ 如果大量使用 IAM 角色(你应该这样做!)
# 可能会遇到实例元数据 API 限流

# 解决方案:
# 1. 在代码中缓存凭证(如 2 分钟)
# 2. 可以缓存到 ~/.aws/credentials
# 3. 但要注意凭证会过期,必须定期刷新

# 示例缓存逻辑:
if (credential_age < 2 minutes):
    return cached_credential
else:
    refresh_from_metadata_service()

3. IAM API 可用性

# 🔸 IAM API 的可用性历史上低于实例元数据 API

# 警告:
# 不要在关键路径中依赖 IAM API
# 例如:用 IAM 组验证用户登录权限

# 建议:
# - 预缓存组成员信息
# - 保留应急后门
# - 设计降级策略

4. IAM 操作延迟

# 🔸 某些 IAM 操作比其他 API 调用慢(几秒钟)
# 因为 AWS 需要在全球各区域传播这些变更

# 影响的操作:
# - 创建/更新策略
# - 附加策略到角色
# - 创建用户/角色

# 建议:创建资源后等待几秒再使用

5. 凭证泄露到 Git

# ❗ 有机器人扫描 GitHub 寻找 AWS 凭证!

# 预防措施:
# 1. 使用 git-secrets
git secrets --install
git secrets --register-aws

# 2. 在 .gitignore 中排除凭证文件
echo "*.pem" >> .gitignore
echo ".env" >> .gitignore
echo "credentials.json" >> .gitignore

# 3. 如果已泄露:立即轮换凭证!
aws iam update-access-key --access-key-id AKIAEXAMPLE --status Inactive
aws iam create-access-key --user-name USERNAME

6. 过度授权

# ❌ 错误:使用 * 通配符
{
  "Action": "*",
  "Resource": "*"
}

# ✅ 正确:明确列出需要的权限
{
  "Action": [
    "s3:GetObject",
    "s3:PutObject"
  ],
  "Resource": "arn:aws:s3:::specific-bucket/*"
}

安全最佳实践总结

实践优先级说明
启用 Root MFA❗ 必须使用硬件 MFA 设备
不使用 Root 账户❗ 必须创建 IAM 用户代替
启用 CloudTrail❗ 必须记录所有 API 调用
每人独立 IAM 账户❗ 必须不共享凭证
所有用户启用 MFA强烈推荐包括服务账户
使用 IAM 角色强烈推荐避免长期凭证
定期轮换密钥推荐每 90 天
使用权限边界推荐限制最大权限
启用 Access Analyzer推荐分析外部访问

有用的 IAM 资源

📚 本章小结

  • IAM 是 AWS 安全的核心,每个管理员都必须掌握
  • 从一开始就为每个用户创建独立的 IAM 账户
  • Root 账户必须启用 MFA,且极少使用
  • 策略遵循最小权限原则,避免使用 * 通配符
  • 优先使用 IAM 角色而非长期凭证
  • 第一时间启用 CloudTrail
  • 定期审计和轮换凭证
  • 使用 git-secrets 防止凭证泄露
📝 章节练习 (20 题)
开始练习