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