Microsoft Remote Desktop services (RDS)

Remote Desktop Services, formerly Terminal Services, is a technology from Microsoft that allows users to access remotely to a session-based desktop, virtual machine-based desktop or applications hosted in a datacenter from their corporate network or from the internet.

Multiple RDS servers can be used in a farm. Hence we need to balance the load against them.
To achieve this purpose, we have different ways:
* using a connection broker
* using a load-balancer with the connection broker
* using a load-balancer without the connection broker

Of course, our load-balancer of choice is HAProxy!
In this blog article, we’re going to focus only on the case where a load-balancer is used.

The main issue when load-balancing multiple Remote Desktop Services servers is to ensure a user the continuity of his session in case of a network outage.

Current article will focus on session high availability for an optimal end user experience.

HAProxy with a connection broker

The connection broker, formerly Session broker, main purpose is to reconnect a user to his existing session. Since Windows 2008, the connection broker also have some load-balancing mechanism.

So, why using a load-balancer if the connection broker can do load-balance?


Answer is simple: security. Since HAProxy is a Reverse-Proxy, it breaks the TCP connection between the client and the server. HAProxy can be deployed in DMZ to give access to users coming from internet to a RDS farm deployed in the VLAN dedicated to servers.

HAProxy configuration


Note: this configuration works for the ALOHA 6.0 and above and HAPEE (HAProxy Enterprise Edition) 1.5 and above.

[sourcecode language=”text”]
frontend ft_rdp
mode tcp
bind 192.168.13.128:3389 name rdp
timeout client 1h
log global
option tcplog
tcp-request inspect-delay 2s
tcp-request content accept if RDP_COOKIE
default_backend bk_rdp

backend bk_rdp
mode tcp
balance leastconn
persist rdp-cookie
timeout server 1h
timeout connect 4s
log global
option tcplog
option tcp-check
tcp-check connect port 3389 ssl
default-server inter 3s rise 2 fall 3
server srv01 192.168.13.13:3389 weight 10 check
server srv02 192.168.13.14:3389 weight 10 check
[/sourcecode]

HAProxy without a connection broker

HAProxy can be used on its own to perform session load-balancing and resumption. For this purpose, it needs a stick-table where the user-server association is stored.
A peers section is added to the configuration. So we can share session persistence information between a cluster of ALOHAs or HAPEE servers.

[sourcecode language=”text”]
peers aloha
peer aloha1 192.168.13.1:1023
peer aloha2 192.168.13.2:1023

frontend ft_rdp
mode tcp
bind 192.168.13.128:3389 name rdp
timeout client 1h
log global
option tcplog
tcp-request inspect-delay 2s
tcp-request content accept if RDP_COOKIE
default_backend bk_rdp

backend bk_rdp
mode tcp
balance leastconn
timeout server 1h
timeout connect 4s
log global
option tcplog
stick-table type string len 32 size 10k expire 8h peers aloha
stick on rdp_cookie(mstshash)
option tcp-check
tcp-check connect port 3389 ssl
default-server inter 3s rise 2 fall 3
server srv01 192.168.13.13:3389 weight 10 check
server srv02 192.168.13.14:3389 weight 10 check
[/sourcecode]

To know the user-server association, we can simply read the content of the stick-table:
[sourcecode language=”text”]
echo show table bk_rdp | socat /var/run/haproxy.stat –
# table: bk_rdp, type: string, size:10240, used:5
0x21c7eac: key=Administrator use=0 exp=83332288 server_id=1
0x21c7eac: key=test-001 use=0 exp=83332288 server_id=2
[/sourcecode]

We can easily read the login used by the user, the expiation date (in milliseconds) and the server ID used for the session.

Links