Load Balancing Remote Desktop Gateway with Citrix NetScaler Part 2

In Part 1 of this post, we setup a simple content switching vServer to front our Remote Desktop Gateway server. It accomplished two things:

 

  • Allowed Remote Desktop connections using the Windows RDP client with ‘Connect from Anywhere’ set to the RDG vServer address
  • Allowed applications to be launched from the RDWeb web portal
The vServer configuration is not quite complete. You may notice that connections from mobile devices don’t work using the RD client and connections from the RemoteAppsAndDesktops configuration on Windows 7 and later machines also do not work when they are on the same\inside network. Let’s get those working – we will add a second content switching policy bound to the SSL vServer and a second vServer listening on port 3389.
First, create the new CSW policy and bind it to the existing SSL CSW vServer:

 

  • Name: CSW-RDG-Mobile
    • Action: CSW-RDG-Action
    • Expression: HTTP.REQ.HEADER(“User-Agent”).CONTAINS(“MSRPC”)
 
Next, create a new CSW vServer (or standard load balancing server). First, create the LB service for RDP (predefined – otherwise, TCP 3389). Then create a new non-addressable LB vServer and bind the RDP service. Last, create a new CSW vServer on the same IP address as the RD Gateway SSL vServer and set the newly created RDP LB vServer as the default vServer –  no other CS policies are needed. Here’s what you end up with:

 

**Update 4/10/2016: Thanks to the feedback and comments below from Bill and Dan, it should be noted that the RDP client included with Windows 10 uses Secure WebSockets to connect. To enable this on the NetScaler, you can either modify the default HTTP profile or to be more granular, create a new HTTP profile with WebSockets enabled and bind to a specific vServer\service.

This can be done via the GUI under System > Profiles > HTTP Profiles

Or via command line (replacing http_profile1 with your new HTTP Profile):

set ns httpProfile http_profile1 -webSocket ENABLED

More information on HTTP profiles is available here: http://docs.citrix.com/en-us/netscaler/11/system/http-configurations.html

*Notes:

  1. Once upgraded to a WebSockets connection, the NetScaler does not process Layer 7 traffic on this connection.
  2. This will not currently work with a Unified Gateway CS vServer due to the NetScaler Gateway target vServer using WebSockets for HTML5 Receiver. I will investigate this further, though the native RDP proxy functionality in NetScaler should work in place of RDGateway.
  3. The following registry entry will disable WebProxy connections in the Windows 10 RDP client:

HKEY_CURRENT_USER\Software\Microsoft\Terminal Server Client

Name: RDGClientTransport
Type: Dword
Data: 1

14 thoughts on “Load Balancing Remote Desktop Gateway with Citrix NetScaler Part 2

  1. Hi Jacob!

    I am trying these instructions on NetScaler 11 VPX (free) and when I try and connect with RDP client (using the secure gateway address) I get the error: Your computer can’t connect to the remote computer because an error occurred on the remote computer that you want to connect to.

    I’ve already spent a good many hours trying to get RD Gateway content switching to work, even before I came across this blog post. I’ve tried all sorts of combinations and cannot get it to work. Your article is the only thing I could find which is exactly what I need: ability to content switch to a 2012 R2 RD Gateway server.

    In my demo environment I have an Exchange server “mail.domain.com” and an RD Gateway server “secure.domain.com”. I’ve got content switching enabled and have some initial rules to match the hostname in the request. Exchange works perfectly, RD Web page loads OK and can login, but can’t launch apps from RD Web. Also, cannot RDP using connect from anywhere set to the citrix vServer.

    I’ve confirmed that if I bypass the NetScaler the rd gateway does work.

    Is there anything else missing from your article, that you might not have included because it would be obvious to someone familiar with NetScaler? Because I am not familiar with this at all, this is the first time I’ve been looking at it.

    Thanks in advance,
    Bill

    • Hi Bill,

      To be honest, I have not used the RDGateway configuration in some time. I primarily use XenApp for remote access to my lab (for obvious reasons). Though I can tell you that this configuration did work – the hardest part was determining the 3 CS policies and the 3389 vServer for internal RemoteAppAndDesktop connections. Let me see if I can spin up an RDG and Session Host in the lab real quick and get this configured again.

      My only other thought is because you are content switching based on request hostname, your policy expressions for RDG would look like this:

      HTTP.REQ.HOSTNAME.EQ(“secure.domain.com”) && HTTP.REQ.URL.REGEX_MATCH(re-^/RDWeb/*-)
      HTTP.REQ.HOSTNAME.EQ(“secure.domain.com”) && HTTP.REQ.HEADER(“User-Agent”).CONTAINS(“MS-RDGateway/1.0”)
      HTTP.REQ.HOSTNAME.EQ(“secure.domain.com”) && HTTP.REQ.HEADER(“User-Agent”).CONTAINS(“MSRPC”)

      So that you match the requested hostname as well as the user agent string, etc.

      • I’m having the same issue as Bill. Can’t seem to get the RDP connection to get to the Gateway. Web Access piece works perfectly. I have seen mentioned of UDP 3391 for Gateway, not sure if it applies here.

      • I was able to fix my issue by checking “Enable WebSocket connections” in the nshttp_default_profile. Once I did that, I was able to access the Gateway with no problem.

        • Hi Dan and Bill,

          Thanks for your feedback. I had honestly not tried the Windows 10 RDP client using this setup, so I was not aware of the change. I have updated the post to reflect the WebSockets requirement and some configuration options available.

          I’ll try to investigate this specific scenario further.

          Thanks again.

      • I have progressed a bit further with this. Turns out I am having the same problem as Dan. I have to enable WebSocket connections. Since my client is Windows 10, it uses this method. It started to dawn on me when I tried the connection from a spare Win7 machine and it worked. Then I knew it was a Win10 issue and a bit of googling brought me to a post about WebSocket connections.

  2. I have created a copy of the ‘nshttp_default_profile’ and called it ‘nshttp_custom_profile’ and enabled ‘WebSocket Connections’ on this profile.

    I then assigned this profile to my SSL Content Switching Virtual Server.
    I’m still unable to make a connection from Win10 without setting the RDGClientTransport registry setting.
    I must be missing something else here! 🙁

  3. Hi there, fantastic couple of articles on this subject that have helped me get RD Gateway 2016 load balanced (yes, still no built in load balancing like the Connection Brokers).
    What I can’t work out from your article though is,
    1. Why do we need to create the RDP vserver, and
    2. If it is needed, what servers should be sitting behind the Netscaler RDP services? Should the RD Gateway servers be sitting behind the RDP Services, or the RDS Session Hosts?

    Everything seems to be working as expected with just the CSW vServers/policies in place. This includes Windows 10 access (although login is slow – haven’t investigated that yet) and RemoteApp Workplace.
    I’m yet to test a full range of Operating Systems, but so far it seems to be OK without the extra RDP vServer.

    • Hi Rob,

      Thanks for the feedback. I believe the RDP vServer was pointed at the gateway and was used for RemoteAppandDesktop connections from Windows 7 machines inside the network. This may have changed with Win10 or RDP 10.2, but it was required with Win7.

  4. Thought I’d leave a quick note that by adding the RDP vServer, login times are drastically reduced.
    Thanks heaps again for the articles!

  5. Hi, your article is great. Helped me setup RD Gateway behind our Netscaler. But I am having a problem. Connections from Windows 7 and Windows 10 are fine. But I cannot connect from Windows 8, 8.1, 2012 or specifically RDP v8 or v8.1. It just stays stuck on Initiating remote connection. Has anyone had this problem? What could be the problem?

Leave a Reply