- The concept of computer delegation in a nutshell
- Two different approaches
- Unconstrained delegation to any service
- Constrained delegation to specified services with Kerberos only
- Constrained delegation to specified services only with any authentication protocol
- Resource-based constrained delegation
- Check the current delegation for a computer
- Remove delegation
- How to configure computer delegation with PowerShell - Mon, Jul 23 2018
- Save on Azure costs for testing and training - Wed, Jun 6 2018
- Clean up orphaned Foreign Security Principals - Fri, Oct 20 2017
The concept of computer delegation in a nutshell
To make it easy to understand the whole article, let's work on an example:
- You are logged in on ComputerA.
- You connect from ComputerA to ComputerB via a PSSession.
- From the PSSession on ComputerB, you want to copy files from the central repository on ComputerC to ComputerB.
This scenario is called a "double hop," and without delegation, you will get an "Access denied" error message.
Two different approaches
The "one to many" approach consists of setting the ComputerB account with a list of ComputerC-like computers that ComputerB can access.
This concerns:
- Unconstrained delegation (from ComputerB you can access all services on all other computers).
- Constrained delegation to any service (from ComputerB you can access all services on a specified list of computers).
- Constrained delegation to specified services (from ComputerB you can access a specified list of services on a specified list of computers). This offers two options: using Kerberos only or using any authentication protocol.
The "one from many" approach consists of setting the ComputerC account with the list of all ComputerB-like computers allowed to access all services on ComputerC through a double hop.
This last approach concerns resource-based constrained delegation.
A full comparison of all of these different possibilities is beyond the scope of this article.
However, you should know that:
- "No delegation" is the most secure option. Therefore, set delegation only when you have to.
- Unconstrained delegation is the least secure solution.
- Every type of delegation has its own advantages and limitations.
- Constraint delegation is easy to manage, and when deleting your computer account, the delegation goes with it.
- With resource-based constrained delegation, one computer account can contain a very long list of other computers. You should regularly check that all computer accounts from this list still exist and that there are no duplicates.
- Domain controllers are set with unconstrained delegation by design. Don't change this behavior, and ensure that when you configure delegation massively with a script, exclude domain controllers from its computer list.
Important note:
Based on my findings, when you set delegation, it needs a few seconds or even minutes before you can check the value with a Get verb and also before all involved computers become aware of the delegation.
This can lead you to wrong conclusions when you play around and you want to check the results too fast.
Unconstrained delegation to any service
This is attainable with the Set-ADAccountControl cmdlet.
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedForDelegation $true
Constrained delegation to specified services with Kerberos only
In this case, you must specify a list of ComputerC's service principal names (SPNs) in ComputerB's account. To obtain the list of SPNs, you can use the Get-ADComputer cmdlet and display the servicePrincipalName property of ComputerC.
Get-ADComputer ComputerC -Properties servicePrincipalName | Select-Object ‑ExpandProperty servicePrincipalName
Then you add ComputerC's list of SPNs you need to ComputerB's account with the Set-ADComputer cmdlet along with the Add parameter. This parameter accepts a hash table containing an array of strings as input.
Set-ADComputer -Identity ComputerB -Add @{'msDS-AllowedToDelegateTo'=@('HOST/ComputerC','WSMAN/ComputerC.MyDomain.com')}
Constrained delegation to specified services only with any authentication protocol
As with the former method, you must find the list of ComputerC's SPNs and add those you need to the ComputerB account.
However, you must also use the Set-ADAccountControl cmdlet with the TrustedToAuthForDelegation parameter.
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $true Set-ADComputer -Identity ComputerB -Add @{'msDS-AllowedToDelegateTo'=@('HOST/ComputerC','WSMAN/ComputerC.MyDomain.com')}
Note: Do not confuse the TrustedToAuthForDelegation parameter for constrained delegation with the TrustedForDelegation parameter from above, which applies to unconstrained delegation only.
Resource-based constrained delegation
There's no screenshot here because there is no native user interface to set this value. You must do it with PowerShell.
In the following example we will allow ComputerB1 and ComputerB2 to access ComputerC with the Set-ADComputer cmdlet. The input for the PrincipalsAllowedToDelegateToAccount parameter is an array of distinguished names. But for convenience we will use a computer object as input, and the cmdlet will find out the distinguished name itself.
Set-ADComputer ComputerC -PrincipalsAllowedToDelegateToAccount (Get-ADComputer ComputerB1),(Get-ADComputer ComputerB2)
Please note that the PrincipalsAllowedToDelegateToAccount parameter is only available on Windows 8 or Windows Server 2012 computers and later.
Check the current delegation for a computer
The computer account object stores all values, which the Get-ADComputer cmdlet can retrieve.
Get-ADComputer ComputerName -Properties * | Format-List -Property *delegat*,msDS-AllowedToActOnBehalfOfOtherIdentity
When using resource-based constrained delegation, it will display System.DirectoryServices.ActiveDirectorySecurity for the msDS-AllowedToActOnBehalfOfOtherIdentity property.
You must then expand this value to see the content, especially the list of computers allowed to access ComputerC in the Access property.
Get-ADComputer ComputerC -Properties * | Select-Object -ExpandProperty msDS-AllowedToActOnBehalfOfOtherIdentity |Format-List
Remove delegation
To remove unconstrained delegation from ComputerB, use the following command:
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedForDelegation $false
To remove constrained delegation from ComputerB, use the following two commands:
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $falseSet-ADComputer -Identity ComputerB -Clear 'msDS-AllowedToDelegateTo'
To remove resource-based constraint delegation from ComputerC, use the following command:
Subscribe to 4sysops newsletter!
Set-ADComputer ComputerC -PrincipalsAllowedToDelegateToAccount $Null
You are missing a closing ‘)’ in both delegation commands.
incorrect:
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’}
correct:
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’)}
incorrect:
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’}
correct:
Get-ADComputer -Identity ComputerB | Set-ADAccountControl ‑TrustedToAuthForDelegation $trueSet-ADComputer -Identity ComputerB -Add @{‘msDS-AllowedToDelegateTo’=@(‘HOST/ComputerC’,’WSMAN/ComputerC.MyDomain.com’)}
@Sedrick
Good catch with the parenthesizes!
I have corrected the error.
When removing delegation, I would recommend using the -Remove option instead of -Clear. if you have multiple delegations this would clear them all.
@Sedrick
Yes, that’s the point with my example using -Clear, like the example that follows and which uses $Null to removes all principals from the PrincipalsAllowedToDelegateToAccount property.
But if you want to remove only some entries of the msDS-AllowedToDelegateTo property, you are right, the -Remove option is the way to go.
Hi Luc,
what happens when a constrained delegation is removed from computer c. The reason i ask is that in our infrastructure there is an issue that computer a cannot access coputer c after a reboot(cifs share access). I would like to remove all delegations from c so that we can access it.
thanks
azd
@assad
If you remove delegation you cannot access resources through computerB anymore. You have to access them directly from ComputerA to ComputerC.
another way to get just the values set
(Get-ADServiceAccount <GMSANAME> -Properties * | Select-Object -ExpandProperty msDS-AllowedToActOnBehalfOfOtherIdentity).Access.IdentityReference.Value
Hi,
thx for your very interesting blog! I have a question, we need to run a lot of servers in a docker environment (tomcat), the tomcat servers a running all with the same user called tomcat. From the tomcat server it should be possible to call a second servers webservice. So as I understand right I have to allow delegation for the tomcats. But I'm not sure, should I allow delegation to the user tomcat, or to the tomcat servers? I connect the server with the tomcat user by
setspn -A HTTP/tomcatsrv1.example.com tomcat
then I generate the keytab file
ktpass /out c:\temp\tomcat.keytab
/princ HTTP/tomcatsrv1.com@EXAMPLE.COM
/pass ******** /ptype KRB5_NT_PRINCIPAL
User tomcat has set constrainted delegation for all auth protocolls to the webservice server?
But somehow it doesn't work :-/
regards
Meex
What PowerShell command do I use to mass set a list of computers for ‘Do not trust this computer for delegation’?