Certificates for Horizon HTML Blast Agent and non-persistent desktops

Background

If you wish to have the connection server hand off an HTML5 blast connection directly to the horizon agent then there is a requirement for there to be a trusted certificate on the desktop.

When using the Connection server as a gateway this is not required.

In addition, with UAGs providing external access you need to turn the Blast gateway off. You can use a dedicated Connection server(s) for external access, but this pairing requirement was a limitation of security server that was lifted with UAG so I don’t want to deploy additional servers.

I also want to avoid using a wildcard cert if at all possible and this all needs to happen automatically of course.

Lab Setup

I’m testing in a small lab using Horizon 7.7 Connection Server, UAG 3.4 and an internal Microsoft CA. I have enabled certificate auto enrolment which is already well covered online (couple of links below).

*Ensure you configure the cert template to have an exportable key*

*Ensure you include both server and client authentication in template*

Horizon internal cert request and deploy – here

Microsoft Computer Cert Auto enrolment – here

Enable firefox\chrome to trust Microsoft CA certs – here

I am using 2 instant clones pools, with both a windows 7 sp1 (latest patches) and windows 10 (version 1809) master images.

Right, off we go.

Firstly, let’s ensure that HTML5 access is enabled in the pool settings

C:\Users\christ\AppData\Local\Temp\\SnagitTemp\Snag_19cb6433.png

And ensure the blast gateway is not in play.

Now, let’s try accessing a desktop via the HTML5 client. I’m using firefox here.

C:\Users\christ\AppData\Local\Temp\\SnagitTemp\Snag_19ea6dc1.png

Two things to note, in addition to being flagged as not secure, the connection is using the IP address of the agent. We need to use a DNS name. To change this behavior, we can alter the Horizon LDAP attribute to prefer DNS names (using ADSI edit below). The VMware document explaining this is here

C:\Users\christ\AppData\Local\Temp\\SnagitTemp\Snag_19e701e7.png

After completing the change and trying again we still receive an insecure connection but this time it is using the DNS name.

C:\Users\christ\AppData\Local\Temp\\SnagitTemp\Snag_19eb9c3f.png

The blast client is using the self-signed certificate that is generated when the agent is installed.

VMware tell us that we can change this behaviour by obtaining our trusted cert thumbprint, tweaking a registry key and restarting the blast service. https://kb.vmware.com/s/article/2088354

No problem! – I’ve already setup autoenrollment and I can do the rest with a powershell script.

## Get CA cert thumbprint

$domainname = "mydomain"
$FQDN = "$env:COMPUTERNAME.$domainname"
$Subject = "CN=$FQDN"

$thumbprint = (Get-Childitem -path cert:\LocalMachine\My | where {$_.Subject -like $Subject}).thumbprint

## Reformat Thumbprint

$regthumb = $thumbprint -replace '([0-9A-f]{2})', '$1 '

## Replace Reg Key

Set-ItemProperty -Path "HKLM:\SOFTWARE\VMware, Inc.\VMware Blast\Config" -Name SslHash -Value $regthumb

## Restart Blast Service

Restart-Service -DisplayName 'VMware Blast'

We have now established the 3 things that we need to happen.

  1. Trusted Cert must be deployed to local Machine store of Desktop – auto enrolment
  2. Blast Client requires a registry setting modification – powershell script
  3. Blast service needs restarting – powershell script

I confirmed that this process works as expected by running the steps manually on a persistent desktop and connecting without a security prompt.

However, I need all of these tasks to occur automatically to a freshly provisioned (non-persistent) instant clone prior to a user connection from an HTML5 client. This is where I ran into a few problems and, like so many things in life, it was all down to timing.

Windows OS

My initial thought was to run the PowerShell as a Computer Logon script in a GPO. However, due to the way instant clones pools deploy, that script would not trigger as it would need to run on the master VM (which is no use here as the certificate name would be different and it is not domain joined).

Next, I tried running the script as a post optimisation task (need to copy the .ps1 onto the Master image and call the powershell script from a batch file) during deployment.

A screenshot of a cell phone

Description automatically generated

This also did not work. After some head scratching and log checking it transpired that the script was indeed running successfully (this can be confirmed by examining the log file located in c:\windows\temp\vmware). The auto enrol was also successful so why was this not working?

A screenshot of text

Description automatically generated
A screenshot of a social media post

Description automatically generated

The auto enrol was happening after the post-sync script!

This turned me towards incorporating the certificate deploy in PowerShell to do the enrolment. However, when using windows 7 I ran into some limitations, I could not use the get-certificate commandlet but no worries I can use certutil to trigger the process too. No such issues with Windows 10 so either method can be used.

## Deploy Certificate - WIN7

certutil -pulse
sleep 5

## Deploy Certificate - WIN10

set-location -Path Cert:\LocalMachine\My

Get-Certificate -Template "Computer Auto Enroll" -Url ldap:

I also played with creating a scheduled task on the master image that triggers the script when the auto-enrolment (event ID 66) is logged and that also seems to work nicely (below) but I prefer the script solution which limits the amount of moving parts to manage.

A screenshot of a computer

Description automatically generated

So now we get a nice user experience logging into the desktop via the HTML5 client without using the Blast gateway.

HTML5 login with SSL cert

Hopefully that was of some use and gives an understanding of the process. In summary, steps required are:

  • Setup Certificate Autoenrollment with an internal CA
  • Create Powershell script(s)
  • Add script location to post synchronisation settings of required desktop pool
  • Publish IC Pool

Complete Script is below

## Deploy Certificate - WIN7

certutil -pulse
sleep 5

## Deploy Certificate - WIN10

set-location -Path Cert:\LocalMachine\My

Get-Certificate -Template "Computer Auto Enroll" -Url ldap:

## Get CA cert thumbprint

$domainname = "mydomain"
$FQDN = "$env:COMPUTERNAME.$domainname"
$Subject = "CN=$FQDN"

$thumbprint = (Get-Childitem -path cert:\LocalMachine\My | where {$_.Subject -like $Subject}).thumbprint

## Reformat Thumbprint

$regthumb = $thumbprint -replace '([0-9A-f]{2})', '$1 '

## Replace Reg Key

Set-ItemProperty -Path "HKLM:\SOFTWARE\VMware, Inc.\VMware Blast\Config" -Name SslHash -Value $regthumb

Share

You may also like...

13 Responses

  1. Mathew May says:

    Remember that the certificate you use must have it’s key set as exportable, otherwsie the blast service when restarted, generates a new self-signed cert and uses that instead.

    • theb0ss says:

      Yes, that is well worth pointing out – that needs to be addressed when setting up autoenrollment. Will add in.
      Cheers Mat

  2. hunyadi says:

    Really useful post – helped me get my head around Blast and PKI. Am now finding that with version 7.9 even when the key is set as exportable the blast service is generating a new self-signed cert when it’s restarted. The VMware kb only nominally applies to 7.4 Have you found the same with later versions since this post by any chance? Cheers

    • cjt says:

      Hi hunyadi,

      I’ve not updated my lab for a while and it’s not cropped up since I posted, will certainly take a look when I deploy 7.9 Let me know if you find out any further information.

      Cheers, CJT

    • Diego Sanches says:

      I had the same issue and figured out if you include a SAN entry point to the client ip address it works.

      • Diego Sanches says:

        Nvm, I found the issue, in my case my auto-enrollment is based on a template that serves only for Client Authentication Purposes and always worked on version 7.6/7.8. Now that I move to 7.10 is broken. Testing a certificate with Server Authentication Purpose fixed my issue without using SAN.

        • cjt says:

          Yes – turns out I had both server and client authentication included in my lab template so have not had a problem. I have added a note to the process to call this out so thanks for bringing it up.

  3. Diego Sanches says:

    Btw I made some minor adjustments to your script, not a big issue, but using the current script you can receive the following warnings on the Blast logs and you know how Vmware support works, if is not 100% blindly following their articles they will complain.

    2019-11-07 13:32:32.183+0100 [WARN ] 0x32a0 config::GetHexString: removed extraneous whitespace
    2019-11-07 13:32:32.183+0100 [WARN ] 0x32a0 config::GetHexString: converted upper to lower case

    To avoid them I’m using the following to put everything in lower case and trimming the additional space that was created in the end of the regthumb.

    ## Deploy Certificate – WIN10

    set-location -Path Cert:\LocalMachine\My

    Get-Certificate -Template “VMWAREWorkstationAuthentication-TEST” -Url ldap:

    ## Get CA cert thumbprint

    $domainname = “yourdomain”
    $FQDN = “$env:COMPUTERNAME.$domainname”
    $Subject = “CN=$FQDN”

    $thumbprint = (Get-Childitem -path cert:\LocalMachine\My | where {$_.Subject -like $Subject}).thumbprint

    ## Reformat Thumbprint

    $regthumb = $thumbprint.ToLower() -replace ‘([0-9A-f]{2})’, ‘$1 ‘

    ## Replace Reg Key

    Set-ItemProperty -Path “HKLM:\SOFTWARE\VMware, Inc.\VMware Blast\Config” -Name SslHash -Value $regthumb.TrimEnd(” “)

  4. Shimon says:

    Hi,
    What certificate type need?
    Are it like https certificate (server)
    Did you try to work with wildcard certificate?

    Thanks

    • cjt says:

      Hi Shimon,

      Yes this will work and is somewhat simpler with a wildcard cert but often domain names are not the same and this case was to use an internal and non-wildcard cert.

  5. Hawes29 says:

    Good Morning CJT

    We have been trying to get this to work for a while now and came across your great tutorial. We currently have an internal CA, but it isn’t configured for auto-enrollment. I have looked at copying the Enrollment Agent (computer) but there is a lot of setting and options to choose from, would you be able to offer any suggestions to which ones we should use?

Leave a Reply

Your email address will not be published. Required fields are marked *