Forum Discussion

Brodie83_245572's avatar
Brodie83_245572
Icon for Nimbostratus rankNimbostratus
Jan 21, 2016

Method for redirecting RDP traffic from a specific URL to a specific pool member

Is there any way of redirecting RDP traffic from various subdomains on a single external IP to different pool members.

 

My Problem seems to be that the traffic is not HTTP but TCP

 

E.G

 

aaa.demo.com in RDP Client (3389) -> F5 aaa subdomain is detected -> forwarded to pool member a

 

bbb.demo.com in RDP Client (3389) -> F5 bbb subdomain is detected -> forwarded to pool member b

 

I realise that i could use HTTP_REQUEST / HTTP::HOST were these normal web traffic - unsure if RDP traffic contains the same host information.

 

1 Reply

  • Hi Brodie,

     

    I've analysed a TLS secured RDP connection, to see if it would include SNI records (aka. Server Name Indication = FQDN send in clear text). And it does! So I decided to write a very minimalistic SNI based RDP connection proxy for you... 🙂

     

    The code below, will emulate the initial RDP connection handshake to the client, till the client sends the SNI record (aka. TLS Start Message). It would then use a data-group to compare the SNI information with valid FQDNs. If a valid FQDN is found, it would used the data-group value to create the backend RDP connection. It would then emulate the initial RDP connection handshake to the backend server and finally forward the original TLS Start Message to the selected backend server. If a valid FQDN wasn't found in the TLS Start Message it would reject the connection...

     

    Seems to work like a charm^^

     

    Note: You may still want to take a look to the Microsoft Terminal Server Gateway... 😉

     

    Datagroup

     

    ltm data-group internal DG_RDP_SERVER {
        records {
            server1.itacs.de {
                data "192.168.1.1 3389"
            }
            server2.itacs.de {
                data "192.168.1.2 3389"
            }
        }
        type string
    }
    

    iRule

     

    when CLIENT_ACCEPTED {
        set rdp_packet 0
        TCP::collect
    }
    when CLIENT_DATA {
        if { [incr rdp_packet] == 1 } then {
            TCP::payload replace 0 [TCP::payload length] ""
            TCP::respond [b64decode AwAAEw7QAAASNAACDwgACAAAAA==]
            TCP::collect
        } elseif { $rdp_packet == 2 } then {
            if { [set node [class match -value [string tolower [TCP::payload]] contains DG_RDP_SERVER]] ne "" } then {
                node $node
                set tls_start [TCP::payload]
                TCP::payload replace 0 [TCP::payload length] [b64decode AwAAEw7gAAAAAAABAAgACwAAAA==]
                TCP::release
            } else {
                TCP::release
                reject
            }
        }
    }
    when SERVER_CONNECTED {
        TCP::collect
    }
    when SERVER_DATA {
        if { [info exist tls_start] } then { 
            TCP::payload replace 0 [TCP::payload length] ""
            TCP::respond $tls_start
            unset -nocomplain tls_start
        } else {
            TCP::release 
        }
    }
    

    Cheers, Kai