With the new capability in Windows 10, version 1709, Windows Client can host shielded VMs while using remote Host Guardian Service (HGS) attestation. This caused some confusion as people stated they have already been running shielded VMs on client. This blog post is intended to clarify things and explain how to run them side by side.
In Windows 10, when you create a VM, you can optionally attach a virtual TPM (vTPM) to it. It offers similar protection to the VM as a physical TPM does for the physical device. vTPM state is encrypted and the encryption key can be either stored locally (a.k.a. local mode) or stored remotely on a HGS server (a.k.a HGS mode). There are several strong security measures in HGS mode such as validating boot measurements and code integrity policies. For more information on what HGS mode measures, check out my previous blog post on Privileged Access Workstations here.
The mode--local mode vs. HGS mode--is a configuration setting on the physical host so it knows where to get the key to unlock the vTPM. When the host is running in HGS mode, it will get the key from HGS server (assuming it qualifies as healthy); when the host is running in local mode, it will look for the key locally. Previously, Windows Client only supported local mode; HGS mode support was added in the Windows 10, version 1709 release.
When you start the shielded VM in HGS mode, the host must get the key from HGS. If the host is not connected to the network, the shielded VM won’t start. In local mode, the key is held locally so the VM can start anytime.
Using the example of a PAW’s configuration, it typically hosts one desktop VM and one PAW VM. The Desktop VM needs to run anytime, while the PAW VM should be protected by HGS. This can be done by setting the host to local mode when create and start the desktop VM and setting the host to HGS mode when create and start the PAW VM.
It’s quite simple to change the setting. To set the host to local mode:
To change it to HGS mode:
Set-HGSClientConfiguration -AttestationServerUrl <url> -KeyProtectionServerUrl <Url>
If you are writing scripts, be sure to configure the host to the correct mode before creating or starting the shielded VM. Below is a sample script to create a shielded VM local mode:
# Change host to local mode
# Create an owner self-signed certificate
$Owner = New-HgsGuardian –Name 'Owner' –GenerateCertificates
# Create a Key Protector, which defines which fabric is allowed to run this shielded VM
$KP = New-HgsKeyProtector -Owner $Owner -AllowUntrustedRoot
# Enable shielding on the VM
Set-VMKeyProtector –VMName $VMName –KeyProtector $KP.RawData
# Set the security policy of the VM to be shielded
Set-VMSecurityPolicy -VMName $VMName -Shielded $true
# Enable vTPM on the VM
Enable-VMTPM -VMName $VMName
You can find the script to create remote mode shielded VM here.
If you have VMs in both modes running side by side, be sure to set the host in the correct mode before create or start them. If the host is running in the wrong mode for the VM, the VM will not be able to start. You can easily correct it by setting the security policy again on the VM after you change the host mode.