Haproxy as balancer MS RDS Gateway, NTLM Failed

Hi, all! I trying to configure Haproxy as load balancer and failover for ms rds gateways.
I want make scheme: Client => Haproxy => RDGATEWAY01, RDGATEWAY02, RDGATEWAY03
By default MS RDG using port tcp port 443 and udp port 3391.
For 443 i use Haproxy and for 3391 i use nginx.
For test installed VM with OS Debian 12 Bookworm and Haproxy 3.0.3
after reading a lot of examples, i prepare config for haproxy:

global
        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon
        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private
        tune.ssl.default-dh-param 4096

        ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:@SECLEVEL=0
        ssl-default-server-options ssl-min-ver TLSv1.0 no-tls-tickets





defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option  redispatch
        #option h1-case-adjust-bogus-client
        #no option httpclose
        #no option http-use-htx
        retries 3
        timeout connect 10s
        timeout client  30s
        timeout server  35s
        timeout tunnel        3600s
        timeout http-keep-alive  15s
        timeout http-request    30s
        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 rds_gateway_front
 bind *:80
 bind *:443 ssl crt /etc/haproxy/pki/contoso.com.pem
 mode http
 timeout client 12h
 timeout server 12h
 log global

 option forwardfor
 option http-no-delay
 option http-keep-alive
 option http-server-close

 http-request add-header X-Forwarded-For %[src]
 http-request set-header X-Forwarded-Host %[req.hdr(host)]
 #http-request set-header X-Forwarded-Proto https

 http-request set-header X-Forwarded-Proto https if { ssl_fc }
 http-request set-header Host %[req.hdr(Host)]

 http-request set-header Upgrade websocket if { hdr(Upgrade) -i websocket }
 http-request set-header Connection upgrade if { hdr(Upgrade) -i websocket }
 redirect scheme https code 301 if !{ ssl_fc }
 default_backend rds_gateway

backend rds_gateway
 mode http
 balance leastconn
 #balance source
 #hash-type consistent
 log global

 cookie RDGW insert nocache
 http-reuse always
 #acl RDGW_PATH path_beg -i /remoteDesktopGateway/
 #http-request deny if RDGW_PATH
 option http-keep-alive
 option prefer-last-server
 option log-health-checks
 option httpchk GET /
 http-check expect status 200
 http-request add-header X-Forwarded-For %[src]
 http-request set-header X-Forwarded-Host %[req.hdr(host)]
 http-request set-header X-Forwarded-Proto https if { ssl_fc }
 http-request set-header Host %[req.hdr(Host)]
 http-request set-header X-Client-IP %[src]
 http-request set-header X-Client-IP req.hdr_ip([X-Forwarded-For])
 http-request set-header Upgrade websocket if { hdr(Upgrade) -i websocket }
 http-request set-header Connection upgrade if { hdr(Upgrade) -i websocket }
server RDGW1 10.0.10.71:443 ssl verify none alpn h2,http/1.1 check
server RDGW2 10.0.10.72:443 ssl verify none alpn h2,http/1.1 check

listen statistics
bind *:9001
mode http
log global
stats enable
stats refresh 30s
stats show-node
stats show-legends
stats show-desc desc
stats auth demo1:statin
stats uri /stats

With this configuration user unable to pass Authentication (
I test on Haproxy 2.0.18, 2.6.x, 3.0.3. same result on any version
May be my configuration is wrong?

i start haproxy in debug mode:

00000000:rds_gateway_front.accept(0006)=000e from [10.0.10.95:59150] ALPN=<none>
00000000:rds_gateway_front.clireq[000e:ffffffff]: RDG_OUT_DATA /remoteDesktopGateway/ HTTP/1.1
00000000:rds_gateway_front.clihdr[000e:ffffffff]: cache-control: no-cache
00000000:rds_gateway_front.clihdr[000e:ffffffff]: connection: Upgrade
00000000:rds_gateway_front.clihdr[000e:ffffffff]: pragma: no-cache
00000000:rds_gateway_front.clihdr[000e:ffffffff]: upgrade: websocket
00000000:rds_gateway_front.clihdr[000e:ffffffff]: accept: */*
00000000:rds_gateway_front.clihdr[000e:ffffffff]: user-agent: MS-RDGateway/1.0
00000000:rds_gateway_front.clihdr[000e:ffffffff]: rdg-connection-id: {EFB5A616-998D-41BF-AE11-AAB2BBC4C2CF}
00000000:rds_gateway_front.clihdr[000e:ffffffff]: rdg-correlation-id: {CDC4CDF8-FEF2-431C-88E7-D50370A60100}
00000000:rds_gateway_front.clihdr[000e:ffffffff]: rdg-client-appbuild: Type=OOB; Build=WinBuild Jan 01 2016 10.0.17763.4252;
00000000:rds_gateway_front.clihdr[000e:ffffffff]: rdg-client-generation: Win32#10.0=5
00000000:rds_gateway_front.clihdr[000e:ffffffff]: sec-websocket-key: j6na/kCVc259BQrv09ygXg==
00000000:rds_gateway_front.clihdr[000e:ffffffff]: sec-websocket-version: 13
00000000:rds_gateway_front.clihdr[000e:ffffffff]: host: gw-test.contoso.com
00000000:rds_gateway.srvrep[000e:000d]: HTTP/1.1 503 Service Unavailable
00000000:rds_gateway.srvhdr[000e:000d]: content-type: text/html; charset=us-ascii
00000000:rds_gateway.srvhdr[000e:000d]: server: Microsoft-HTTPAPI/2.0
00000000:rds_gateway.srvhdr[000e:000d]: date: Tue, 20 Aug 2024 20:41:17 GMT
00000000:rds_gateway.srvhdr[000e:000d]: content-length: 326
00000000:rds_gateway.srvcls[000e:000d]
00000000:rds_gateway.clicls[000e:000d]
00000000:rds_gateway.closed[000e:000d]
10.0.10.95:59150 [20/Aug/2024:15:41:17.659] rds_gateway_front~ rds_gateway/RDGW1 0/0/1/1/2 503 498 - - --NI 1/1/0/0/0 0/0 "RDG_OUT_DATA /remoteDesktopGateway/ HTTP/1.1"
00000001:rds_gateway_front.accept(0006)=000e from [10.0.10.95:59150] ALPN=<none>
00000001:rds_gateway_front.clireq[000e:ffffffff]: RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1
00000001:rds_gateway_front.clihdr[000e:ffffffff]: cache-control: no-cache
00000001:rds_gateway_front.clihdr[000e:ffffffff]: pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729
00000001:rds_gateway_front.clihdr[000e:ffffffff]: accept: application/rpc
00000001:rds_gateway_front.clihdr[000e:ffffffff]: user-agent: MSRPC
00000001:rds_gateway_front.clihdr[000e:ffffffff]: content-length: 1073741824
00000001:rds_gateway_front.clihdr[000e:ffffffff]: host: gw-test.contoso.com
00000001:rds_gateway.srvrep[000e:000d]: HTTP/1.1 401 Unauthorized
00000001:rds_gateway.srvhdr[000e:000d]: content-type: text/plain
00000001:rds_gateway.srvhdr[000e:000d]: server: Microsoft-IIS/8.5
00000001:rds_gateway.srvhdr[000e:000d]: www-authenticate: Negotiate
00000001:rds_gateway.srvhdr[000e:000d]: www-authenticate: NTLM
00000001:rds_gateway.srvhdr[000e:000d]: www-authenticate: Basic realm="gw-test.contoso.com"
00000001:rds_gateway.srvhdr[000e:000d]: date: Tue, 20 Aug 2024 20:41:17 GMT
00000001:rds_gateway.srvhdr[000e:000d]: content-length: 13
00000002:rds_gateway_front.accept(0006)=000f from [10.0.10.95:59153] ALPN=<none>
00000002:rds_gateway_front.clireq[000f:ffffffff]: RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1
00000002:rds_gateway_front.clihdr[000f:ffffffff]: cache-control: no-cache
00000002:rds_gateway_front.clihdr[000f:ffffffff]: pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=5a384ca7-11dc-4ff2-b597-c2c95d425d75
00000002:rds_gateway_front.clihdr[000f:ffffffff]: accept: application/rpc
00000002:rds_gateway_front.clihdr[000f:ffffffff]: user-agent: MSRPC
00000002:rds_gateway_front.clihdr[000f:ffffffff]: content-length: 0
00000002:rds_gateway_front.clihdr[000f:ffffffff]: host: gw-test.contoso.com
00000002:rds_gateway_front.clihdr[000f:ffffffff]: authorization: Negotiate TlRMTVNTUAABAAAAl4II4gAAAAAAAAAAAAAAAAAAAAAKAGNFAAAADw==
00000002:rds_gateway.srvrep[000f:0010]: HTTP/1.1 401 Unauthorized
00000002:rds_gateway.srvhdr[000f:0010]: content-type: text/plain
00000002:rds_gateway.srvhdr[000f:0010]: server: Microsoft-IIS/8.5
00000002:rds_gateway.srvhdr[000f:0010]: www-authenticate: Negotiate TlRMTVNTUAACAAAABAAEADgAAAAVgoniS91OnJ3H1N8AAAAAAAAAAKwArAA8AAAABgOAJQAAAA9BAEQAAgAEAEEARAABABQAQwBMAC0AUgBEAEcAVwAtADAAMQAEAB4AYQBkAC4ANAAyAGMAbABvAHUAZABzAC4AYwBvAG0AAwA0AGMAbAAtAHIAZABnAHcALQAwADEALgBhAGQALgA0ADIAYwBsAG8AdQBkAHMALgBjAG8AbQAFAB4AYQBkAC4ANAAyAGMAbABvAHUAZABzAC4AYwBvAG0ABwAIAH6cuU5B89oBAAAAAA==
00000002:rds_gateway.srvhdr[000f:0010]: www-authenticate: NTLM
00000002:rds_gateway.srvhdr[000f:0010]: www-authenticate: Basic realm="gw-test.contoso.com"
00000002:rds_gateway.srvhdr[000f:0010]: date: Tue, 20 Aug 2024 20:41:17 GMT
00000002:rds_gateway.srvhdr[000f:0010]: content-length: 13
00000002:rds_gateway.srvcls[000f:0010]
00000002:rds_gateway.clicls[000f:0010]
00000002:rds_gateway.closed[000f:0010]
10.0.10.95:59153 [20/Aug/2024:15:41:17.978] rds_gateway_front~ rds_gateway/RDGW1 0/0/2/4/6 401 564 - - --NI 2/2/1/1/0 0/0 "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1"
00000003:rds_gateway_front.accept(0006)=000f from [10.0.10.95:59153] ALPN=<none>
00000003:rds_gateway_front.clireq[000f:ffffffff]: RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1
00000003:rds_gateway_front.clihdr[000f:ffffffff]: cache-control: no-cache
00000003:rds_gateway_front.clihdr[000f:ffffffff]: pragma: ResourceTypeUuid=44e265dd-7daf-42cd-8560-3cdb6e7a2729, SessionId=5a384ca7-11dc-4ff2-b597-c2c95d425d75
00000003:rds_gateway_front.clihdr[000f:ffffffff]: accept: application/rpc
00000003:rds_gateway_front.clihdr[000f:ffffffff]: user-agent: MSRPC
00000003:rds_gateway_front.clihdr[000f:ffffffff]: content-length: 76
00000003:rds_gateway_front.clihdr[000f:ffffffff]: host: gw-test.contoso.com
00000003:rds_gateway_front.clihdr[000f:ffffffff]: authorization: Negotiate TlRMTVNTUAADAAAAGAAYAIIAAABiAWIBmgAAAAQABABYAAAADAAMAFwAAAAaABoAaAAAABAAEAD8AQAAFYKI4goAY0UAAAAPKarYVNN3iT6Yk1l+61vJkWEAZABzAGUAbgBzAGUAaQBDAEwALQBBAEQATQBJAE4ALQBJAFQARQBSAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAL3y4SLQ1NvnC2SMZZ9bLkwBAQAAAAAAAH6cuU5B89oBvnY9FU5CHdMAAAAAAgAEAEEARAABABQAQwBMAC0AUgBEAEcAVwAtADAAMQAEAB4AYQBkAC4ANAAyAGMAbABvAHUAZABzAC4AYwBvAG0AAwA0AGMAbAAtAHIAZABnAHcALQAwADEALgBhAGQALgA0ADIAYwBsAG8AdQBkAHMALgBjAG8AbQAFAB4AYQBkAC4ANAAyAGMAbABvAHUAZABzAC4AYwBvAG0ABwAIAH6cuU5B89oBBgAEAAIAAAAIADAAMAAAAAAAAAABAAAAACAAAJRK6Ew4ctcqIDqJjsH2JZrkz4GzP3VOLY35ULzm9LsWCgAQANh55Xu60x8wm1JeJlox7csJADIASABUAFQAUAAvAGcAdwAtAHQAZQBzAHQALgA0ADIAYwBsAG8AdQBkAHMALgBjAG8AbQAAAAAAAAAAAGvTMTfKKNScrdJBoDdDBPE=
00000003:rds_gateway.srvrep[000f:0010]: HTTP/1.0 503 RPC Error: 6ba
00000003:rds_gateway.srvcls[000f:0010]
00000003:rds_gateway.clicls[000f:0010]
00000003:rds_gateway.closed[000f:0010]
10.0.10.95:59153 [20/Aug/2024:15:41:17.986] rds_gateway_front~ rds_gateway/RDGW1 0/0/0/130/130 503 50 - - --NI 2/2/1/1/0 0/0 "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1"
00000001:rds_gateway.srvcls[000e:000d]
00000001:rds_gateway.clicls[000e:000d]
00000001:rds_gateway.closed[000e:000d]
10.0.10.95:59150 [20/Aug/2024:15:41:17.866] rds_gateway_front~ rds_gateway/RDGW1 0/0/1/2/251 401 251 - - CDNI 1/1/0/0/0 0/0 "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1"
^C

Short log:

2024-08-21T05:43:30.586858-05:00 rds-balancer-1 haproxy[34627]: 10.0.10.95:62903 [21/Aug/2024:05:43:30.583] rds_gateway_front~ rds_gateway/RDGW2 0/0/1/2/3 401 559 - - --NI 1/1/0/0/0 0/0 "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1"
2024-08-21T05:43:30.597945-05:00 rds-balancer-1 haproxy[34627]: 10.0.10.95:62907 [21/Aug/2024:05:43:30.594] rds_gateway_front~ rds_gateway/RDGW2 0/0/1/1/2 401 559 - - --NI 2/2/1/1/0 0/0 "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1"
2024-08-21T05:43:30.601506-05:00 rds-balancer-1 haproxy[34627]: 10.0.10.95:62907 [21/Aug/2024:05:43:30.598] rds_gateway_front~ rds_gateway/RDGW2 0/0/1/1/2 401 246 - - --NI 2/2/1/1/0 0/0 "RPC_OUT_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1"
2024-08-21T05:43:30.602115-05:00 rds-balancer-1 haproxy[34627]: 10.0.10.95:62903 [21/Aug/2024:05:43:30.587] rds_gateway_front~ rds_gateway/RDGW2 0/0/1/2/14 401 246 - - CLNI 2/2/0/0/0 0/0 "RPC_IN_DATA /rpc/rpcproxy.dll?localhost:3388 HTTP/1.1"

Please help solve problem…

Authorization issue solved, but failloved freezes RDP Window , config example:

global
        log /dev/log    local0
        log /dev/log    local1 notice

        chroot /var/lib/haproxy
        stats socket /run/haproxy/admin.sock mode 660 level admin
        stats timeout 30s
        user haproxy
        group haproxy
        daemon

        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private
        tune.ssl.default-dh-param 4096
    ssl-default-server-ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:DHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES256-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:TLS_AES_128_GCM_SHA256:TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:@SECLEVEL=0
    ssl-default-server-options ssl-min-ver TLSv1.0 no-tls-tickets


   # ssl-dh-param-file etc/haproxy/dhparam.pem

    log stdout format raw local0



defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        option  redispatch
        #option h1-case-adjust-bogus-client
        option httpclose
        #no option http-use-htx
        retries 3
        timeout connect 10s
        timeout client  30s
        timeout client-fin 30s
        timeout server  35s
        timeout tunnel        3600s
        timeout http-keep-alive  15s
        timeout http-request    30s

        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 rds_gateway_front
 bind *:80
 bind *:443 ssl crt /etc/haproxy/pki/contoso.com.pem no-tls-tickets alpn http/1.1 allow-0rtt
 mode http
 log global
 option forwardfor
 option http-no-delay
 option http-keep-alive
# option http-server-close # Connection to gw Not work with this option
# Internet Explorer and NTLM with HTTPS sites
 option http-use-proxy-header
 #option accept-invalid-http-request
 #no option  http-buffer-request
 #http-reuse always


 #Dump all headers
 http-request capture req.hdrs len 1024
 redirect scheme https code 301 if !{ ssl_fc }
 default_backend rds_gateway


backend rds_gateway
 #HTTPS
 #default-server ssl tfo verify none alpn http/1.1 check stick allow-0rtt
 #HTTP
 default-server alpn http/1.1 check on-marked-down shutdown-sessions
 mode http

 balance leastconn
 log global

 dynamic-cookie-key  RDWGW
 cookie RDGW42C insert indirect nocache
 stick-table    type ip size 5000
 stick on       src

# no option redispatch
# no option persist
# option http-server-close
 option http-keep-alive
 option prefer-last-server
 option httpchk GET /
 http-check expect status 200

 http-request add-header X-Forwarded-For %[src]
 http-request set-header X-Forwarded-Host %[req.hdr(host)]
 http-request set-header X-Forwarded-Proto https if { ssl_fc }

 http-request set-header X-Client-IP %[src]
 http-request set-header X-Client-IP req.hdr_ip([X-Forwarded-For])

server RDGW1 10.20.10.71:80
server RDGW2 10.20.10.72:80
#server RDGW2 10.20.10.72:443 ssl verify none alpn h2,http/1.1 check
#server RDGW1 10.20.10.72:443 ssl verify none check cookie RDGW1 weight 50



listen statistics
bind *:9001
mode http
log global
stats enable
stats refresh 30s
stats show-node
stats show-legends
stats show-desc desc
stats auth demo1:statin
stats uri /stats
stats hide-version