AWS IAM角色最佳实践:构建安全云架构的核心指南

本文深入探讨了AWS IAM角色的核心概念、类型及最佳安全实践,涵盖了从识别保护、威胁检测到自动响应的完整安全生命周期,旨在帮助构建安全、可控的云身份与访问管理体系。

AWS IAM角色最佳实践

Amazon Web Services 是一家领先的云服务提供商,提供从简单的实例机器到无服务器数据集成服务等一系列工具和服务。虽然 AWS 上有数百种不同的服务,但有一个服务统领全局:AWS 身份和访问管理(IAM)。

从设计上讲,AWS 是一个云平台,其中每个实体都需要获得许可才能访问和利用资源与服务。实体范围从用户和虚拟机一直到原生的 AWS 服务。是的,即使是内置的 AWS 服务也需要获得许可才能访问其他 AWS 服务。这种设计理念将 IAM 置于一切的中心,而 IAM 的主要功能——IAM 角色——则定义了其核心的权限和特权。

什么是 IAM 角色?

IAM 角色是您可以在账户中创建的具有特定权限的 IAM 身份。IAM 角色类似于 IAM 用户,它是一种 AWS 身份,具有权限策略,决定了该身份在 AWS 中能做什么和不能做什么。然而,角色并不唯一地与某个人相关联,而是旨在由任何需要它的人承担。角色没有与之关联的长期凭证(控制台密码、标准访问密钥),它们拥有通过安全令牌服务(STS)授予的短期凭证。每次服务主体想要承担角色时,它都会调用安全令牌服务(STS),如果获得允许,它将收到包含临时安全令牌的响应。

有不同类型的服务主体可以承担 IAM 角色。我大致将它们分为用户和服务。

  1. 用户是代表个人的实体;该实体具有与之关联的名称和凭证。虽然这不是官方分类,但我将面向用户的角色称为“用户角色”。
  2. 服务实体可以是代表您执行操作的原生 AWS 服务,也可以是运行在 AWS 服务(如 EC2 和 Lambda)上的应用程序。原生 AWS 服务预定义了角色,这些角色授予它们代表用户访问其他 AWS 服务所需的所有权限;它们被称为“服务关联角色”。运行在 EC2、Elastic Beanstalk 或 Lambda 上的应用程序是自定义构建的,通常需要“自定义 IAM 角色”,因此我这样称呼它们。

实际上,角色是通用的,任何被允许的实体都可以承担它。考虑到用户可以使用 IAM 角色,而数百种原生服务专门使用 IAM 角色,我们最终会面临这样一个场景:拥有大量的 IAM 角色,并且新的角色还在不断涌现。

我概述了应对 IAM 潜在风险的最佳实践。为了条理清晰,这些最佳实践按照识别、预防、检测、响应和补救这几个阶段进行排序。

我坚信这个助记口诀:“识别所有资产,预防威胁,检测无法预防的威胁,响应检测到的威胁并补救其后果”。

识别与保护

1. 锁定您的 AWS 账户根用户

首次创建 Amazon Web Services (AWS) 账户时,您会获得一个对账户中所有 AWS 服务和资源拥有完全访问权限的身份。此身份称为 AWS 账户根用户。任何拥有您 AWS 账户根用户凭证的人都可以不受限制地访问您账户中的所有资源。根凭证的泄露危害极大。

a. 我建议不要在日常任务(甚至是管理任务)中使用根用户。相反,仅使用根用户凭证来创建您的 IAM 管理员用户。 b. 要么禁用根用户的访问密钥,要么直接删除它。 c. 使用强密码甚至随机密码来限制根用户。 d. 为根用户强制执行多因素认证。

2. 优先为所有服务主体使用 IAM 角色,但要限制其使用

a. 对于用户:优先为内部用户和第三方用户使用 IAM 角色。使用 SAML 2.0 角色是合适的。根据信任策略文档限制对角色的访问,仅允许匹配特定 SAML 属性(例如 SAML 隶属关系)的用户。同时,使用 aws:SourceIp 条件基于用户的源 IP 地址限制访问。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
{
    “Version”: “2012–10–17”,
    “Statement”: [{
        “Effect”: “Allow”,
        “Principal”: {“Federated”: “arn:aws:iam::account-id:saml-provider/ExampleOrgSSOProvider”},
        “Action”: “sts:AssumeRoleWithSAML”,
        “Condition”: {
            “StringEquals”: {
                “saml:aud”: “https://signin.aws.amazon.com/saml",
                “saml:iss”: “https://openidp.feide.no"
            },
            “ForAllValues:StringLike”: {“saml:edupersonaffiliation”: [“staff”]},
            “StringEquals”: { “aws:SourceIp” : “x.x.x.x” }
        }
    }]
}

b. 对于 EC2 实例和 Lambda 函数:无法直接在 IAM 角色的信任策略中使用来限制其仅用于特定实例。Lambda 也存在同样的问题。我建议至少使用诸如 aws:SourceVpc 这样的条件来限制访问,确保角色仅限于来自受信任 VPC 的资产。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
{
    “Version”: “2012–10–17”,
    “Statement”: [
        {
            “Effect”: “Allow”,
            “Principal”: { “Service”: “ec2.amazonaws.com” },
            “Action”: “sts:AssumeRole”,
            “Condition”: {
                “StringLike”: { “aws:SourceVpc”:  arn:${Partition}:ec2:${Region}:${Account}:vpc/${VpcId} }
            }
        }
    ]
}

3. 用于管理任务的即时访问

传统上,用户在访问受保护资源之前必须经过身份验证和授权。身份验证通常是一次性事件,这意味着用户拥有持久访问权限,可以随时调用。调用访问的过程不考虑每次调用的具体原因。

“即时”方法考虑了临时提升的访问权限,也称为即时访问,用于处理关键权限。用户必须像以前一样经过身份验证和授权——但除此之外,每次用户调用访问权限时,都会启动一个额外的流程,其目的是识别并记录在此特定场合调用访问权限的业务原因。该流程可能涉及其他人员,也可能使用自动化。流程完成后,仅当业务原因合适时,才授予用户访问权限。

虽然我们通常可以将某些权限标记为关键权限,但大多数权限与它们在 AWS 生产账户中的相关性相关,具有一定主观性。IAM 是被普遍接受的关键权限之一,因此我建议阻止以下 IAM 操作,仅通过“即时”系统允许它们:

“iam:Add*”, “iam:Attach*”, “iam:Create*”, “iam:Deactivate*”, “iam:Delete*”, “iam:Detach*”, “iam:Put*”, “iam:Remove*”, “iam:Set*”, “iam:Update*”, “iam:Upload*”

AWS 有一个“即时”访问系统的模板,许多 CSPM 和 PAM 供应商也提供商业解决方案来满足这一需求。

检测

1. 检测 IAM 角色枚举

恶意行为者会使用多种技术来枚举 AWS 账户的 IAM 角色。

a. 一种简单但初级的方法是使用 IAM 角色名字典暴力尝试 sts assume-roleaws sts assume-role –role-arn arn:aws:iam::<<ACCOUNTID>>:<<ROLE>> 一种检测机制是在 CloudTrail 日志中监控连续失败的 sts assume-role 请求。

b. 一种更隐蔽的方法是使用 UpdateAssumeRolePolicy 方法,恶意行为者拥有自己的账户,他们尝试在信任策略部分使用 UpdateAssumeRolePolicy 文档,为受害者账户中的角色提供承担其账户中角色的权限。如果操作成功,则证实了该角色在受害者账户中存在。这种技术仅在恶意行为者的账户中生成 CloudTrail 日志,而不会在受害者的 CloudTrail 日志中记录枚举尝试。更多信息请参考 Rhinosecuritylabs 的文章和图 (1.)。

虽然这种技术本身难以检测,但风险较低。作为一种替代补救措施,我建议运行模拟同类攻击,以识别潜在的泄漏,并可能重命名这些 IAM 角色。文章中的 iam_user_enum.py 脚本可以帮助完成此练习。

2. 检测可疑访问

虽然没有明确的方法来识别可疑的访问事件,但确实存在一些蛛丝马迹。

a. 监控 IP 地址:监控 IP 地址有助于我们识别 API 调用来源的性质,特别是其信誉;即,该 IP 地址是否与恶意声誉相关联,来源是否试图通过 TOR 网络、防弹托管或其他代理服务传输请求来混淆其 IP 地址。 b. 可疑的用户代理:伴随 API 调用或控制台登录的另一个产物是用户代理。user-agent 标头参数描述了源主机,特别是操作系统;一个明显的危险信号是操作系统如果是 Kali Linux 或其他为攻击性安全设计的操作系统。 c. 多地登录 / “超人”登录:多地登录或“超人”登录事件也暗示了可疑行为。虽然多地登录很容易检测,但“超人”登录则不然。“超人”登录指的是用户从一个地理位置登录,随后又从另一个遥远的、不可行的地理位置登录,除非你能像超人一样快速飞行。

上述事件可以通过注入 CloudTrail 日志来检测,但更简单的方法是使用原生工具:Amazon GuardDuty。

3. 检测 IAM 权限提升技术

理想情况下,所有 IAM 的写入和删除权限都应通过“即时”访问机制进行保护,如上一节所述。如果未实施“即时”机制,我们需要监控可能用于权限提升的 IAM 事件。可以使用 CloudWatch 在 CloudTrail 日志中监控这些事件。事件列表如下:

用户事件iam:CreateUser, iam:CreateLoginProfile, iam:AddUserToGroup, iam:UpdateProfile, iam:PutUserPolicy, iam:AttachUserPolicy

组事件iam:CreateGroup, iam:PutGroupPolicy

角色事件iam:CreateRole, iam:CreateInstanceProfile, iam:PutRolePolicy, iam:AttachRolePolicy, iam:UpdateAssumeRolePolicy

策略事件iam:CreatePolicy, iam:CreatePolicyVersion

其中一些操作也可能被恶意行为者用来在受害者账户中实现持久化:iam:CreateUser, iam:CreateRole, iam:CreateAccessKey, iam:UpdateAssumeRolePolicy

响应与补救

自动化事件响应

虽然检测潜在的权限提升技术和可疑访问很有帮助,但及时响应是关键,自动化事件响应是实现这一目标的适当方式。在云中有多种方法可以实现自动化事件响应;其中大多数需要使用无服务器函数。无服务器函数从设计上讲是事件驱动的、简短的代码片段,通常目的明确,因此非常适合用于事件响应。有许多针对 AWS 事件响应的开源项目;CloudBots 就是其中之一。它是由 Check Point 软件技术公司维护的一个项目,建立在 CloudGuard 持续合规能力之上。它们也可以独立使用,无需 CloudGuard,来补救 AWS 账户中的问题。

我建议至少为以下用例部署 CloudBots:

a. 删除根用户的访问密钥:如果为根用户创建了未经授权的访问密钥,CloudBot iam_delete_access_key.py 可以删除它们。 b. 撤销权限提升 — 分离策略:如果发生因 IAM 角色操作导致的疑似权限提升事件,CloudBot iam_detach_policy.py 可以分离 IAM 策略,或者 iam_quarantine_role.py 可以向有问题的 IAM 策略添加显式的“全部拒绝”。

典型的自动化事件响应解决方案可以利用 CloudTrail 日志、CloudWatch 警报、SNS 和在 Lambda 上运行的 CloudBots 来构建。请参考图表 (2.) 并参考 CloudBots 项目以获取更多信息。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计