Create a Container with Active Directory Support
Windows Containers do not ship with Active Directory support and due to their nature can’t (yet) act as a full-fledged domain joined objects, but a certain level of Active Directory functionality can be supported through the use of Globally Manages Service Accounts (gMSA).
An introduction to gMSA can be found here : https://blogs.technet.microsoft.com/askpfeplat/2012/12/16/windows-server-2012-group-managed-service-accounts/
The gMSA is used to create a ‘CredentialSpec’ which is passed into the container at run time. Any process running on the container under the context of ‘Local Service’ will then present the domain creds of the gMSA to any domain joined service to which it connects. For example: you could run a Windows Service on a Container using a domain account to access a secure SQL server.
An introduction to gMSA use on Windows Containers can be found here: /en-us/virtualization/windowscontainers/manage-containers/manage-serviceaccounts
Step by Step
Obtain a gMSA Note: In this example we assume the name of the gMSA is adoncontt1
. In the likely event that your gMSA has a different name, be sure to place each instance of adoncontt1
in this example with the name of your gMSA.
On the container host console
- Open Admin PowerShell
- Install AD features
Add-WindowsFeature RSAT-AD-PowerShell Import-Module ActiveDirectory
- Create the c:\data directory
mkdir c:\data Cd c:\data
- Fetch CredentialSpec.psm1 script (see below) and place a copy in c:\data
- Create the credential spec
Import-Module ./CredentialSpec.psm1 New-CredentialSpec -Name adoncontt1 -AccountName adoncontt1
- Verify the credential spec
Get-CredentialSpec
Start the Container
Active Directory support is enabled in containers by providing the name of the credentialspec (created above) in the --security-opt option in the docker run command as shown below. In this case the name of the credentialspec is adoncontt1
- Run the container interactively
docker run -it --security-opt "credentialspec=file://adoncontt1.json" microsoft/windowsservercore
Wait for container console shell to start
On the container console
Test AD access <if using AD>
nltest /parentdomain
At his point, if no errors occurred, the LocalSystem account on the container will be a proxy for the configured gMSA account. Any process run as the LocalSystem principal on the container will appear to be the gMSA principal to all assets on the Active Directory domain.
CredentialSpec Source
You may locate the latest version of CredentialSpec.psm1 at Virtualization-Documentation. After cloning a local Git repo the file will be located at <local repo>\Virtualization-Documentation\windows-server-container-tools\ServiceAccounts\CredentialSpec.psm1
The latest version as of 1/30/2017 is provided here for reference:
# This requires the ActiveDirectory module. Run Add-WindowsFeature rsat-ad-powershell to install it Import-Module ActiveDirectory $Script:CredentialSpecPath="$($env:ProgramData)\Docker\CredentialSpecs"
function New-CredentialSpec
{
param(
[Parameter(Mandatory=$true)] [String] $Name,
[Parameter(Mandatory=$true)] [String] $AccountName,
[Parameter(Mandatory=$false)] [Microsoft.ActiveDirectory.Management.ADDomain] $Domain = (Get-ADDomain),
[Parameter(Mandatory=$false)] $AdditionalAccounts
)
# TODO: verify $Script:CredentialSpecPath exists
# Start hash table for output
$output = @{}
# Create ActiveDirectoryConfig Object
$output.ActiveDirectoryConfig = @{}
$output.ActiveDirectoryConfig.GroupManagedServiceAccounts = @( @{"Name" = $AccountName; "Scope" = $Domain.DNSRoot } )
$output.ActiveDirectoryConfig.GroupManagedServiceAccounts += @{"Name" = $AccountName; "Scope" = $Domain.NetBIOSName }
if ($AdditionalAccounts) {
$AdditionalAccounts | ForEach-Object {
$output.ActiveDirectoryConfig.GroupManagedServiceAccounts += @{"Name" = $_.AccountName; "Scope" = $_.DomainName }
}
}
# Create CmsPlugins Object
$output.CmsPlugins = @("ActiveDirectory")
# Create DomainJoinConfig Object
$output.DomainJoinConfig = @{}
$output.DomainJoinConfig.DnsName = $Domain.Forest
$output.DomainJoinConfig.Guid = $Domain.ObjectGUID
$output.DomainJoinConfig.DnsTreeName = $Domain.DNSRoot
$output.DomainJoinConfig.NetBiosName = $Domain.NetBIOSName
$output.DomainJoinConfig.Sid = $Domain.DomainSID.Value
$output.DomainJoinConfig.MachineAccountName = $AccountName
$output | ConvertTo-Json -Depth 5 | Out-File -FilePath "$($Script:CredentialSpecPath)\\$($Name).json" -encoding ascii
}
function Get-CredentialSpec
{
Get-ChildItem $Script:CredentialSpecPath | Select-Object @{
Name='Name'
Expression = { $_.BaseName }
},
@{
Name='Path'
Expression = { $_.FullName }
}
}
Comments
- Anonymous
June 23, 2017
Hello Mark , thanks for this blog this has been very useful. Does this also apply to IIS web applications running inside a container? if not how do we get as IIS web application to run under a domain identity to access network resources and also provide support for windows authentication.- Anonymous
June 26, 2017
The comment has been removed- Anonymous
July 17, 2017
Really interested in your update on this MarkBrianWest, my container currently shows up as 'NT AUTHORITY\ANONYMOUS LOGON' when configured to use the gMSA and trusted authentication from an app pool running as local system inside the container!- Anonymous
August 10, 2017
Also interested in hearing about AD authenication for ASP.NET apps in IIS + NTFS permissions.- Anonymous
August 19, 2017
Well then you are in luck! See https://blogs.msdn.microsoft.com/containerstuff/2017/07/31/getting-iis-win-auth-to-work-in-a-container/ - Anonymous
September 08, 2017
Here is step by step https://github.com/artisticcheese/artisticcheesecontainer/wiki/Using-Group-Managed-Service-Account-(GMSA)-to-connect-to-AD-resources
- Anonymous
- Anonymous
- Anonymous
- Anonymous
- Anonymous
July 10, 2017
Hello Mark, the current implementation requires the app to run under local system or network account. Looks like the supported scenario is only IIS.Is there a way to run an asp.net CORE application as system account, so it can benefit GMSA? Pls see my question here: https://stackoverflow.com/questions/44591253/run-aspnet-core-app-in-docker-using-gmsa - Anonymous
September 08, 2017
Mark, would you know how to setup AD authentication for a Docker container running on CentOS Linux?