Forum Discussion
Universal or Hash Persistence for Windows Terminal Services Gateway Traffic
I need help creating persistence profile for Windows Terminal Services (TS) Gateway traffic. I really have no preference regarding the type of persistence but it looks like hash or universal with an iRule is the only way. You probably know this but I will say it anyway... the TS Gateway product is part of Windows and it encapsulates the terminal server RDP (tcp/3389) traffic in HTTPS. This eliminates the need for the 3389 port. Here is my situation...
If I use Source Address persistence, everything is fine but it causes uneven load distribution between the terminal servers as I have large groups of users coming from the same source IP address, e.g. remote offices. I also know that Windows Session Directory is probably the way to persist termianl services sessions but for many reasons I cannot use that service. My configuration is a single SSL Virtual Server (VS) used for the TS Web and TS Gateway services. The VS performs SSL offload. The pool assigned to teh VS is port 80 (HTTP). The connection sequence is:
1. A user connects to the TS Web service and the following is seen by the BIG-IP when I log the source IP and port:
Persisting on: 1.2.3.4:59401
Persisting on: 1.2.3.4:59402
Persisting on: 1.2.3.4:59403
Persisting on: 1.2.3.4:59404
Persisting on: 1.2.3.4:59405
Persisting on: 1.2.3.4:59406
Persisting on: 1.2.3.4:59407
2. When a user clicks on a connect button within the TS Web site, the following is logged:
Persisting on: 1.2.3.4:59410
Persisting on: 1.2.3.4:59411
As you can imagine the above log is from an attempt to persist on client IP and Port, which was not ideal and doesn't cover all requirements but it would have patched the situation for a while. I used the following iRule along with Universal persistence profile for the test:
when CLIENT_ACCEPTED {
if { [TCP::client_port] and [IP::client_addr] !=0 } {
persist uie "[IP::client_addr]:[TCP::client_port]"
log local0. "Persisting on: [IP::client_addr]:[TCP::client_port]"}
}
I also stumbled on and tried the following rule:
when CLIENT_ACCEPTED {
TCP::collect }
when CLIENT_DATA {
TCP::collect 25 binary scan [TCP::payload] x11a* msrdp
log local0. "Contents after binary scan: $msrdp"
if { [string equal -nocase -length 17 $msrdp "cookie: mstshash="] } {
set msrdp [string range $msrdp 17 end] set len [string first "\n" $msrdp] if { $len == -1 } { TCP::collect return }
if { $msrdp contains "@" } { if { $len > 5 } { incr len -1 log local0. "Data Persisting on: [getfield $msrdp "@" 1]"
persist uie [getfield $msrdp "@" 1] 300 } }
else { persist uie $msrdp 300 }
}
TCP::release
}
The above iRule logs the following on the TCP binary scan and never proceeds to the persistence section:
Contents after binary scan: L?6óÅÓÉ?èl0íÓ;1/7?¶?ë?/?ÚC?Õó / 5 ÀÀ ÀÀ 2 8 4 offsiteqa.mycompany.com ÿ
I think the iRule was designed for RDP traffic.
I also tried the built-in SSL persistence but that fails because of the two sessions and two source ports used for the initial connection.
And lastly, I tried the following iRule from the F5 guide on configuring Windows Terminal Services persistence:
when HTTP_REQUEST {
if { [HTTP::header exists "Authorization"] } {
persist uie [HTTP::header "Authorization"] }
}
Needless to say, it too failed. Any idea on how to persist on Terminal Services Gateway traffic, which is HTTPS but the client is not a browser, would be greatly appreciated.
Thanks, Maxim
- Maxim_Taskov_90
Nimbostratus
Things are starting to look even worse. The following is a log of the SSL session IDs for the first connection: - Chris_Miller
Altostratus
I've heard SSL is a bad persistence strategy because of the constant re-negotiations...when CLIENT_ACCEPTED { TCP::collect } when CLIENT_DATA { TCP::collect 25 binary scan [TCP::payload] x11a* msrdp if { [string equal -nocase -length 12 $msrdp "cookie: msts"] } { set msrdp [string range $msrdp 12 end] set len [string first "\n" $msrdp] if { $len == -1 } { Didnt get whole cookie collect more TCP::collect return } if { $msrdp starts_with "hash=" } { No session directory - username used instead if { $len > 5 } { incr len -1 set record [string tolower [string range $msrdp 5 $len] ] log "adding persistence record - $record" persist uie $record 1801 adjust your timeout (in seconds) } else { log "No username - not persisting" } } } else { log "Cookie not found" } TCP::release }
when CLIENT_ACCEPTED { TCP::collect } when CLIENT_DATA { TCP::collect 25 binary scan [TCP::payload] x11a* msrdp log local0. "Contents after binary scan: $msrdp" if { [string equal -nocase -length 17 $msrdp "cookie: mstshash="] } { set msrdp [string range $msrdp 17 end] set len [string first "\n" $msrdp] if { $len == -1 } { TCP::collect return } if { $msrdp contains "@" } { log local0. "Setting data to: [getfield $msrdp "@" 1]" set username [getfield $msrdp "@" 1] } elseif { $msrdp contains "\\" } { log local0. "Setting data to: [getfield $msrdp "\\" 3]" set username [getfield $msrdp "\\" 3] } else { set username $msrdp log local0. "Setting data to: $msrdp" } set finalusername [string tolower $username] set finalusername [string trim $finalusername] log local0. "User Being Persisted is: |$finalusername|" persist uie $finalusername 10800 } TCP::release }
- Maxim_Taskov_90
Nimbostratus
Thanks for the reply Chris. I agree on the SSL persistence.
Recent Discussions
Related Content
* Getting Started on DevCentral
* Community Guidelines
* Community Terms of Use / EULA
* Community Ranking Explained
* Community Resources
* Contact the DevCentral Team
* Update MFA on account.f5.com