亚马逊AWS官方博客

在带有 Amazon Fargate 的 Amazon ECS 上的 Linux 容器上使用 gMSA 进行 Windows 身份验证

简介

我们于近日宣布可将 Credentials FetcherAmazon Elastic Container Service(Amazon ECS)上的 Amazon Fargate 集成。通过此次发布,您可以选择使用 Amazon Elastic Compute Cloud(Amazon EC2)启动类型以及 Amazon Fargate 无服务器计算启动类型在 Amazon ECS 上运行 Linux 容器。

在此版本之前,在 Amazon ECS 上运行依赖于组托管服务账户(gMSA)作为 Linux 容器的应用程序仅限于在加入域或无域的 Amazon EC2 实例上运行。借助 Amazon Fargate 支持,您可以将应用程序现代化改造为 Linux 容器,同时通过 gMSA 使用 Windows 身份验证,而无需预置、维护、修补和扩展虚拟机。

本文章利用博客在 Amazon ECS 上的 Linux 容器上搭配使用 Windows 身份验证和 gMSA 中探讨的大部分概念。本文章中提供了相关部分的链接。

解决方案概述

要探索 gMSA 对 Amazon Fargate 上的 Linux 容器支持的工作原理,需要部署和探索以下示例解决方案:

图 1:示例解决方案架构图

您将部署:

部署这些组件后,您将为创建的 gMSA 帐户生成凭证规范(CredSpec)文件,并将其上传到 Amazon S3,Credentials Fetcher 将在其中检索它。最后,您将在 Amazon ECS 上的 Linux 容器中构建和部署简单的.NET Web 应用程序。该应用程序配置为使用集成 Windows 身份验证来安全地连接到数据库。

示例解决方案使用 AWS Cloud Development Kit(AWS CDK)通过 TypeScript 预置云资源。AWS CDK 可让开发人员使用各种熟悉的编程语言构建 AWS 基础设施,包括 JavaScript、C#、Python、Java 和 Go。

在进行任何生产部署之前,您应始终咨询当地安全团队,根据您的环境和安全状况审查安全控制和要求。

先决条件

为完成本教程,您应该具备以下先决条件:

部署基础设施

首先,在本地计算机上创建示例解决方案目录。将此 GitHub 存储库克隆到该目录中。

在克隆存储库的 cdk 目录中打开终端,将 {KEY_PAIR_NAME} 替换为您的 Amazon EC2 密钥对名称,并且如果您使用的是 Bash,请运行以下命令:

export AWS_DEFAULT_REGION={YOUR REGION}
导出 EC2_INSTANCE_KEYPAIR_NAME="{KEY_PAIR_NAME}"
export MY_SG_INGRESS_IP=$(curl checkip.amazonaws.com)
export FARGATE=1

npm install
cdk deploy "*" --require-approval "never"

如果您使用的是 PowerShell,请运行以下命令:

$Env:AWS_DEFAULT_REGION = "{YOUR REGION}"
$Env:EC2_INSTANCE_KEYPAIR_NAME = "{KEY_PAIR_NAME}"
$Env:MY_SG_INGRESS_IP = $(Invoke-WebRequest -URI https://checkip.amazonaws.com).ToString().Trim()
$Env:FARGATE = 1   

npm install
cdk deploy "*" --require-approval "never"

这将开始部署包含示例解决方案的三个 AWS CloudFormation 堆栈。大约需要一小时才能完成部署。

部署完成后,导航到 AWS CloudFormation 控制台。此时将显示类似于下图的内容:

图 2:AWS 管理控制台中的 CloudFormation 资源

部署期间,在 AD 中创建安全组、用户和 gMSA。用户被设置为安全组的成员,该安全组有权从 gMSA 检索密码。AD 用户的密码是随机生成的并存储在密钥中,其名称为:

aws/directory-services/[directory-id]/seamless-domain-join.

演练

在以下部分中,您将探索如何配置 Amazon ECS 和 Credentials Fetcher 以为 Web 应用程序提供 Windows 身份验证。

配置 Credentials Fetcher 和 Active Directory

Credentials Fetcher 负责从 gMSA 获取 Kerberos 票证并将其提供给 Linux 容器。使用 Amazon EC2 实例时,需要在每个实例中安装 Credentials Fetcher。在 Amazon Fargate 上,Credentials Fetcher 是开箱即用的。

以下内容代表 Amazon Fargate 和 Credentials Fetcher 向容器提供 Kerberos 票证所遵循的流程:

图 3:Amazon Fargate 和 Credentials Fetcher 流程

  1. 用户或 Amazon ECS 服务请求新的 Fargate 任务。
  2. Amazon ECS 集群启动一个新的 Fargate micro-VM 并将要启动的任务定义发送到 ECS 代理。
  3. ECS 代理将 Credentials Fetcher 作为 ECS 托管的进程守护程序启动。
  4. Credentials Fetcher 从任务定义的 credentialSpecs 属性中检索 CredSpec 位置。*
  5. Credentials Fetcher 从 CredSpec 的 HostAccountConfig 对象中定义的 AWS Secrets Manager 密钥中检索要使用的 AD 用户和域。**
  6. Credentials Fetcher 从相应的 AD 域控制器检索 Kerberos 票证。***
  7. Credentials Fetcher 将 Kerberos 票证存储在本地微型虚拟机存储空间中,并与 ECS 代理共享该位置。
  8. ECS 代理启动任务定义容器,将 Kerberos 票证位置挂载到该容器。

* Credentials Fetcher 需要一个安全主体进行 AD 身份验证并检索 gMSA 密码。对于 Fargate 任务,您应该使用有权直接或通过 AD 安全组检索 gMSA 密码的 AD 用户。

该示例解决方案将创建并使用名为 SampleWebAppGmsaPrincipals 的 AD 安全组来访问 gMSA 密码。

**CredSpec 文件是一个 JSON 文档,其中包含有关每个容器中使用的 gMSA 账户的元数据。Credentials Fetcher 使用 CredSpec 文件请求 Kerberos 票证,然后将其提供给容器。只有以 AD 的管理员用户身份登录时,才能在 Windows 计算机中生成 CredSpec 文件。

要生成 CredSpec 文件,请按照上一篇博客中概述的步骤进行操作,忽略加入域模式的任何说明。该脚本会将 CredSpec 上传到相应的 Amazon S3 存储桶。

*** 为了确保 Amazon Fargate 中运行的 Credentials Fetcher 可以与您的 AD 域进行通信,启动任务的 Amazon VPC 应附加一个 DHCP 选项集。此 DHCP 选项集应根据您的 AD 设置域名域名服务器值。有关更多信息,请访问产品文档

构建应用程序容器并部署 Amazon Fargate 任务

在示例存储库中有一个 ASP.NET Core 应用程序,连接到示例 SQL Server 数据库中的表。此应用程序可帮助您验证面向 SQL Server 的连接是否确实使用了集成安全。要构建应用程序并将其推送到 Amazon ECR 存储库,请按照上一篇博客中概述的步骤进行操作。

正如您在上一节中看到的,要在 Amazon ECS 任务定义中启用 gMSA 支持,您需要使用指向存储在 Amazon S3 中的 CredSpec 的链接来设置 credentialSpecs 属性。任务定义应将任务执行角色设置为 AWS Identity and Access Management(AWS IAM)角色,并有权读取存储桶、Secrets Manager 密钥和 Amazon ECR 存储库。有关更多信息,请参阅关于将 gMSA 用于 Fargate 上的 Linux 容器的 Amazon ECS 文档。

将应用程序部署到 Amazon ECS

要将 Amazon ECS 服务与您的应用程序一起部署,请返回用于部署基础设施的终端。如果使用的是 Bash,请运行以下命令:

export DEPLOY_APP=1
cdk deploy "*" --require-approval "never"

如果使用的是 PowerShell,请运行以下命令:

$Env:DEPLOY_APP = 1

cdk deploy "*" --require-approval "never"

务必注意,Amazon ECS 服务和 ECS 任务应在连接到 AD 域控制器的 VPC 子网中启动,否则 Credentials Fetcher 将无法检索 Kerberos 票证。

部署完成后,前往 CloudFormation 控制台,点击名称类似 websiteec2serviceServiceURLXXXXXXXX 的输出值,以导航到 Web 应用程序。Web 应用程序将运行,并使用 gMSA 进行 AD 身份验证。

图 4:运作中的示例 Web 应用程序

ASP.NET Core 应用程序配置与任何其他环境(包括本地环境)相同。唯一需要记住的特殊之处是,连接字符串中的 SQL Server 地址必须使用 AD 域名进行定义。如果您使用 IP 地址或其他 DNS 名称,则身份验证方法默认为 Microsoft NTLM,这将会失败。

故障排除

在部署示例解决方案时,您可能会遇到两种主要类型的错误。第一种(也是最简单的)错误类型是连接到 SQL Server 时出错。要诊断问题,请导航到 Amazon ECS 控制台,选择您的集群名称,然后选择服务名称,最后选择日志以显示该应用程序记录的错误。

第二种错误是无法成功启动 Amazon ECS 任务。这些错误的根本原因通常是 Credentials Fetcher 无法从指定的 gMSA 帐户检索 Kerberos 票证。要诊断问题,请先仔细检查:

  1. Amazon ECS 任务定义的 credentialSpecs 属性设置为前缀“credentialspecdomainless:”,后跟一个指向带有 CredSpec 文件的有效 Amazon S3 对象的 ARN。
  2. Amazon S3 中的 CredSpec 文件指向有效的 Secrets Manager 密钥以及 Credential Fetcher 使用的 AD 用户信息。
  3. Secrets Manager 中存储的用户名、密码和域名对于有权从 CredSpec 文件中指定的 gMSA 帐户检索密码的 AD 用户有效。

如果您已经验证了这一点但仍然存在问题,您可以将该任务部署到 Amazon EC2 容器实例并使用以下命令查看 Credential Fetcher 的日志:sudo journalctl -u credentials-fetcher -e

或者,您也可以为 Fargate 团队创建支持工单,以调查问题的根本原因。

清理

为避免将来产生费用,请删除这些资源。可以使用 cdk destroy 命令删除堆栈。在终端或 PowerShell 窗口中运行以下命令:

cdk destroy "*" --require-approval "never"

最后,手动删除 Amazon CloudFormation 创建的 Amazon CloudWatch 日志组。

总结

在本文中,您学习了如何在 Amazon ECS 上使用 Credentials Fetcher 与 Amazon Fargate 的集成。亚马逊云科技客户可以通过该集成将应用程序现代化改造为 Linux 容器,同时通过 gMSA 使用 Windows 身份验证,并实现 Amazon Fargate 无服务器计算的优势。

此功能以及对 AmazonEC2 实例的支持已经上线,可供您使用自己的应用程序进行测试。如果您希望其他亚马逊云科技计算服务原生支持适用于 Linux 容器的 gMSA,请通过 Credentials Fetcher GitHub 存储库AWS 上的 .NET 官方 Twitter 账号与我们分享。访问 AWS 上的 .NET 以获取有关在 AWS 上运行 .NET 应用程序的更多信息和资源。

本篇作者

Cristobal

Cristobal 是亚马逊云科技的高级解决方案架构师。他专门帮助客户对在 AWS 上运行的.NET 应用程序进行现代化改造。自 2009 年以来,他帮助组织使用开放 Web 技术、Kubernetes、CI/CD 和云原生服务对其传统 .NET 应用程序进行现代化改造。