亚马逊AWS官方博客

构建弹性身份基础设施:AWS IAM 和 STS 的多区域容灾最佳实践

在设计云架构时,我们通常关注应用层的韧性——负载均衡器、自动扩展组和多区域部署。然而,一个经常被忽视的关键组件是身份层本身。例如,如果您的身份认证流程依赖某一单一区域,当此区域发生故障时,您的团队可能将无法通过 AWS 身份验证并登录 AWS 账户,进而可能导致您无法按预期计划执行故障区域切换等应急响应操作。同样地,如果您的灾备区域应用依赖 AWS STS 的全局端点,一旦该端点所在区域(us-east-1)发生故障,本应正常工作的灾备应用也会因无法获取临时凭证而瘫痪。因此,在设计系统的整体容灾架构时,身份层的多区域容灾设计应与应用层的容灾设计一并考虑。

本文将详细介绍为 AWS Identity and Access Management (IAM),AWS IAM Identity Center 和 AWS Security Token Service (STS) 实施多区域灾难恢复的最佳实践。这些方法能够帮助组织在区域服务中断期间维持业务连续性。

理解风险

以下是关于 AWS Identity and Access Management (IAM),AWS IAM Identity Center 和 AWS Security Token Service (STS) 这些服务,如果设计架构或配置不正确,可能带来的可用性风险说明:

  • IAM Identity Center:许多用户使用该服务来集中管理人员登录 AWS 账户的身份和权限。在启用该服务时用户需选择在哪个区域创建该服务的实例,当该区域的 IAM Identity Center服务发生故障时,可能导致人员无法成功登录AWS账户,从而影响对于账户中的 AWS 资源的访问和操作。
  • IAM Identity Federation:借助该功能,用户可以将人员登录 AWS 账户时的身份认证委派至第三方的身份提供商(IdP),从而实现单点登录而无需在 AWS 账户内为人员创建 IAM User。用户若在对该功能进行配置时没有考虑多区域的冗余性,则一旦配置中所依赖的区域不可用,将可能导致人员无法成功登录AWS账户。
  • Security Token Service (STS):该服务可为用户或应用程序提供访问 AWS 资源的临时安全凭证。当该服务不可用时将无法获取临时凭据,进而影响对 AWS API 的调用。STS 服务同时提供了全局端点(sts.amazonaws.com)及区域(Region)端点(sts.<region-id>.amazonaws.com),但 STS 的全局端点依赖单个区域us-east-1),因此当该区域不可用的时候 STS 全局端点也不可用。

为了应对上述的风险,用户需要合理配置这些服务从而避免单一区域不可用时而无法登录 AWS 账户,并且也应提前部署破窗机制(Break-Glass)用于在紧急状况下仍可登录账户,以下是关于这些最佳实践的详细介绍。此外,我们建议用户在中断发生前部署这些配置,因为在区域中断发生期间可能无法成功创建这些配置。用户也需要定期测试这些配置和流程,以确保团队了解在区域服务出现中断时应该如何完成身份认证。

最佳实践 1:提前部署紧急破窗机制

当采用 AWS IAM Identity Center 或 IAM Identity Federation 进行集中身份认证时,用户应部署紧急破窗机制,用于在区域 IAM Identity Center 不可用或用户的 IdP 服务不可用时仍可以紧急登录 AWS 账户。破窗机制类似于放置在驾驶室里的紧急破窗锤,它平时不会被使用,但专门用于在联邦身份认证系统完全失效时,让管理员能够绕过所有常规登录流程,以预留的最高权限进入 AWS 账户进行抢险操作。

实施方案

创建紧急访问专用 IAM User,完全不依赖 IAM Identity Center 和外部 IdP 服务。IAM 采用分离的控制平面和数据平面设计,IAM User的修改、IAM 策略的变更等请求将发送到 IAM 控制平面,AWS 的海外全球区域共享同一个 IAM 控制平面,该控制平面运行在 us-east-1 区域。虽然该控制平面只运行在单区域,但是控制平面在接收到 IAM 的变更请求后,相应的 IAM 资源的变更将同步到所有用户已启用的 AWS 区域中的 IAM 数据平面。IAM 数据平面本质上是 IAM 控制平面配置数据的只读副本,负责处理来自本区域的请求的身份验证和鉴权。因此,即便某一 AWS 区域不可用,用户仍可在其他区域中完成 IAM 的身份验证和鉴权。所以,提前创建好紧急访问专用 IAM User 可以借助 IAM 的多区域高可用数据平面设计来确保始终可以通过身份验证和鉴权。以下是配置和使用该紧急访问专用 IAM User 的建议:

用户配置:

  • 创建至少2个紧急访问 IAM User(例如,breakglass-admin-1、breakglass-admin-2)。2个用户可以避免因其中一名用户无法使用而导致紧急时无法登录账户,例如当 MFA 损坏或无法联络到凭据持有者时
  • 启用控制台访问权限,使用强密码和随机生成的密码(至少 32 个字符)
  • 使用虚拟或硬件令牌强制执行多因素身份验证 (MFA)
  • 不要创建访问密钥(Access Key),除非紧急响应流程中必须要使用 AWS CLI/SDK
  • 设置密码策略,要求每 90 天轮换一次密码
  • 每次使用后应考虑立即更换密码
  • 附加 AdministratorAccess 管理策略
  • 将访问流程记录在您的事件响应手册中
  • 请确保您的 AWS Organizations SCP(服务控制策略)没有意外阻止这些紧急IAM User的访问权限,或者应将这些IAM User加入 SCP 的白名单。

安全凭证管理:

紧急凭证的挑战在于如何在紧急情况下平衡安全性和可访问性。既要保证其安全性,防止被盗用,又要保证在身份中心宕机时也能正常使用。用户应考虑采用多层级安全防护策略来保护紧急访问 IAM User 的凭证:

第 1 层:强密码

  • 至少 32 个字符,随机生成
  • 存储在安全离线地点(加密的 USB 驱动器、保险箱)
  • 为不同团队成员设立独立存储位置

第 2 层:多重身份验证(MFA)要求

  • 采用虚拟 MFA(Google 身份验证器、Authy)或硬件 MFA 设备(FIDO2 安全令牌)
  • 多个团队成员拥有自己独立的 MFA

第 3 层:策略强制的多重身份验证(MFA)

  • 即使有人获得了密码,也无法在没有 MFA 的情况下执行任何动作
  • 这防止了攻击者使用盗窃得到的凭证
  • 以下样例策略可挂载于紧急访问 IAM User上用于强制多重身份验证(MFA)
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "DenyAllActionsWithoutMFA",
      "Effect": "Deny",
      "Action": "*",
      "Resource": "*",
      "Condition": {
        "BoolIfExists": {
          "aws:MultiFactorAuthPresent": "false"
        }
      }
    }
  ]
}

监控与警报:

  • 通过 CloudTrail 记录所有临时IAM User活动
  • 设置 CloudWatch 警报在任何紧急访问 IAM User 登录时触发并通知安全团队

以下示例代码可用于在账户中添加针对紧急访问 IAM User 登录账户的监控。使用时请注意修改代码中的以下内容:

  • security-team@example.com更改为用户接收告警的邮箱地址:
  • 更改成之前配置的紧急访问 IAM User 的user name:
# Setup monitoring for all break-glass users
setup_breakglass_monitoring('breakglass-admin-1')
setup_breakglass_monitoring('breakglass-admin-2')

环境中需要安装 python,以及执行以下命令:

Shell
pip3 install boto3 "botocore[crt]"
import boto3

def setup_breakglass_monitoring(username):
    """Create CloudWatch alarm for break-glass user activity"""
    cloudwatch = boto3.client('cloudwatch')
    sns = boto3.client('sns')
    
    # Create SNS topic for alerts
    topic_response = sns.create_topic(Name='BreakGlassAlerts')
    topic_arn = topic_response['TopicArn']
    
    # Subscribe security team
    sns.subscribe(
        TopicArn=topic_arn,
        Protocol='email',
        Endpoint='security-team@example.com'
    )
    
    # Create metric filter for CloudTrail logs
    logs = boto3.client('logs')
    logs.put_metric_filter(
        logGroupName='/aws/cloudtrail/logs',
        filterName=f'BreakGlassLogin-{username}',
        filterPattern=f'{{ $.userIdentity.userName = "{username}" && $.eventName = "ConsoleLogin" }}',
        metricTransformations=[{
            'metricName': f'BreakGlassUserLogin-{username}',  # Make metric name unique per user
            'metricNamespace': 'Security/BreakGlass',
            'metricValue': '1',
            'defaultValue': 0
        }]
    )
    
    # Create alarm
    cloudwatch.put_metric_alarm(
        AlarmName=f'BreakGlassAccess-{username}',
        AlarmDescription=f'Alert when {username} logs in',
        MetricName=f'BreakGlassUserLogin-{username}',  # Match the unique metric name
        Namespace='Security/BreakGlass',
        Statistic='Sum',
        Period=60,
        EvaluationPeriods=1,
        Threshold=1,
        ComparisonOperator='GreaterThanOrEqualToThreshold',
        AlarmActions=[topic_arn],
        TreatMissingData='notBreaching'
    )
    
    print(f"Monitoring configured for {username}")
    print(f"Alerts will be sent to: {topic_arn}")

# Setup monitoring for all break-glass users
setup_breakglass_monitoring('breakglass-admin-1')
setup_breakglass_monitoring('breakglass-admin-2')

多账户访问设置:

在多账户的 AWS 环境中,我们建议采用集中式 IAM User 管理分散式角色(IAM Role)授权的模式,以确保在需要时, 可以在使用紧急访问 IAM User 登录后能够访问任何 AWS 账户。即:

  • 在专用账户中集中创建和管理上述的紧急访问 IAM User,例如使用安全账户或创建专用的紧急访问账户
  • 在其他账户中创建紧急访问 IAM 角色,该角色仅允许由紧急访问 IAM User 进行承担(AssumeRole)。该 IAM 角色可命名为 breakglass-admin-role 并附加 AdministratorAccess 管理策略。

以下是一个紧急访问 IAM 角色的信任策略的示例,请注意替换其中紧急访问 IAM User 的 ARN。

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "AWS": [
          "arn:aws:iam::<SECURITY_ACCOUNT_ID>:user/breakglass-admin-1",
          "arn:aws:iam::<SECURITY_ACCOUNT_ID>:user/breakglass-admin-2"
        ]
      },
      "Action": "sts:AssumeRole",
      "Condition": {
        "Bool": {
          "aws:MultiFactorAuthPresent": "true"
        }
      }
    }
  ]
}

最佳实践 2:使用区域 STS 端点

在2011年8月,AWS 发布了 STS 服务,当时该服务仅提供单一区域的全局端点(sts.amazonaws.com)仅运行在单个区域(us-east-1)。 为了使得工作负载可以调用本区域的 STS 服务来提升性能、避免跨区域依赖并减少单一区域故障带来的可用性风险,AWS STS 于 2015 年 2 月推出了区域端点(sts.<region-id>.amazonaws.com),并鼓励用户通过区域端点访问 STS 服务。因此目前的 STS 全局端点可被视为是传统(legacy)模式的端点。

然而,许多用户和第三方工具仍旧习惯于使用 STS 全局端点,所以并未得到 STS 区域端点带来的好处。因此,为了进一步优化 STS 服务的韧性,在2025年4月,AWS 对 STS 全局端点进行了变更。现在,发往 AWS STS 全局端点的请求将自动在请求发起的同一区域(而非 us-east-1)中处理。例如,若应用程序从 us-west-2 区域调用 STS 全局端点(sts.amazonaws.com),相关请求将由 us-west-2 区域处理,而非由 us-east-1 提供服务。

但该优化行为的生效有两个前提条件,不满足这两个条件的全局端点请求仍由 us-east-1 区域进行处理:

  • 条件 A: 解析amazonaws.com时,使用 Amazon DNS server(也称为 Route 53 Resolver)进行 DNS 解析。
  • 条件 B: 所在区域为默认开启的区域(即此表格中 opt-in status 为 “Not required” 的区域)

因此,为了获得最低的延迟、更高的区域隔离性,以及避免潜在的跨区域网络依赖,AWS 建议用户在应用中应该尽可能明确、显式的指定使用本区域的 STS 区域端点。有关 AWS STS 区域及其端点的列表,请参阅 AWS STS 区域和端点

实施方案

用户在应用中通过 AWS CLI/SDK 访问 STS 服务时应使用区域端点。2022 年 7 月之后发布的所有新 AWS CLI/SDK 的主要版本默认使用 STS 区域端点,会根据当前指定的区域访问对应的 STS 区域端点(例如在 AWS CLI 命令指定 –region us-west-2 后将访问 STS 的 us-west-2 区域端点),因此无需任何额外变更。

但在此之前发布的主要版本的 CLI/SDK(例如,AWS CLI v1,SDK for Java 1.x) 默认仍会使用全局端点,因此我们建议用户尽可能使用最新的主要版本的 CLI/SDK。此外,对于这些默认使用全局端点的 CLI/SDK 版本,用户可通过特定参数配置来使其使用 STS 区域端点。有关于不同版本的 AWS CLI/SDK 是否支持该参数配置,请参阅 AWS SDK 及工具对于 STS 区域端点的支持

该参数可设置两种取值:

  • 传统模式(legacy):使用 AWS STS 全局端点
  • 区域模式(regional):使用当前配置区域对应的 AWS STS 端点。例如,若客户端配置为使用 us-west-2 区域,所有 AWS STS 调用将发送至区域终端节点 us-west-2.amazonaws.com,而非全局终端节点 sts.amazonaws.com。若启用此设置后仍需向全局终端节点发送请求,可将区域设置为 aws-global

配置该参数有两种方式:

1. 使用共享的AWS配置文件

用户可以在 AWS 配置文件(在 Linux 或 macOS 上位于~/.aws/config,在 Windows 上位于 C:\Users\USERNAME.aws\config)中添加 sts_regional_endpoints 参数来控制 AWS CLI/SDK 是否使用 STS 区域端点。例如:

[default]
sts_regional_endpoints = regional

2. 使用环境变量

用户可通过设置名为 AWS_STS_REGIONAL_ENDPOINTS 的环境变量来配置该参数,例如在 Linux 系统上,可通过 export AWS_STS_REGIONAL_ENDPOINTS=regional 命令来指定 CLI/SDK 使用 STS 区域端点。

此外,除了使用该配置参数来控制 CLI/SDK 使用 STS 区域端点,用户也可在代码中通过指定 STS 的区域端点 URL 来强制使用某一区域的 STS 端点,例如:

import boto3
sts_client = boto3.client('sts', region_name='us-east-2', endpoint_url='https://sts.us-east-2.amazonaws.com')

最佳实践 3:在 IAM Identity Federation 设置中添加多个区域的 Sign-In 服务端点

有些用户会使用 IAM Identity Federation 功能通过 SAML2.0 协议来将自有 IdP 与 AWS IAM 联合,以用于通过自有 IdP 完成人员的身份验证并进行 AWS 账户的控制台登录。在此情况下,用户需要创建 IAM 角色(IAM Role)并将该角色的信任策略(Trust Policy)设置为信任用户的 IdP。以下是一个典型的信任策略示例:

{
  "Version":"2012-10-17",                                   
  "Statement": [
    {
      "Effect": "Allow",
        "Principal": {
          "Federated": "arn:aws:iam::111122223333:saml-provider/ExampleOrgSSOProvider"
        },
        "Action": "sts:AssumeRoleWithSAML",
        "Condition": {
          "StringEquals": {
            "SAML:aud": "https://<region-code>.signin.aws.amazon.com/saml"
          }
        }
    }
  ]
}

其中的 “SAML:aud” 条件用于验证 SAML 响应中的 saml:aud 属性是否匹配。控制台登录由 Sign-In 服务提供,因此该值应设置为 Sign-In 服务接收 SAML 响应的端点地址。Sign-In 服务为每个区域提供了独立的端点,各区域的端点 URL 可以参见 AWS Sign-In 端点

许多用户习惯于使用 us-east-1 区域的 Sign-In 服务端点(signin.aws.amazon.com)进行控制台登录,因此在设置上述的 IAM Role 的信任策略时,通常只将该服务端点设置为 “SAML:aud” 条件的允许值。此时,若 us-east-1 区域的 Sign-In 服务不可用,用户便无法通过 IAM Identity Federation 的 SAML 联合身份认证功能来登录 AWS 控制台。因此,我们建议用户在配置信任策略时应包含目前正在使用的所有区域。

实施方案

用户应在 IAM 角色的信任策略的 Condition 字段中配置多个区域的 Sign-In 端点 URL。如果用户目前只使用了一个区域,也应考虑配置一个额外的区域端点 URL 用以实现多区域冗余。例如,若用户目前只在 us-east-1 区域部署了资源,也应在配置中增加第二个区域端点 URL(如 us-west-2)。在 Condition 字段中配置多个 Sign-In 端点 URL 的示例如下:

"Condition": {
  "StringEquals": {
    "SAML:aud": [
      "https://us-east-2.signin.aws.amazon.com/saml",
      "https://us-west-1.signin.aws.amazon.com/saml",
      "https://us-west-2.signin.aws.amazon.com/saml",
      "https://signin.aws.amazon.com/saml"
    ]
  }
}

完成上述 AWS IAM 配置后,当某一区域的 Sign-In 服务不可用时,用户便可在 IdP 的配置中修改 SAML ACS 的 URL 来使用其他区域的 Sign-In 服务。例如,若 IdP 中设置的 SAML ACS 的 URL 是 “https://signin.aws.amazon.com/saml”,当 us-east-1 的 Sign-In 服务不可用时,用户将无法通过 SAML 登录 AWS 控制台。此时,用户可将 IdP 中的 SAML ACS 修改为在 IAM 角色的信任策略中设置的其他区域的 Sign-In 服务的端点 URL,后续的 SAML 登录响应便会由该区域的 Sign-In 服务来处理。

说明:SAML ACS 即 Assertion Consumer Service(断言消费服务),是服务提供方(在上述场景下 Sign-In 服务即是服务提供方)侧的端点,用于接收并处理 IdP 返回的 SAML 响应(含身份断言),完成验证、提取用户信息并建立会话。

此外,如果在 IdP 中指定了 SAML RelayState 地址(RelayState 地址用于告知服务提供方在 SAML 认证流程结束后的跳转地址), 在修改 SAML ACS 的地址时,应将 RelayState 设置为相同区域的端点地址以增强用户的登录体验,避免因 RelayState 所设置的控制台页面区域不可用而导致跳转后的页面无法打开。例如,假设 ACS 地址被修改为 us-west-2 区域的端点,则 RelayState 的地址建议同步修改为 “https://us-west-2.console.aws.amazon.com/…”。

每个 IdP 设置 ACS 和 RelayState 的步骤都不同。有关于如何修改 IdP 中这些配置,请参阅所使用的 IdP 的文档。
此外,在 IdP 中修改 ACS URL 通常需要 IdP 管理员权限。在发生故障的紧急情况下,这需要跨团队协作。因此,提前在 Runbook(运维手册)中记录详细的 IdP 修改步骤至关重要。

结论

身份基础设施的弹性设计通常比应用层灾难恢复受到的关注更少,但它同样至关重要。当身份验证系统出现故障时,即使是已经实施了多区域冗余,应用也可能由于缺少必要的权限而无法正常工作,同时,开发和运维人员可能也会由于认证失败而无法执行紧急灾备响应相关操作。

本文针对构建弹性身份基础设施提供了三项最佳实践建议,包括提前部署紧急访问机制、使用区域 STS 终端节点、在 IAM Identity Federation 设置中添加多个区域的 Sign-In 服务端点。用户应检查当前的灾备设计是否有考虑相关的风险,并参考本文中的实施建议在事故来临之前完成相应的应对。

*前述特定亚马逊云科技生成式人工智能相关的服务目前在亚马逊云科技海外区域可用。亚马逊云科技中国区域相关云服务由西云数据和光环新网运营,具体信息以中国区域官网为准。

本篇作者

陈家慧

亚马逊云科技安全专家,负责亚马逊云科技安全类产品,有15年工作经验,曾在甲方和乙方都做过安全,主导开发多个安全项目。对数据安全,身份安全领域拥有丰富经验。致力于亚马逊云安全服务在国内的应用和推广。

王旭东

亚马逊云科技安全产品解决方案架构师,负责帮助客户进行安全解决方案的架构设计。在加入亚马逊云科技之前,曾在互联网 SaaS 企业负责公司基础架构安全建设及治理。

AWS 架构师中心: 云端创新的引领者

探索 AWS 架构师中心,获取经实战验证的最佳实践与架构指南,助您高效构建安全、可靠的云上应用