Remote Desktop IP and Loopback Virtualization with Horizon Instant Clone farms

Using Microsoft RDSH for delivering session desktops and apps is still a very popular approach. While cost effective, it lacks many features and functionalities that are available in the full VDI. One of them is lack of a unique IP address tied to a specific user in a given time. Having 25 users sharing sessions on a single RDSH VM means that our apps and network systems will see multiple users traffic originating from the same IP source. This might cause problems around application compatibility, license assignment and network monitoring. Another example is an application that binds to a server’s IP address or to all interfaces (0.0.0.0) on a static port – thus allowing only one instance to be started on the RDSH host. It’s the same if an application tries to bind to a loopback address.

An answer to all of this are forgotten Microsoft RDSH features called “IP Virtualization” and “Loopback Virtualization” introduced in Windows Server 2008 and still available in Windows Server 2012/2016 (and most likely 2019) . There is very little and outdated documentation on the Internet on that topic, including docs from Microsoft and Citrix (the company from the 90’s 😉 That’s why I decided to test and document this functionality in my lab.

A little bit of theory

First of all, IP and Loopback Virtualization are broker independent. You can configure both or only one of those features on each RDSH host. They work on the Winsock level of the operating system and can be configured with any Remote Desktop Protocol Provider including Blast Extreme. IP Virtualization provides unique dynamically-assigned IP address for each session established on an RDSH host. Those IP addresses can originate from DHCP or a static pool defined by an administrator and can be available to any or a specific application started within the user session. They work as a filter between the application itself and Winsock. For IP Virtialization, if an application makes a Winsock call, the feature intercepts the answer and replaces the server IP address with a unique IP assigned to the session. For loopback it replaces 127.0.0.1 with incremental IP – 127.0.0.2, 127.0.0.3 etc. So

How to configure IP Virtualization

There are three options to configure IP Virtualization: GPO, Powershell and WMI. We will focus on GPO here. There are two policies in Computer Configuration\Administrative Templates\System Components\ Remote Desktop Session Host\Application Compatibility:

“Turn on Remote Desktop Virtualization” – allows you to enable the feature and decide whether to use it for specific executables or for an entire session.
“Select the network adapter to be used for Remote Desktop IP Virtualization” – is used to select a network adapter to be used. Strangely, we do not point to a specific network adapter by MAC or name, rather we specify a CIDR (i.e. 192.168.0.0/24) network address to look for on all interfaces.

After this configuration is done (followed by gpupdate.exe /force or a reboot) you can notice that after you connect with a Horizon Client (or just mstsc.exe) to the RDSH host, an additional IP address will be assigned:

And a new lease will appear in your DHCP. In fact you will notice that your RDSH server requests additional 2 addresses “up front” for future sessions, probably to have an ACK available immediately during logon:

Although the address is marked as “Deprecated” in fact it is the one that will be used to manipulate what Winsock will answer the calls. All the network traffic originating from this session will be visible to external apps and systems as coming from this IP:

Setting up static IP Pool

An example above used DHCP as a source for session IP addresses. If you wish, you can configure a static IP Pool in the RDSH server registry:

Navigate to HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAPPSrv\VirtualIP.

Create a new REG_SZ registry setting named IPPool and in the Value data box, type “%SystemRoot%\system32\TSVIPool.dll”.

Create a new registry key named IPPool.

Inside IPPool key create a new REG_SZ registry setting named Start and in the Value data box, type the starting IP address in the desired IP address range, and then click OK.

Create a new REG_SZ registry setting named End and in the Value data box, type the ending IP address in the desired IP address range.

Create a new REG_SZ registry setting named SubnetMask and in the Value data box, type the subnet mask for the desired IP address range.

Alternatively, if you wish to use specific IP addresses rather than a scope, in the IPPool key create a Multi-String Value with the name StaticIPList and in the Value data box, type the desired IP addresses.

How to configure Loopback Virtualization

Loopback Virtualization do not offer GPO policies for configuration. We have to do it through the registry or using a Powershell/WMI Script. The one I used for testing is referenced below with some explanations:

$obj = gwmi -Namespace “Root\CIMV2\TerminalServices” Win32_TSVirtualIP$obj.SelectNetworkAdapter(“00-50-56-A7-A8-73”) # change for your mac address

$obj.SetVirtualIPActive(1) # needed for loopback

$obj.SetVirtualIPMode(0) # 0 for session , 1 for application

$obj.SetVirtualizeLoopbackAddressesEnabled(1) # enable loopback virtualization

This actually sets several registry entries:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAppSrv\VirtualIP]
“EnableVirtualIP”=dword:00000001
“ComponentDLL”=”%SystemRoot%\\system32\\TSVIPSrv.dll”
“VirtualizeLoopbackAdresses”=dword:00000000
“VirtualMode”=dword:00000001
“IPPool”=”%SystemRoot%\\system32\\TSVIPool.dll”
“AdapterAddress”=”00-00-00-00-00-00” 

The reference for the Win32_TSVirtualIP class can be found here:
https://docs.microsoft.com/en-us/windows/win32/termserv/win32-tsvirtualip?redirectedfrom=MSDN

How to specify apps allowed to use Loopback Virtualization

You can configure them using a GPO for IP Virtualization described above, or directly in the registry using this example:

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAppSrv\VirtualIP\PerApp]
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\TSAppSrv\VirtualIP\PerApp\yourapp.exe]
“FullPathName”=”C:\\Program Files\\yourapp\\bin\\yourapp.exe

Alternatively, there is a AddProgram method inside Win32_TSVirtualIP class that can be used to script it.

Horizon Instant Clone considerations

Although VMware do not state official support to this functionality as this is 3rd party area, my tests show that IP Virtualization and Loopback Virtualization are fully compatible with Horizon Instant Clone RDSH farms (and also with Full Clones), although some considerations are important:

  • It’s better to go with GPO based configuration and use CIDR adresses to specify the network adapter on which this function should be enabled. With this approach you don’t have to know the MAC address of the “yet to be created” Instant Clone host.
  • Use seperate Organizational Units in Active Directory to seperate Pools attached to different CIDR network segments for proper GPO attachement.
  • Those policies do not require reboot, so they will be applied during Instant Clone creation even if created after image push (refer to https://kb.vmware.com/s/article/2150495)
  • Even if you configure IP Virtualization with GPO, you still need to enable Loopback Virtualization with a script as described above as there is no policy for that. You can do it with the script referenced above as a ClonePrep Post-synchronization script, before you can consider gpupdate /force but test it first. Also remember about the 20s limit for the ClonePrep scripts, this can be extended if necessary.

Unique IP for Internet Explorer based web apps

Your use case might not involve traditional Win32 apps but instead you need to provide webapp servers a unique IP identification of each user connecting from Internet Explorer running on an RDSH host. If so, there is also a Horizon Agent feature called “Client IP Transparency”. This feature manipulate X-Forwarded-For (XFF) HTTP header field and injects the IP of the client system used by the user. This feature is VMware propertiary and completely independent from the MS IP and Loopback virtualization. You can read more about it on my colleague’s blog: https://blogs.vmware.com/euc/2017/11/vmware-client-ip-transparency-explained.html

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s