Configuring Kerberos Constrained Delegation for Hyper-V Management

 

Managing Hyper-V can be done in several ways; using Hyper-V Manager, using System Center Virtual Machine Manager and, of course, using PowerShell. As a best practice in any management scenario, you manage a service from a remote machine. Whether this is a workstation running Windows 8 or a Remote Desktop Services server running Windows Server 2012 does not really matter, at least not from a technical perspective. I always suggest performing management from a central ‘management server’ where all management tools are installed and maintained. The whole idea being that you don’t want people logging in interactively on servers just for service management.

Managing Hyper-V in a remote scenario differs from the local scenario. In a local scenario you are logged on with your credentials and any operations are being run using your credentials. As long as your privileges are sufficient, you can perform any operation you wish. The situation changes in a remote scenario. Any operations you perform on the Hyper-V host itself will work. But operations that involve other Hyper-V hosts (or any remote host) fail if you have not made the proper arrangements.

For example, when you create a virtual machine (New-VM), your credentials are being used on the Hyper-V host. But when you move a virtual machine (Move-VM) the operation involves another Hyper-V host. Let’s call the host where you want to move the VM off the source host, the host where you want to move the VM to the destination host. The source host will use your credentials to move the virtual machine to the other host and this will fail because the source host is not allowed to use your credentials. It simply lacks the right to delegate your credentials. This is where Kerberos Constrained Delegation, also known as KCD, will help you out.

A little background on Kerberos delegation.

Ever since Windows 2000 we support the concept of delegation. A client might need to let an application or a service connect to other servers or services on its behalf. A client might use a front-end server, for example, that then needs to authenticate with a back-end server. The front-end server needs to authenticate to the back-end server with the client's credentials, because if it authenticated under its own service account, it would have different authorization than the user.

The Kerberos protocol includes a mechanism called delegation of authentication. When this mechanism is used, the client (the requesting service) delegates authentication to a second service by informing the KDC that the second service is authorized to act on behalf of a specified Kerberos security principal, such as a user that has an Active Directory directory service account. The second service can then delegate authentication to a third service.

In the Windows 2000 delegation model, the KDC does not limit the scope of services that a Kerberos principal's identity can be delegated to. That is, after a service account is trusted for delegation, it can request service tickets on behalf of a given user to any other service accounts. With constrained delegation, on the other hand, domain administrators can configure service accounts to only delegate to specific sets of service accounts. In Windows Server 2003 and higher, the ms-DS-Allowed-To-Delegate-To attribute is added to service accounts to help enforce constrained delegation. The ms-DS-Allowed-To-Delegate-To attribute lists the service principal names (SPNs) of other service accounts that a given service account is allowed to delegate to. When a Windows Server KDC processes a service ticket request via the constrained delegation extension, it will verify that the target service account is one that is listed in the ms-DS-Allowed-To-Delegate-To attribute.

Now that you know the technical explanation of Kerberos Constrained Delegation, I will go into the practical use and configuration in the scenario of remotely managing Hyper-V. For easy understanding I will use the setup of my own demo environment. In this environment there are two Hyper-V Server 2012 hosts and one Windows Server 2012 host. This is a rather simple environment in which the Hyper-V hosts simply run my virtual machines and the Windows Server 2012 host is being used as a file server to store virtual machine (configuration, virtual disks, smart paging and snapshots) and ISO files.

Let’s assume that this environment is pristine from a fresh installation of the hosts and the domain, so nothing has been modified for any specific purpose other than being able to logon with a domain account. In this scenario I am logged on using the domain administrator account. The three physical hosts have been joined to the domain and I have a ‘management server’ running Windows Server 2012 in a virtual machine. The diagram below is the logical representation of the hosts and servers.

image

Vmhost1 and vmhost2 are the Hyper-V hosts, fhost1 is the file server, mgmt1 is the ‘management server’ and contoso1 the Active Directory domain controller. Except for the Hyper-V hosts, all others run Windows Server 2012.

From mgmt1, I run the Hyper-V management tools being Hyper-V Manager and the Hyper-V PowerShell cmdlets. Obviously, I also run Server Manager and any role and feature tools for File and Storage Services, Active Directory and DNS from mgmt1.

Configuring Hyper-V from mgmt1 I don’t run into any issues. I am remotely managing Hyper-V using my domain credentials. As long as my management operations stay ‘inside’ vmhost1 then there are no authentication issues. But when the operation involves for example vmhost2, authentication fails and messages like ‘general access denied’ and ‘no credentials are available in the security package’ occur. Despite the fact that I am logged on as a domain administrator on mgmt1, I cannot perform any actions that involve vmhost2 when managing vmhost1. As you now know, KCD has not been configured yet.

For this to succeed, KCD has to be configured on vmhost1. To be more precise, vmhost1 needs to be trusted for delegation to specific services on vmhost2. These services are:

  • CIFS
  • Microsoft Virtual System Migration Service

CIFS (Common Internet File System) is the updated name for SMB (Server Message Block). SMB is necessary for vmhost1 to access vmhost2 and create files/folders. The Microsoft Virtual System Migration Service is the migration capability of the Virtual Machine Management Service. This service performs operations like virtual machine migration and virtual machine replication. Once I have configured delegation for these services to vmhost2, I can perform management operations that involve vmhost2.

Suppose I want to store the virtual machine data on the file server fhost1. I would then need to configure vmhost1 to be able to delegate CIFS to fhost1. But if I want to move a virtual machine with storage on fhost1, I must configure delegation on vmhost2 as well, because vmhost2 needs access to the virtual machine data as well. I also want to use ISO images stored on the fhost1 file server from within my virtual machines. With delegation configured for the CIFS service type to fhost1 on both vmhost1 and vmhost2, I can use SMB shared storage on both Hyper-V hosts and use ISO images stored on fhost1.

You can configure delegation from the GUI tool Active Directory Users and Computers. This is what it looks like for VMhost1:

clip_image003

Notice that I have checked the ‘Expanded’ view which then shows both single label and FQDN host entries.

Obviously you can configure this from PowerShell too by using the Set-ADObject cmdlet. You will need to supply the distinguished name of the host and provide the hash table entries for the attribute msDS-AllowedToDelegateTo.

Below is a script I use to configure KCD on my Hyper-V hosts. It is nothing fancy or advanced, it is just easy to use since I don’t have to remember the attribute name and construct the hash table. The script offers an Add, Replace and Remove switch.

Set-KCD

  1. #######################################################
  2. ##
  3. ## Set-KCD.ps1, v1.0, 2012
  4. ##
  5. ## Created by Matthijs ten Seldam, Microsoft
  6. ##
  7. #######################################################
  8.  
  9. <#
  10. .SYNOPSIS
  11. Configures Kerberos Constrained Delegation (KCD) on a computer object in Active Directory.
  12.  
  13. .DESCRIPTION
  14. Set-KCD supports adding, replacing and removing delegation records for a specified distinguished user or computer object in Active Directory.
  15.  
  16. .PARAMETER AdDN
  17. The distinguished name of the user or computer object.
  18.  
  19. .PARAMETER HostFQDN
  20. The fully qualified domain name of the target computer.
  21.  
  22. .PARAMETER Service
  23. The name of the service type to delegate.
  24.  
  25. .PARAMETER Add
  26. Switch to specify the operation.
  27.  
  28. .PARAMETER Replace
  29. Switch to specify the operation.
  30.  
  31. .PARAMETER Remove
  32. Switch to specify the operation.
  33.  
  34. .EXAMPLE
  35. Set-KCD -AdDN "cn=vmhos1,cn=computers,dc=contoso,dc=com" cifs vmhost2.contoso.com -Add
  36.  
  37. .EXAMPLE
  38. Set-KCD -AdDN "cn=vmhos1,cn=computers,dc=contoso,dc=com" cifs vmhost2.contoso.com -Replace
  39.  
  40. .INPUTS
  41. None
  42.  
  43. .OUTPUTS
  44. None
  45.  
  46. .NOTES
  47. This script must be run using domain administrator credentials.
  48. The script adds both entries for the target computer; unqualified and fully qualified host names.
  49.  
  50. .LINK
  51. https://blogs.technet.com/matthts
  52. #>
  53.  
  54. param(
  55.     [Parameter(Mandatory=$true, Position=0)]
  56.     [string] $AdDN,
  57.     [Parameter(Mandatory=$true, Position=1)]
  58.     [string] $HostFQDN,
  59.     [Parameter(Mandatory=$true, Position=2)]
  60.     [string]$Service,
  61.     [Parameter(Mandatory=$true, ParameterSetName="Add")]
  62.     [switch]$Add,
  63.     [Parameter(Mandatory=$true, ParameterSetName="Replace")]
  64.     [switch] $Replace,
  65.     [Parameter(Mandatory=$true, ParameterSetName="Remove")]
  66.     [switch] $Remove
  67.     )
  68.  
  69.  
  70. $HostName=$HostFQDN.Remove($HostFQDN.IndexOf("."))
  71.  
  72. switch($PSCmdlet.ParameterSetName)
  73. {
  74.     "Add"
  75.     {
  76.         Set-ADObject $AdDN -Add @{"msDS-AllowedToDelegateTo"="$Service/$HostFQDN","$Service/$HostName"}
  77.     }
  78.  
  79.     "Remove"
  80.     {
  81.         Set-ADObject $AdDN -Remove @{"msDS-AllowedToDelegateTo"="$Service/$HostFQDN","$Service/$HostName"}
  82.     }
  83.  
  84.     "Replace"
  85.     {
  86.         Set-ADObject $AdDN -Replace @{"msDS-AllowedToDelegateTo"="$Service/$HostFQDN","$Service/$HostName"}
  87.     }
  88.  
  89. }

 

You can verify you delegation using Get-AdObject. For example:

Get-AdObject "cn=vmhost1,cn=computers,dc=contoso,dc=com" -Properties msDS-AllowedToDelegateTo

This will then show:

 

image

 

Detailed Kerberos protocol explanation can be found here.

 

Update 2012-09-25
I have updated the Set-KCD.ps1 script. It can be downloaded here.