2、云上身份与访问管理(IAM)

聊到多云安全,IAM 绝对是绕不开的第一道关卡。说白了,云上的身份管理就是「谁是谁,能干嘛」的问题。我见过太多团队,安全策略写得天花乱坠,结果 IAM 配置一塌糊涂,最后被攻破的往往就是那把「钥匙」。

2.1 IAM 核心概念:主体、资源与动作

IAM 模型其实不复杂。三个核心要素:主体(谁)、资源(什么)、动作(怎么干)。

  • 主体(Principal):用户、组、角色、服务账号。说白了就是「谁在发起请求」。
  • 资源(Resource):云上的对象,比如一台虚拟机、一个存储桶、一个数据库实例。
  • 动作(Action):对资源能做什么,比如读取、写入、删除、启动。

嗯,这里要注意:策略(Policy) 就是把这些要素串起来的规则。一条典型的策略长这样:「允许主体 A 对资源 B 执行动作 C」。我在项目中遇到过,有人把策略写得像天书,结果权限要么太大要么太小。我的建议是:策略越短越好,能明确拒绝的,就别用允许来绕

核心原则:最小权限

只给完成任务所需的最小权限。多一分都是风险。我曾经因为图省事,给一个测试账号绑了管理员权限,结果测试脚本被注入,差点把生产库删了。嗯,从那以后我再也不敢偷懒了。

2.2 用户、组与角色:谁该用哪个?

很多新手分不清用户、组和角色。我简单说下我的理解:

  • 用户(User):代表一个人。比如你的开发同事、运维同事。每个用户有独立的凭证(密码或密钥)。
  • 组(Group):用户的集合。把相同职责的人放一起,统一分配权限。比如「开发组」、「运维组」。我个人习惯:永远不要给单个用户直接绑策略,全部通过组来管理。这样哪天人员变动,改一个组就行,不用一个个改用户。
  • 角色(Role):临时身份。角色没有长期凭证,谁需要谁「扮演」。比如一个 EC2 实例需要访问 S3,就给实例绑定一个角色,而不是把密钥塞进代码里。你想想看,密钥泄露的风险是不是小多了?

避坑指南

我曾经见过一个团队,把几十个用户的权限直接写在用户上。后来一个人离职,光清理权限就花了三天。所以,能用组就别用用户,能用角色就别用密钥。这是血的教训。

2.3 策略(Policy)怎么写才安全?

策略是 IAM 的灵魂。写策略时,我建议遵循几个原则:

  1. 明确拒绝优先:先拒绝所有,再允许特定。比如「拒绝所有删除操作,只允许读取特定桶」。
  2. 资源范围要窄:别写 Resource: "*",除非你真的需要。我见过有人把 "*" 写进策略,结果一个不小心,整个账号的资源都暴露了。
  3. 条件(Condition)要用好:比如限制来源 IP、限制时间、限制是否使用 MFA。条件能帮你把权限收得更紧。

举个例子,一个只读策略的 JSON 片段:

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

你看,这里只允许从内网 IP 段读取特定桶。就算密钥泄露,攻击者从外网也访问不了。这就是策略的精细度。

注意:策略的「Effect」字段只有两种:Allow 和 Deny。Deny 的优先级永远高于 Allow。所以如果你写了一条 Deny 所有,再写 Allow 某个操作,Deny 会覆盖 Allow。嗯,这个坑我踩过,当时排查了半天才发现是 Deny 优先级的问题。

2.4 跨云身份联邦:SSO、SAML 与 OIDC

多云环境下,最头疼的问题就是:用户要在 AWS、Azure、GCP 之间来回切换,每个云一套账号密码?那运维成本就太高了。所以我们需要身份联邦(Federation)

说白了,就是用一个「中心身份源」来管理所有云的身份。比如你们公司用 Okta 或 Azure AD 做统一认证,用户登录一次,就能访问所有云资源。

2.4.1 SAML 2.0:老牌协议,稳定可靠

SAML 是基于 XML 的协议。流程大概是:

  1. 用户访问云控制台,云服务商(SP)发现你没登录,把你重定向到身份提供商(IdP)。
  2. 你在 IdP 登录,IdP 生成一个 SAML 断言(Assertion),里面包含你的身份信息。
  3. IdP 把这个断言发回给云服务商,云服务商验证后,给你临时凭证。

我在项目中遇到过,SAML 配置最麻烦的地方是证书交换属性映射。比如 Azure AD 里的「部门」字段,要映射到 AWS 里的「Role」字段。映射错了,用户登录后可能拿不到正确的角色。

我的建议:配置 SAML 时,先在测试环境走一遍完整流程。我曾经在生产环境直接配,结果用户登录后一片空白,排查了俩小时才发现是属性名大小写写错了。嗯,从那以后我学乖了。

2.4.2 OIDC:现代协议,轻量灵活

OIDC(OpenID Connect)是基于 OAuth 2.0 的身份层。它用 JWT(JSON Web Token)来传递身份信息,比 SAML 的 XML 轻量得多。现在很多 CI/CD 工具(比如 GitHub Actions、GitLab CI)都用 OIDC 来获取云资源访问权限。

举个例子,GitHub Actions 要部署到 AWS:

# GitHub Actions 工作流片段
jobs:
  deploy:
    runs-on: ubuntu-latest
    permissions:
      id-token: write   # 允许获取 OIDC token
      contents: read
    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v2
        with:
          role-to-assume: arn:aws:iam::123456789012:role/GitHubDeployRole
          aws-region: us-east-1

这里的关键是:GitHub Actions 通过 OIDC 协议,向 AWS 证明「我是 GitHub 上的这个仓库,正在跑这个工作流」。AWS 验证后,给一个临时角色凭证。整个过程不需要存储任何长期密钥。你想想看,是不是比把 AK/SK 写进代码里安全一万倍?

2.4.3 跨云联邦的常见模式

模式 适用场景 协议 我的经验
中心 IdP 统一认证 企业员工访问多个云控制台 SAML 2.0 适合人员固定的场景,配置一次管很久
CI/CD 工具获取云权限 自动化部署、流水线 OIDC 强烈推荐,比密钥轮转省心太多
跨云角色互信 AWS 角色访问 Azure 资源 OIDC / 自定义 需要两边都配置信任策略,比较繁琐

核心要点:无论用 SAML 还是 OIDC,永远不要共享长期凭证。联邦认证的核心价值就是「临时、动态、可撤销」。我见过有人为了省事,把 AWS 的 Access Key 直接发给 Azure 的虚拟机用,结果密钥泄露后,攻击者从 Azure 直接攻入了 AWS。嗯,这就是典型的「省小钱亏大钱」。

2.5 总结一下

IAM 这件事,说难不难,说简单也不简单。我的经验是:先想清楚谁需要什么,再动手配置。别一上来就写策略,先画个权限矩阵,把用户、组、角色、资源、动作列清楚。然后从最小权限开始,逐步放开。最后,一定要用联邦认证来统一管理多云身份。

你想想看,如果每个云都有一套独立的 IAM,光是密码轮转就能让你崩溃。所以,身份联邦不是可选项,而是多云安全的必选项

最后一个小技巧:定期审计 IAM 策略。我每季度会跑一次 IAM 策略扫描,看看有没有「Resource: *」或者「Action: *」的宽松策略。发现了就立刻收紧。安全这件事,偷懒不得。