Containers

Windows authentication with gMSA on Linux containers on Amazon ECS with AWS Fargate

Introduction

Today, we are announcing the availability of Credentials Fetcher integration with AWS Fargate on Amazon Elastic Container Service (Amazon ECS). With this launch, you have the option of running Linux containers that depend on Windows authentication on Amazon ECS using both the Amazon Elastic Compute Cloud (Amazon EC2) launch type, as well as with AWS Fargate serverless compute launch type.

Prior to this release, running applications dependent on group Managed Service Account (gMSA) as a Linux container on Amazon ECS was limited to running on Amazon EC2 instances domain-joined or domain-less. With AWS Fargate support, you can modernize applications to Linux containers while using Windows authentication via gMSA while removing the burden of provisioning, maintaining, patching, and scaling virtual machines.

This post uses many of the concepts explored in the post Using Windows Authentication with gMSA on Linux Containers on Amazon ECS. Links to the relevant parts are provided throughout this post.

Solution overview

To explore how the gMSA support for Linux containers on AWS Fargate works, you’ll deploy and explore the following sample solution:

Figure 1: Sample solution architecture diagram

After deploying these components, you’ll generate a Credential Specification (CredSpec) file for the created gMSA account, and upload it to Amazon S3 where Credentials Fetcher will retrieve it. Finally, you’ll build and deploy a simple .NET Web application in a Linux container on Amazon ECS. The application is configured to use Integrated Windows Authentication to securely connect to the database.

The sample solution uses the AWS Cloud Development Kit (AWS CDK) to provision cloud resources using TypeScript. The AWS CDK allows developers to build AWS infrastructure in a variety of familiar programming languages, including JavaScript, C#, Python, Java, and Go.

Prior to any production deployment, you should always consult with your local security team to review security controls and requirements based on your environment and security posture.

Prerequisites

For the tutorial, you should have the following prerequisites:

Deploy the infrastructure

To start, create a directory for the sample solution in your local computer. Clone this GitHub repository into the directory.

Open a terminal in the cdk directory of the cloned repository, replace {KEY_PAIR_NAME} with your Amazon EC2 key pair name, and run the following commands if you are using Bash:

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

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

If you are using PowerShell, then run the following commands:

$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
$Env:CREDSPEC_FROM_S3 = 1

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

This starts the deployment of three AWS CloudFormation stacks that contain the sample solution. The deployment takes around one hour to complete.

When the deployment completes, navigate to the AWS CloudFormation Console. Something similar to the following image will be displayed:

Figure 2: AWS CloudFormation resources in AWS Console

During the deployment, a security group, user, and gMSA are created in the AD. The user is a set as member of the security group, which is authorized to retrieve password from the gMSA. The AD user’s password is randomly generated, and stored in the secret with name:

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

Walkthrough

In the following sections, you’ll explore how to configure Amazon ECS and Credentials Fetcher to provide Windows Authentication to the web application.

Configure Credentials Fetcher and Active Directory

Credentials Fetcher is responsible for obtaining the Kerberos ticket from the gMSA and provides it to the Linux container. When you use Amazon EC2 instances, you need to install Credentials Fetcher in each instance. On AWS Fargate, Credentials Fetcher is available out-of-the-box.

The following represents the flow AWS Fargate and Credentials Fetcher follows to provide with a Kerberos ticket to a container:

Figure 3: AWS Fargate and Credentials Fetcher process

  1. A new Fargate task is requested by the user or by an Amazon ECS service.
  2. The Amazon ECS cluster starts a new Fargate micro-VM and send the task definition to launch to the ECS agent.
  3. The Amazon ECS agent starts Credentials Fetcher as an ECS managed daemon.
  4. Credentials Fetcher retrieves the CredSpec location from the task definition’s credentialSpecsproperty. *
  5. Credentials Fetcher retrieves the AD user and domain to use from AWS Secrets Manager secret defined in the CredSpec’s HostAccountConfig object. **
  6. Credentials Fetcher retrieves a Kerberos ticket from the appropriate AD domain controller. ***
  7. Credentials Fetcher stores the Kerberos ticket in the local micro-VM storage and share the location with the Amazon ECS agent.
  8. The Amazon ECS agent starts the task definition container mounting the Kerberos ticket location to it.

* Credentials Fetcher requires a security principal to authenticate with AD and retrieve the gMSA password. For AWS Fargate tasks you should use an AD user that is authorized to retrieve the gMSA password, either directly or through an AD security group.

The sample solution creates and uses an AD Security Group named SampleWebAppGmsaPrincipals to access the gMSA passwords.

** The CredSpec file is a JSON document, which contains metadata about the gMSA account that’s used within each container. Credentials Fetcher uses the CredSpec file to request a Kerberos ticket and then make it available to the container. The CredSpec file can only be generated in a Windows computer when logged in as an admin user of the AD.

To generate the CredSpec file, follow the steps outlines in the previous blog ignoring any instructions for domain-joined mode. The script uploads the CredSpec to the appropriate Amazon S3 bucket.

*** To ensure the Credentials Fetcher running in AWS Fargate can communicate with your AD domain, the Amazon VPC where your task will be launched should have a DHCP option set attached. This DHCP option set should have the Domain name and Domain name servers values set based on your AD. For more information go the product documentation.

Build the application container and deploy the AWS Fargate task

In the sample repository, there’s an ASP.NET Core application that connects to a table in the sample SQL Server database. This application helps you validate that the connection to SQL Server is indeed using Integrated Security. To build the application and push it to the Amazon ECR repository follow the steps outlined in the previous post.

As you saw in the previous section, to enable gMSA support in your Amazon ECS task definition, you need to set the credentialSpecs property with a link to your CredSpec stored in Amazon S3. The task definition should have a task execution role set to an AWS Identity and Access Management (AWS IAM) role with permission to read the bucket, the Secrets Manager secret, and the Amazon ECR repo. For more information, refer to the Amazon ECS documentation for Using gMSAs for Linux Containers on AWS Fargate.

Deploy the application to Amazon ECS

To deploy the Amazon ECS service with your application, go back to the terminal you used to deploy the infrastructure. Run the following commands if you are using Bash:

export DEPLOY_APP=1

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

Run the following commands if you are using PowerShell:

$Env:DEPLOY_APP = 1

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

It’s important to note that the Amazon ECS service and ECS task should be launched in a subnet of a VPC with connectivity to the AD domain controllers, otherwise Credentials Fetcher won’t be able to retrieve the Kerberos ticket.

Once the deployment is complete, go to the AWS CloudFormation Console and select the value of the output named like websiteec2serviceServiceURLXXXXXXXX to navigate to the web application. The web application will run and authenticate to the AD using the gMSA.

Figure 4: Working sample web application

The ASP.NET Core application configuration is identical to any other environment, including on-premises. The only particularity you need to keep in mind is that the SQL Server address in the connection string MUST be defined using the AD domain name. If you use an IP address or a different DNS name, then the authentication method defaults to Microsoft NTLM, which will fail.

Troubleshoot

There are two main types of errors you may encounter when deploying the sample solution. The first, and most simple, type of error is when there is an error connecting to SQL Server. To diagnose the problem, navigate to the Amazon ECS console, select your cluster name, then the service name, and finally select Logs to display the errors logged by the application.

The second type of error is when the Amazon ECS task cannot be launched successfully. The root cause of these errors is usually Credentials Fetcher being unable to retrieve the Kerberos ticket from the specified gMSA account. To diagnose the problem, first double check that:

  1. The Amazon ECS task definition has the credentialSpecs property set with the prefix “credentialspecdomainless:“, followed by an ARN that points to a valid Amazon S3 object with the CredSpec file.
  2. The CredSpec file in Amazon S3 points to a valid Secrets Manager secret with the AD user information used by Credential Fetcher.
  3. The username, password, and domain name stored in Secrets Manager are valid for an AD user with permission to retrieve the password from the gMSA account specified in the CredSpec file.
  4. The Amazon VPC where your task will be launched, has a DHCP option set attached that points to the AD containing the gMSA account you plan to use.

If you have validated this and still present issues, you can deploy the task to an Amazon EC2 container instance and review Credential Fetcher’s logs using the command sudo journalctl -u credentials-fetcher -e.

Alternatively, you can create a support ticket for the Fargate team to investigate the root cause of the problem.

Cleaning up

To avoid incurring future charges, delete the resources. You can use the cdk destroy command to delete the stack. Run this command in the terminal or PowerShell window:

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

Finally, manually delete the Amazon CloudWatch log group created by AWS CloudFormation.

Conclusion

In this post, you learned how to use the integration of Credentials Fetcher with AWS Fargate on Amazon ECS. This integration allows AWS customers to modernize applications to Linux containers while using Windows authentication via gMSA and realize the benefits of AWS Fargate serverless compute.

This functionality, along with support for AmazonEC2 instances, is live and ready for you to test with your own applications. If you want additional AWS compute services to support gMSA for Linux containers natively, please share it with us through the Credentials Fetcher GitHub repository, or the official .NET on AWS Twitter handle. Visit .NET on AWS for additional information and resources for running .NET applications on AWS.

Cristobal Espinosa

Cristobal Espinosa

Cristobal is a Sr. Solutions Architect at Amazon Web Services. He specializes in helping customers modernize their .NET applications running on AWS. Since 2009, he has helped organizations modernize their legacy .NET applications using open web technologies, Kubernetes, CI/CD and cloud-native services.

Sai Kiran Akula

Sai Kiran Akula

Sai Kiran Akula is a SDE at Amazon Web Services EC2 team which helps .NET customers in their modernization journey.