Haproxy with RDP

Hi.
I have a problem with proxying Windows 10/Server RDP, the point is when i type srv1.example.com RDP app connects to virtual machine srv1 (win 10 pro) with ip 10.10.0.1, when i type srv2.example.com it connects to (win srv 2022) ip 10.10.0.2. With that config redirections work without problem but no matter what subdomain i type (have to be rdirected on domain server to my public ip) i connects to server in config (no checking domain etc).

frontend ft_rdp
mode tcp
bind *:3389
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
persist rdp-cookie
timeout server 1h
timeout connect 4s
log global
option tcplog
option tcp-check
server srv1 10.10.0.1:3389

But when i do smth like this (checking domain name and connecting to coresponding srv), RDP automatically refuses connection and post error 0x904 (cypher or network problems):

frontend ft_rdp
mode tcp
bind *:3389
timeout client 1h
log global
option tcplog
tcp-request inspect-delay 2s
tcp-request content accept if { req_ssl_hello_type 1 }
tcp-request content accept if RDP_COOKIE

acl host_srv1 req_ssl_sni -i srv1.example.com
acl host_srv2 req_ssl_sni -i srv2.example.com

use_backend bk_rdp_srv1 if host_srv1
use_backend bk_rdp_srv2 if host_srv2

backend bk_rdp_srv1
mode tcp
persist rdp-cookie
timeout server 1h
timeout connect 4s
log global
option tcplog
option tcp-check
server server1 10.10.0.1:3389

backend bk_rdp_srv2
mode tcp
persist rdp-cookie
timeout server 1h
timeout connect 4s
log global
option tcplog
option tcp-check
server server2 10.10.0.2:3389

Anyone have any idea?

I know there is option with windows server rd gateway but i dont want to use it, “serwers” have to be separated and have no communication between each other.

I added:
bind *:3389 ssl crt /etc/haproxy/srv1.example.com.pem crt /etc/haproxy/srv2.example.com.pem
and:
server srv1 10.10.0.1:3389 check ssl verify none
server srv2 10.10.0.2:3389 check ssl verify none

but still nothink

@Patryk do you find a solution for this topic?

Have you tried using ssl_fc_sni instead? Quoting the documentation:

This fetch is different from “req.ssl_sni” above in that it applies to the
connection being deciphered by HAProxy and not to SSL contents being blindly
forwarded

@rafamiga i have tried nearly the same as @Patryk . Withoout cert in bind both versions ssl_fc_sni and req_ssl_sni will be ignored. If i add an global cert to bind then i get an SSL handshake error: “SSL handshake failure (error:0A00010B:SSL routines::wrong version number)”

The 10B error sometimes means that instead of doing TLS the port does plaintext. At least what I think so based on your description – you didn’t write which “side” the error is produced by – the port haproxy binds to or communication with backend server.

Try openssl s_client -connect <ip>:<port> first. iI you get 10B error on connection try connecting without TLS, with curl http://<ip>:<port> or redesktop if it’s a RDP port.

@rafamiga that is my config:

global
  log /dev/log  local0
  log /dev/log  local1 notice
  stats socket /var/lib/haproxy/stats level admin
  chroot /var/lib/haproxy
  user haproxy
  group haproxy
  daemon

defaults
  log global
  mode  http
  option  httplog
  option  dontlognull
        timeout connect 5000
        timeout client 50000
        timeout server 50000
  errorfile 400 /etc/haproxy/errors/400.http
  errorfile 403 /etc/haproxy/errors/403.http
  errorfile 408 /etc/haproxy/errors/408.http
  errorfile 500 /etc/haproxy/errors/500.http
  errorfile 502 /etc/haproxy/errors/502.http
  errorfile 503 /etc/haproxy/errors/503.http
  errorfile 504 /etc/haproxy/errors/504.http

frontend inbound_rdp
  mode tcp
  bind 192.168.0.100:3389 name rdp ssl crt /etc/haproxy/terminalserver.pem ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3
  # tcp-request content accept if { req_ssl_hello_type 1 }
  timeout client 1h
  log global
  option tcplog
  option tcpka
  tcp-request inspect-delay 2s
  tcp-request content accept if RDP_COOKIE
  tcp-request content reject if { req_ssl_hello_type 1 }

  acl pool_cad_sni req_ssl_sni -i terminalservercad.my.domain
  use_backend terminalservercad_rdp if pool_cad_sni
  default_backend terminalserver_rdp

backend terminalserver_rdp
  mode tcp
  #balance leastconn
  persist rdp-cookie
  balance rdp-cookie
  timeout server 1h
  timeout connect 4s
  log global
  option tcp-check
  tcp-check connect port 3389
  default-server inter 3s rise 2 fall 3
      server ts01 ts01.my.domain:3389 weight 10 check
      server ts02 ts02.my.domain:3389 weight 10 check

backend terminalservercad_rdp
  mode tcp
  #balance leastconn
  persist rdp-cookie
  balance rdp-cookie
  timeout server 1h
  timeout connect 4s
  log global
  option tcp-check
  tcp-check connect port 3389
  default-server inter 3s rise 2 fall 3
	  server ts05 ts05.my.domain:3389 weight 10 check
	  server ts06 ts06.my.domain:3389 weight 10 check

If i remove “ssl crt /etc/haproxy/terminalserver.pem ssl-min-ver TLSv1.2 ssl-max-ver TLSv1.3” from the fronend bind → it works but my Windows clients get an certificate issue because the bind address (DNS name) ist part of the target rdp certificate. But with the above config it shows me the ssl handshake error. So i think that the frontend configuration makes the issue.

I don’t have any experience working with RDP connections in haproxy but out of curiosity, what does

openssl s_client -connect 192.168.100:3389

say when you have ssl-min-ver/ssl-max-ver there and what shows up when this config is not there?