Previous Post in Series: Part 5: Deploy and Configure the Host Guardian Service
Welcome to Part 6 of the Server 2016 Features Series. In this section we’re going to configure all necessary resources to enable us to deploy shielded VMs on our guarded fabric. You’ll need to have already configured a library server within SCVMM, if you’ve yet to do this, I’ve documented the process HERE
You can jump to any of the sections covered in this post using the links below:
- Create a Shielded VM Template in SCVMM
- Create and Prepare VM Shielding Helper VHD
- Create Shielding Data File
- Create a Shielded VM in SCVMM
- Shield an Existing VM in SCVMM
NOTE: For the purposes of this guide, we’ll be deploying our shielded VMs as an administrator that has access to SCVMM. In reality, it’s unlikely that tenant will be able to do this and will be deploying their VMs using the Windows Azure Pack portal. Setting that up is out of scope for this guide but will be covered in a later one.
Create a Shielded VM Template in SCVMM
When deploying regular VMs from SCVMM, you’d use a template right? So it’s good news that we can also create templates for our shielded VMs. The added security of these templates does require a little more effort to setup, but that’s what we’re here to step through 🙂
We’re going to cover creating a shielded template disk and a VM template that makes use of it.
Prepare an Operating System VHDX
The first thing we’ll need to do is prepare an OS disk that we’ll run through the “Template Disk Wizard” RSAT tool. You can use any of your existing tools to create this disk (DISM for example), however I always prefer to create a new VM from ISO and will be using this process now.
Before creating our disk though, there are a few requirements to be aware of, see table below:
|Requirement for VHDX||Reason|
|Must be a GUID Partition Table (GPT) disk||Needed for generation 2 virtual machines to support UEFI|
|Disk type must be Basic as opposed to Dynamic.|
Note: this refers to the logical disk type, not the “dynamically expanding” VHDX feature supported by Hyper-V.
|BitLocker does NOT support dynamic disks|
|The disk has at least two partitions. One partition must include the drive on which Windows is installed. This is the drive that BitLocker will encrypt. The other partition is the active partition, which contains the bootloader and remains unencrypted so that the computer can be started.||Needed for BitLocker|
|File system is NTFS||Needed for BitLocker|
|The operating system installed on the VHDX is one of the following:|
Windows Server 2012, 2012 R2 or 2016
Windows 8, 8.1, or 10
|Needed to support generation 2 virtual machines and the Microsoft Secure Boot template|
|Operating system must be generalized (run sysprep.exe||Template provisioning involves specializing VMs for a specific tenant’s workload|
With all of that in mind, go spin up a VM so we can steal it’s disk 🙂
Once you’ve fully patched the OS, we need to run sysprep but before we do that, enable remote desktop as that is the tenants only means to access a shielded VM (other than remote PowerShell over the network assuming required ports have been opened and no ACL’s block it).
To do this, open an elevated PowerShell console and run the following:
Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server'-name "fDenyTSConnections" -Value 0 Set-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -name "UserAuthentication" -Value 1 Get-NetFirewallRule -DisplayName "Remote Desktop*" | Enable-NetFirewallRule
If you do forget to enable Remote Desktop or forget to open up Windows Firewall, it’s not the end of the world. WS-Man is enabled by default and the above rules can be added by using New-PsSession and Enter-PSSession to connect to the VM (it’s IP can be found in the SCVMM console)…pretty cool right?
Now we can sysprep the OS, instructions below:
Press “Windows Key + R” and type “sysprep”
Run the sysprep application
Select “Enter System Out-of-Box Experience…”, tick “Generalize” and select “Shutdown”. Now click “OK”
Once the VM has finished sysprepping (yeah it’s a word!), we’ll want to copy the disk. This will allow us to keep the VM for usage somewhere else later, including updating it as once it’s been signed, you will not be able to alter it.
NOTE: Don’t copy the VHDX to your VMM library just yet.
Sign and Protect the VHDX With the Template Disk Wizard
Before we can use a template disk to deploy shielded VMs, it must be signed and encrypted with BitLocker. To do this we will make use of the Template Disk Wizard RSAT tool. The wizard will generate a hash for the disk and add it to a Volume Signature Catalog (VSC). The VSC is signed using a certificate specified by either the tenant or the service provider (depending on who is supplying the template disk, as it can all be done by the tenant if that’s their preference) and is used in the provisioning process to ensure that the disk has not been altered or replaced with a disk the tenant hasn’t trusted. BitLocker is also installed on the disk’s operating system to prepare it for encryption during the VM provisioning process.
As the OS disk is modified in place, decide what server you want to install the VM Shielding RSAT tools on and copy the VHDX you prepared earlier across to it.
NOTE: The server you choose will need to be rebooted to complete installation of the tools.
Now log onto the server and install the Shielded VM RSAT Tools using the PowerShell below:
Install-WindowsFeature RSAT-Shielded-VM-Tools –Restart
You will now need to obtain a certificate to sign the VHDX, for production purposes, this certificate should be from a Certificate Authority trusted by both the tenant and the hoster. If however, this is purely for testing purposes then the PowerShell below will create a certificate that you can use.
NOTE: Tenants will be able to see details of the certificate when looking at the VSC of the disk (they’ll use this when creating their shielding data later)
New-SelfSignedCertificate -DnsName gimme.certificate.com
Armed with a certificate and prepared VHDX, we can launch the “Template Disk Wizard”, you’ll find it under “Windows Administrative Tools” in the Start menu
On the “Certificate” screen, click “Browse” and select the certificate you created above and click “OK”. Now click “Next”
Click “Browse” and select the VHDX you prepared earlier and click “Next”
Give your disk a friendly name and a version number (yup, 3 decimal places) and click “Next”
Review your choices and click “Generate” to sign your VHDX
This process may take a while depending on the size of the disk you created, and whether you went with Dynamic or Fixed. I also just noticed that hovering over the progress bar will show you the completion percentage…nice touch 🙂
Copy the Template Disk to the SCVMM Library
Now that we have a shielded template disk, we want to copy it across to our SCVMM library for use in VM provisioning, Carry out the steps below on your SCVMM server:
Copy the VHDX to your SCVMM library share folder, this could be local on the server or if you used this guide a dedicated share on your SOFS cluster (I’ve yet to update my VMM deployment with this piece, coming very soon).
Refresh the SCVMM library. Navigate to “Library”, right-click on your library server object and select “Refresh”.
Once the refresh job has completed, you should see the new shielded VHDX in your library…and hey LOOK, it’s got a shielded icon 🙂
You can also right-click the context bar at the top of the pane and enable a column for denoting resources as “Shielded”
Now we want to give SCVMM some information about the disk, like it’s operating system and Virtualisation platform:
In the “Physical Objects” pane of the library, right-click on your shielded VHDX and select “Properties”
Change the “Operating System” to “Windows Server 2016*” and change the “Virtualization Platform” to “Microsoft Hyper-V”. Now click “OK”
Create a Shielded VM Template in SCVMM (Continued)
Before we can use our newly signed template disk, we need to create a VM template, much in the same way you already do for non-shielded VMs. The main differences being that options like Generation 2, UEFI, secure boot etc. are greyed out. Tenant customisation options are also limited.
Let’s crack on:
Navigate to “Library”, right-click “VM Templates” and select “Create VM Template”
Select “Use and existing VM template or virtual hard disk stored in the library” and click “Browse”
Select your signed template disk, you can make this earlier by right-clicking the context bar and enabling a “Shielded” column. Now click “OK” and “Next”
Type a name for your VM Template and click “Next”
Modify the resources as required, Processors, Memory and Availability. Make sure you attach your network adapter to a VM Network as this is a tenants only route into a shielded VM. If you’re using static IP pools, these should already be configured (See my earlier guide for info on how to do this HERE). Now click “Next”
On the “Operating System” tab, add a product key if you’re providing this on behalf of your tenants, or leave it blank if not (more on this later in the unattend file creation section). For the purposes of this guide, I’ll be populating it in SCVMM as I’ll be both the hoster and the tenant. Confirm you have the correct time zone configured and click “Next” and “Create”
Notice that you’re new template also shows that it’s for deploying shielded or encryption supported VMs.
We’re not going to deploy a shielded VM just yet as we’ll need a Shielding Data file for that. Let’s finish up with the hoster side of things before moving on to that 🙂
Create and Prepare VM Shielding Helper VHD
So we’ve made sure that we can allow our customers to create shielded VMs from scratch, but what if one of our customers wants to shield an already deployed VM…that’s where the VM Shielding Helper VHD comes in. This section will detail the step required to get this up and running.
Create a new Generation 2 VM running Windows Server 2016 from ISO* (currently this can be core, desktop experience but NOT Nano).
The VM Shielding Helper VHD must not be related to the template disks you created in Hosting service provider creates a shielded VM template. If you re-use a template disk, there will be a disk signature collision during the shielding process because both disks will have the same GPT disk identifier. You can avoid this by creating a new (blank) VHD and installing Windows Server 2016 onto it using your ISO installation media.
Once the VM is up and running, log into the desktop, complete any setup steps and make sure the VM is in a working state. Now shut down the VM
NOTE: Do not sysprep the VM
Now copy the VHDX to the server you used for signing the template disk earlier in this guide (it already has the required RSAT tools installed)
Launch an elevated PowerShell console and run the following:
Initialize-VMShieldingHelperVHD -Path ShieldingHelper.vhdx
Once the command has completed, repeat the Copy the Template Disk to the SCVMM Library section from earlier.
Now we need to tell SCVMM to use this VHDX when shielding existing VMs.
Navigate to “Settings”, “General” and “Host Guardian Settings”.
Click “Browse” and select the ShieldingHelper VHDX you just copied to the library. Now click “Finish”
NOTE: Now delete the VM you used to create the ShieldingHelper disk as starting it up again will corrupt the ShieldingHelper disk.
Create Shielding Data File
For the purposes of this guide we’ll be creating this file as a tenant with access to SCVMM, when a tenant does this in production, certain information will be made available for download from the Windows Azure Portal. I’ll be covering this in a later guide and as such it’s out of scope for this one.
A shielding data file comes in .PDK format and holds the following secrets:
- Unattend file – Used to specialise the VM
- Customer certificates – An RDP certificate is the example we’ll be using
- Administrator account password
- Volume Signature Catalog file – Provided by the tenant or hoster (depending on who provides the signed VHDX), this details what signed disks the tenant has trusted
- Guarded Fabric Metadata XML – This is always provided by the hoster and denotes what guarded fabrics a tenants shielded VM can run on
Obtain a Certificate for RDP
Being that tenants can only connect to their shielded VMs using RDP or other remote management tools, it is important that tenants know they are connecting to the correct endpoint. We are going to satisfy this by configuring an RDP certificate Remote Desktop Services will present to the user when they connect to their shielded VM. Tenants will generally create these certificates using their own PKI but for the purposes of this guide we’ll be using a self-signed certificate.
NOTE: When generating an RDP certificate, make sure it’s a wildcard as you’ll be using the same shielding data file to spin up multiple virtual machines.
Log onto the server you used earlier for signing your template disk (as it already has the required RSAT tools installed).
Launch an elevated PowerShell console and run the following to generate your self-signed certificate:
$RDPCertificate = New-SelfSignedCertificate -DnsName "*.domain.com" $Password = ConvertTo-SecureString -AsPlainText "Password" –Force Export-PfxCertificate –Cert $RDPCertificate -FilePath C:\Temp\rdpCert.pfx -Password $Password
Create an Answer File
Microsoft have made this process MUCH easier than it was in Technical Preview by giving us a new PowerShell cmdlet that takes most of the pain away 🙂 Cheers guys, this was my least favourite part.
Still on the same server as above.
To install the new module, run the following from an elevated PowerShell console:
Save-Module -Name guardianFabricTools -Path C:\Temp\ Install-Module -Name GuardedFabricTools
Notice the warning when installing. You may also receive an error relating to your configured Execution Policy, this can be set to the following values:
You can set this to “Unrestricted” long enough to allow you to install the module by running
Set-ExecutionPolicy -ExecutionPolicy Unrestricted
You can set it back to the default value by running:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned
For this guide, we’ll have to provide the following values to our New-ShieldingDataAnswerFile command
- AdminPassword – This will be the password for the local administrator account
- RDPCertificatePath – This is the path to the RDP PFX we created earlier
- RDPCertificatePassword – This is the password we locked the above PFX with
- StaticIP – This sets the unattend file to pull IP and DNS settings for the VM from an SCVMM static IP Pool
- ProductKey – This states whether we’ll be providing the product key in the unattend file or using one configured in in the shielded VM template in SCVMM
- Language – Required as sysprep resets this back to en-US, which is fine if you’re in America…I’m not, so I’ll set it back to en-GB
The following PowerShell will create an unattend file that we can use with the current setup of my environment, you may need to make slight changes to this to work with your environment, if you’ve followed the guide completely though, you should be good.
$AdminPassword = ConvertTo-SecureString -AsPlainText "password" -Force $RDPCertPassword = ConvertTo-SecureString -AsPlainText "password" -Force New-ShieldingDataAnswerFile -AdminPassword $AdminPassword -RDPCertificateFilePath C:\Temp\rdpCert.pfx -RDPCertificatePassword $RDPCertPassword -ProductKey UserSupplied -StaticIP -Path C:\Temp\unattend.xml -Language en-GB
NOTE: Make sure you’re SCVMM setup is in line with the warning detailed in the screenshot below:
Obtain the Volume Signature Catalog File
To get the VSC file, log onto your SCVMM server and launch an elevated PowerShell prompt and run the following:
This code assumes that you only have one signed disk in your SCVMM library at the time of running, if this is not the case, modify the first line as follows:
$Disk = Get-SCVirtualDisk -Name "NameOfSignedDisk" $Disk = Get-SCVirtualHardDisk | ? Shielded -eq True $VSC = Get-SCVolumeSignatureCatalog -VirtualHardDisk $Disk $FileName = $Disk.Name $VSC.WriteToFile("C:\Temp\$FileName.vsc")
NOTE: As previously mentioned, a tenant would generally download this file from the Windows Azure Pack portal.
If the tenant created the signed VHDX themselves, then they could obtain it’s VSC by running the following command:
Save-VolumeSignatureCatalog -TemplateDiskPath "PathToDisk.vhdx" -VolumeSignatureCatalogPath "VSCSaveLocation.vsc"
Obtain Fabric Guardian Metadata File
The last thing we need to do before we can create our Shielding data is to designate which guarded fabrics the tenants VMs are allowed to run on. For this, we need to get a hold of the guardian metadata. For the purposes of this guide, we’ll be obtaining this using an SCVMM PowerShell cmdlet.
Log onto your SCVMM server, launch an elevated PowerShell console and run the following:
Invoke-WebRequest "http://HGS Service FQDN/KeyProtection/service/metadata/2014-07/metadata.xml" -OutFile C:\Temp\GuardianName.xml
…and with that, we can FINALLY create the tenants shielding data file
Create a Shielding Data File
Being that this will always be done by the tenant, lets act like one and run all this from a desktop machine. Microsoft have made their RSAT tools available for download and install for Windows 10. If you don’t have access to a Windows 10 machine, then you can continue this process on the server you used to sign the VHDX earlier (if that’s the case, skip the RSAT download and install steps).
Assuming however you DO have a Windows 10 machine, you can download the tools HERE
Now copy the unattend file, RDP file, VSC file and metadata XML file to your local machine C:\Temp\
From your start menu, navigate to “Microsoft Administrative Tools” and select “Shielding Data File Wizard”
On the “File and Policy” screen make sure “Create a new shielding data file” is ticked and click “Browse” to select a storage location for your secrets PDK.
The first .PDK we’re going to create will be for fully shielding VMs, as such, click “Shielded” and click “Next”
You’ll know from earlier, we needed to download the hoster guardian metadata file to confirm which guarded fabrics we could run our VMs on, now we need to create a local guardian. This gives us as the owner of a VM, the ability to change it from Shielded to Encryption Supported and vice versa.
To create our local guardian, click “Manage Local Guardians” and “Create”.
Give your guardian a name and either generate self-signed certificates or select existing certificates you already own. For the purposes of this guide, we’ll be using self-signed.
Select “Self-signed guardian” and click “Next”, “Create” and “Close”. Now click “OK” to get back to the wizard.
Now we to need import the hosters guardian metadata file we obtained earlier.
Again, click “Manage Local Guardians” and click “Import”.
Click “Browse” and select the locate your metafile file, enter a name for the guardian and click “OK”
Click “OK” to get back to the wizard.
Back on the “Owners and Guardians” page, select the local guardian you just created from the drop-down, and select the hosters guardian you just imported from the list below it. Now click “Next”
On the “Volume ID Qualifiers” page and click “Add”
Click “Browse” to locate the .VSC file you obtained earlier and click “OK”. Now click “Next”
On the “Specialization Files” page, click “Browse” and locate the unattend file you created earlier. The unattend file is checked before it’s added to make sure there are no issues with its layout etc…so that’s good 🙂
Click “Add” and browse to the RDP file you created earlier, now click “Next”, “Generate” and “Close”
Congratulations, you now have all you need to deploy a shielded VM 🙂
Create a Shielded VM in SCVMM
It’s all gonna work right? RIGHT? Let’s find out 🙂
In the last section, you created a .PDK containing all the tenant secrets necessary to deploy a Shielded VM, we now need to upload that file to SCVMM.
Upload VM Shielding Data to SCVMM
Copy the .PDK file to your SCVMM server and from the SCVMM console, navigate to “Library”, “VM Shielding Data”, right-click and select “Import Shielding Data”
Click “Browse” and locate your .PDK file.
Now enter a name for your file and optionally, a description. Now click “Import”
Deploy a Shielded VM from Template
OK, now let’s deploy a shielded VM, shall we?
From your SCVMM console, navigate to “Library”, “VM Template”, right-click on your shielded template and select “Create Virtual Machine”
Enter a name for your shielded VM and click “Next”
On the “Configure Hardware” tab, configure you’re VM as desired but make sure you put the VM on a VM network which has either DHCP or uses a static IP pool (as we’ve done for this guide – See screenshot)
Now click “Next”
Click “Next” on the “Configure Operating System” tab as already configured this when creating the template.
Click “Browse”, highlight the shielding data file you just uploaded and click “OK” and “Next”
Select the host group that contains your guarded hosts and click “Next”.
Select a host and click “Next”.
On the “Configure Settings” tab, accept the default or change the VMs storage location and select “Next”
Configure the “Add Properties” screen as desired and click “Next” and “Create”
You can watch the job progress on the pop-up jobs window, the deployment will take a while depending on the speed of your hardware…go get a coffee 🙂
Good coffee? You should now be looking at a job status like this:
So what’s left to do? Power up your VM and make sure you can RDP to it. You can find it’s IP address within the SCVMM console:
In the interest of transparency I made a mistake deploying my first shielded VM and ended up with an IP conflict…WHOOPS! What I’d actually done was manually specify an IP address from my static pool, which SCVMM knew nothing about and therefore gave it out to my shielded VM. Don’t be me, be better!
This however does allow me to reiterate that without networking, a shielded VM is basically a brick 🙂
If you also find yourself in the situation where you can’t RDP to the VM, recreate your .PDK file but instead of selecting “Shielded”, select “Encryption Supported”. This will allow you to console onto the VM and troubleshoot what’s causing the issue. It’s very likely that RDP wasn’t enabled or the networking isn’t being applied as expected, or like me, it’s an IP address conflict. Once you’ve resolved the issue, deploy the VM using your “Shielding” .PDK file.
So…I deployed another VM after shutting down my moron subroutine and it went swimmingly 🙂
You’ll notice that when you RDP, you see a popup which shows the RDP certificate you placed in your shielding data file, so that works!
So we’ve successfully deployed a fully shielded VM and everything is working as intended, but before we move on, let’s take a look at a couple of things we CAN’T do using our usual management tools.
Trying to console on to the VM from SCVMM is greyed out…hmmm
Trying to do the same from Hyper-V manager gives us a little more insight into why this is:
You’ll also notice that you can’t see what’s going on inside the VM from its preview window. This is because the video memory isn’t captured because the VM runs within a protected process, which other processes (like video memory redirection) can’t be attached to.
OK, so we’ve deployed a shielded VM from scratch, but what if we what to shield an existing VM? Remember that shielding helper VHDX we created earlier?
Shield an existing VM in SCVMM
The shielding data file we created earlier cannot be used to shield existing VM as their requirements are slightly different. So let’s create a new one.
From your Windows 10 machine (or server if you didn’t have one), launch the “Shielded Data File Wizard”.
Click “Browse” to select a storage path and name for your .PDK
Select “Shielding data for existing VMs and non-Shielded templates”, “Shielded” and click “Next”
Select the local guardian you created earlier from the drop-down and highlight the hoster guardian you imported earlier from the windows below it. Click “Next”
Add any file that you want to upload to the VM and click “Next” – you’ll notice that you don’t need to add an unattend file OR a Volume Shielding Catalog file here as the VM you’re shielding already exists.
Now click “Generate”
Copy your new Shielding Data File to your SCVMM server and import it following the process we used above
Deploy a VM from a non -shielded template. Once it’s up and running, make sure you can RDP to it and carry out any addition setup steps.
Now shut down the VM as it can’t be shielded while it’s running.
Right-click the VM you want to shield and select “Shield”
You should only be able to select the Shielding Data File you just uploaded as they’re scoped down based on shielding method. Select your .PDK and click “OK”
During this process you will see a new virtual machine is created called “Temporary Shielding Helper*” this will also be deleted as part of the shielding job. There will be a few warnings and/or errors in the SCVMM job logs regarding this temporary VM as discoveries etc. that are run against it may fail. These can be ignored, and hopefully MS will supress these in a future patch as it ruins my sea of green ticks 🙂
The job should complete with the following status:
Your VM should also now show as shielded within the console:
So there you have it, you can now deploy shielded VMs to your guarded fabric. Join me in part 7 where I’ll be detailing how to offer this service to tenants via the Windows Azure Portal.