8 分钟实战:手把手教你用 SAML 保障 AWS 账户安全

阅读数:489 2019 年 10 月 21 日 14:08

8分钟实战:手把手教你用SAML保障AWS账户安全

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

8分钟实战:手把手教你用SAML保障AWS账户安全

无论配置了多少策略和流程,最终总会有人分享自己本不应分享的帐户或安全密钥!通过配合使用 SAML Identity Provider 和 Active Directory 则可以有效解决这个问题!

虽然我们已经可以通过一些预配置的选项,例如使用 AWS SSO 作为 SAML 提供程序,但这种做法依然需要使用 AD Connector 将 AD 扩展到 AWS,使其成为 AWS Directory Services 的一部分,这也意味着我们需要实施 VPN 或 Direct Connect,但这并非始终都是最适合的方法,有时候甚至根本不可行!就算我们将 AD 扩展到 AWS,也无法直接实现 AWS SSO,我们还需要使用 ADFS 构建自己的解决方案。

为了构建这样的解决方案,我们需要使用多种组件:

  1. Active Directory
  2. ADFS
  3. 一个或多个 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 只是能简单地感知对方的存在,如下所示:

8分钟实战:手把手教你用SAML保障AWS账户安全

配置 ADFS

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

复制代码
联合身份验证元数据地址:
https://signin.aws.amazon.com/static/saml-metadata.xml

8分钟实战:手把手教你用SAML保障AWS账户安全

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

8分钟实战:手把手教你用SAML保障AWS账户安全

规则 1

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

复制代码
规则名称:NameId
声明规则模板:转换传入声明

8分钟实战:手把手教你用SAML保障AWS账户安全

规则 2

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

复制代码
规则名称:RoleSessionName
声明规则模板:以声明方式发送 LDAP 特性
传出声明类型:https://aws.amazon.com/SAML/Attributes/RoleSessionName

8分钟实战:手把手教你用SAML保障AWS账户安全

规则 3

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

复制代码
规则名称:Get AD Groups
声明规则模板:使用自定义规则发送声明
自定义规则:
c:[Type == “http://schemas.microsoft.com/ws/2008/06/identity/claims/windowsaccountname", Issuer == “AD AUTHORITY”]
=> add(store = “Active Directory”, types = (“http://temp/variable"), query = “;tokenGroups;{0}”, param = c.Value);

8分钟实战:手把手教你用SAML保障AWS账户安全

规则 4

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

复制代码
规则名称:Group Transformer
声明规则模板:使用自定义规则发送声明
自定义规则:
c:[Type == "http://temp/variable", Value =~ "(?i)^AWS-([\d]{12})-"]
=> issue(Type = "https://aws.amazon.com/SAML/Attributes/Role", Value = RegExReplace(c.Value, "AWS-([\d]{12})-", "arn:aws:iam::$1:saml-provider/ADFS,arn:aws:iam::$1:role/AWS-"));

8分钟实战:手把手教你用SAML保障AWS账户安全

规则 5

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

复制代码
规则名称:SessionDuration
声明规则模板:使用自定义规则发送声明
自定义规则:
=> issue(Type = "https://aws.amazon.com/SAML/Attributes/SessionDuration", Value = "36000");

8分钟实战:手把手教你用SAML保障AWS账户安全

配置 AWS

ADFS 配置完毕后,该配置我们的 AWS 帐户了。对于任何希望使用 SAML 验证身份的帐户,都需要执行下列操作(或作为帐户自动化操作过程的一部分来执行)。

配置标识提供程序

打开 IAM > Identity Providers,新建一个提供程序,随后向 AWS 提供如下信息:

8分钟实战:手把手教你用SAML保障AWS账户安全

创建一个 IAM 角色

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

8分钟实战:手把手教你用SAML保障AWS账户安全

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

8分钟实战:手把手教你用SAML保障AWS账户安全

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

8分钟实战:手把手教你用SAML保障AWS账户安全

配置用户组

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

8分钟实战:手把手教你用SAML保障AWS账户安全

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

8分钟实战:手把手教你用SAML保障AWS账户安全

创建一个 S3 Website Bucket

这一步并非必需,但可以让通过 SAML 访问 AWS 帐户的过程变得更简单。借此可以让用户访问一个 URL(例如 awsconsole.domain.com )来访问 AWS 控制台,而不需要手工访问你的 IdP 然后选择 SP。

在你的某一个 AWS 帐户(例如组织内部,配置了特定 SCP 策略的核心基础架构相关帐户)中创建一个 S3 Website Bucket,将其命名为 awsconsole.domain.com 请酌情替换 domain.com )。将该 Bucket 配置为静态网站托管,然后选择执行重定向的选项:

复制代码
目标:fs.domain.com/adfs/ls/idpinitiatedsignon.aspx?logintorp=urn:amazon:webservices
协议:https

8分钟实战:手把手教你用SAML保障AWS账户安全

创建完成后,在 DNS 中新建一条记录,借此将 awsconsole.domain.com 指向 S3 Bucket。

测试

接下来可以开始试运行一下了。请在浏览器中输入 URL: awsconsole.domain.com 。随后首先会看到浏览器窗口将你重定向至 IdP 并自动进行身份验证,或要求登录(具体行为取决于配置)。

随后可以看到自己能够访问的帐户列表,选择一个角色并点击登录。

8分钟实战:手把手教你用SAML保障AWS账户安全

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

8分钟实战:手把手教你用SAML保障AWS账户安全

总结

为了进一步提高该解决方案的安全性,我们还可以考虑实施 MFA,借此进一步降低他人 AD 帐户被攻陷,以至于攻击者借此访问多个系统的风险。

上述操作看起来似乎很繁琐,并且最初需要做大量工作,但长远来看,以后只需要添加额外的 AD 组并配置 AWS 帐户就够了。最终这些操作还可以实现自动化,为此需要使用我开发的一个虽然简陋但已实用的 Serverless 工具: account factory ,当然,市面上也有很多其他类似的工具可供选择。

本文最初发布于 The Startup 博客,原作者 Gavin Lewis ,经原作者授权由 InfoQ 中文站翻译并分享。

英文原文:

Securing your AWS Accounts with SAML Authentication

欲了解 AWS 的更多信息,请访问【AWS 技术专区】

评论

发布