
你的 AWS 帐户需要妥善保护,这不仅是为了保护客户数据,同时也是为了增强应用程序的可用性。对于生产环境中的工作负载这一点尤为重要,我们需要完全确信谁能访问每个账户,可以获得何种级别的权限,并能从整个组织层面上管理用户,而不用分别管理每个系统。

无论配置了多少策略和流程,最终总会有人分享自己本不应分享的帐户或安全密钥!通过配合使用 SAML Identity Provider 和 Active Directory 则可以有效解决这个问题!
虽然我们已经可以通过一些预配置的选项,例如使用 AWS SSO 作为 SAML 提供程序,但这种做法依然需要使用 AD Connector 将 AD 扩展到 AWS,使其成为 AWS Directory Services 的一部分,这也意味着我们需要实施 VPN 或 Direct Connect,但这并非始终都是最适合的方法,有时候甚至根本不可行!就算我们将 AD 扩展到 AWS,也无法直接实现 AWS SSO,我们还需要使用 ADFS 构建自己的解决方案。
为了构建这样的解决方案,我们需要使用多种组件:
Active Directory
一个或多个 AWS 帐户
理论
我打算从较高层面介绍这些组件如何协同工作,因为这其中涉及很多组件和依赖项。
为了成功登录,用户需要访问一个备用 URL(例如awsconsole.domain.com),而不能访问传统的控制台 URL。该 URL 会将用户重定向至 SAML 提供程序,对其进行身份验证,随后允许用户访问特定的 AWS 帐户。
能否访问 AWS 帐户,这是由一系列组件共同决定的:用户在 AD 中隶属的组,以及 AWS 中创建的 IAM 角色。AD 中的组需要具备与 IAM 角色相关的名称。随后 IAM 角色还必需具备必要的权限,以便让用户在通过身份验证后获得所需的权限级别。
IAM 角色与“用户”不同,并不包含访问密钥和机密密钥,而是会生成一组临时凭据,这些凭据在过期前可使用一段时间,在过期后则要重新生成。如果希望详细理解该过程的工作原理,建议阅读STS(安全令牌服务)文档。
这个解决方案不仅适用于控制台,也适用于 CLI。通常我会使用一款名为saml2aws的工具来简化身份验证过程,借此实现以编程方式进行的访问,现在,则可以用它来取代硬编码的 IAM。
另外还要注意,该解决方案可支持用于多个帐户!
SAML 基本概念
在深入介绍配置过程前,首先有必要简要了解一些与 SAML 有关的基本概念和术语。如果你以前从未使用过 SAML,那么更有必要了解一下这些术语:
标识提供程序(Identity Provider,IdP):身份验证信息的来源,例如本例中的 ADFS 就是一种 IdP。
服务提供程序(Service Provider,SP):负责使用 IdP 进行身份验证的应用程序。对于 ADFS,SP 也可以叫做依赖方信任(Relying Party Trust,RPT)。本例中的 SP 是 AWS。
声明规则(Claim Rule):断言过程中需要发送的一系列信息,其中包含了诸如用户名和组等信息。
断言(Assertion):作为令牌从 IdP 发送给 SP 的信息。
此处需要注意,IdP 和 SP 绝对不会直接通信,发生的所有通信都是通过最终用户的浏览器进行的。IdP 和 SP 只是能简单地感知对方的存在,如下所示:

配置 ADFS
首先我们需要在 ADFS 中配置一个新的依赖方信任,为此可以使用 ADFS 中的 RPT 向导。AWS 通过一个 XML 文件公开提供了自己的 SAML 元数据,该 XML 文件可以直接引用到你自己的 IdP 中。在添加了诸如联合身份验证元数据和 RPT 名称等初始信息后,即可使用默认设置完成向导的其他操作。

向导操作完成后,应该可以在你自己的 ADFS 服务器的 RPT 列表中看到一项有关 AWS 的内容。随后我们需要在 ADFS 中配置声明规则,这些规则可以将需要身份验证的用户的相关信息作为断言的一部分发送给 AWS。右键点击 AWS RPT 并选择“编辑声明规则”即可。

规则 1
将 Windows 帐户名映射给发送给 AWS 的断言中的 NameID 一节。

规则 2
将用户的电子邮件地址映射至发送给 AWS 的断言中的 RoleSessionName 特性。

规则 3
获取用户所属的 AD 组列表。这样一旦用户的 AWS 帐户成功通过了身份验证,就可以使用这些 AD 组。

规则 4
将 AD 组列表转换为与 AWS 中所创建的 IAM 角色相匹配的格式。

规则 5
设置会话令牌的有效期。我们通常将其设置为 10 小时(对于典型的工作日来说已经足够长了)。

配置 AWS
ADFS 配置完毕后,该配置我们的 AWS 帐户了。对于任何希望使用 SAML 验证身份的帐户,都需要执行下列操作(或作为帐户自动化操作过程的一部分来执行)。
配置标识提供程序
打开 IAM > Identity Providers,新建一个提供程序,随后向 AWS 提供如下信息:
提供程序类型:SAML
提供程序名称:ADFS
元数据文档:上传下列地址包含的某个可用文档: https://fs.yourdomain.com/FederationMetadata/2007–06/FederationMetadata.xml

创建一个 IAM 角色
随后需要新建一个 IAM 角色。用户登录 AWS 帐户时需要使用该角色。请打开 IAM > Roles,随后新建一个角色。

接下来需要为该角色分配权限,借此用户才能以这个角色的身份执行各种操作。本例中将提供 ReadOnlyAccess 权限。

在最后一个界面上,可以将该角色命名为 AWS-GavinSandbox-ROA。角色名称中一定要包含“AWS”字样,因为我们的组转换信息中需要包含该字样。

配置用户组
随后我们需要在 Active Directory 中创建与 AWS 帐户中角色信息相匹配的用户组。组名称的格式必需为AWS--
,请酌情替换 Account ID 和 IAM 角色名称。

组创建完毕后,我们需要为其分配用户,例如此处分配了我本人:

创建一个 S3 Website Bucket
这一步并非必需,但可以让通过 SAML 访问 AWS 帐户的过程变得更简单。借此可以让用户访问一个 URL(例如awsconsole.domain.com)来访问 AWS 控制台,而不需要手工访问你的 IdP 然后选择 SP。
在你的某一个 AWS 帐户(例如组织内部,配置了特定 SCP 策略的核心基础架构相关帐户)中创建一个 S3 Website Bucket,将其命名为awsconsole.domain.com(请酌情替换domain.com)。将该 Bucket 配置为静态网站托管,然后选择执行重定向的选项:

创建完成后,在 DNS 中新建一条记录,借此将 awsconsole.domain.com 指向 S3 Bucket。
测试
接下来可以开始试运行一下了。请在浏览器中输入 URL:awsconsole.domain.com。随后首先会看到浏览器窗口将你重定向至 IdP 并自动进行身份验证,或要求登录(具体行为取决于配置)。
随后可以看到自己能够访问的帐户列表,选择一个角色并点击登录。

假设一切正常无误,接下来就可以用刚才选择的角色成功登录自己的帐户了!

总结
为了进一步提高该解决方案的安全性,我们还可以考虑实施 MFA,借此进一步降低他人 AD 帐户被攻陷,以至于攻击者借此访问多个系统的风险。
上述操作看起来似乎很繁琐,并且最初需要做大量工作,但长远来看,以后只需要添加额外的 AD 组并配置 AWS 帐户就够了。最终这些操作还可以实现自动化,为此需要使用我开发的一个虽然简陋但已实用的 Serverless 工具:account factory,当然,市面上也有很多其他类似的工具可供选择。
本文最初发布于The Startup博客,原作者Gavin Lewis,经原作者授权由 InfoQ 中文站翻译并分享。
英文原文:
Securing your AWS Accounts with SAML Authentication
评论