Forum Discussion
Selecting Basque-end based on the SNI
Is it possible to do balancing tcp-sessions on F5 to different back-ends, based on the value of the value field in SNI Client Hellos ssl-session? Having a license only on LTM. Set the encryption is not supported by F5, since they are used GOST cryptography in Russia.
3 Replies
- Kevin_Stewart
Employee
If the F5 doesn't support the cryptography, you can't decrypt at the F5. And more importantly, you can't do SNI-based processing the easy way. Otherwise you could very easily build a CPM policy to load balance to different pools based on the SNI.
But since we're not talking about the easy way, I'll show you a harder way involving some layer 4 iRule parsing:
when CLIENT_ACCEPTED priority 300 { set detect_handshake 1 TCP::collect } when CLIENT_DATA priority 200 { binary scan [TCP::payload] H* orig if { [binary scan [TCP::payload] cSS tls_xacttype tls_version tls_recordlen] < 3 } { reject return } 768 SSLv3.0 769 TLSv1.0 770 TLSv1.1 771 TLSv1.2 switch $tls_version { "769" - "770" - "771" { if { ($tls_xacttype == 22) } { binary scan [TCP::payload] @5c tls_action if { not (($tls_action == 1) && ([TCP::payload length] > $tls_recordlen)) } { set detect_handshake 0 } } } "768" { set detect_handshake 0 } default { set detect_handshake 0 } } if { ($detect_handshake) } { skip past the session id set record_offset 43 binary scan [TCP::payload] @${record_offset}c tls_sessidlen set record_offset [expr {$record_offset + 1 + $tls_sessidlen}] skip past the cipher list binary scan [TCP::payload] @${record_offset}S tls_ciphlen set record_offset [expr {$record_offset + 2 + $tls_ciphlen}] skip past the compression list binary scan [TCP::payload] @${record_offset}c tls_complen set record_offset [expr {$record_offset + 1 + $tls_complen}] check for the existence of ssl extensions if { ([TCP::payload length] > $record_offset) } { skip to the start of the first extension binary scan [TCP::payload] @${record_offset}S tls_extenlen set record_offset [expr {$record_offset + 2}] read all the extensions into a variable binary scan [TCP::payload] @${record_offset}a* tls_extensions for each extension for { set ext_offset 0 } { $ext_offset < $tls_extenlen } { incr ext_offset 4 } { binary scan $tls_extensions @${ext_offset}SS etype elen if { ($etype == 0) } { if it's a servername extension read the servername set grabstart [expr {$ext_offset + 9}] set grabend [expr {$elen - 5}] binary scan $tls_extensions @${grabstart}A${grabend} tls_servername_orig set tls_servername [string tolower ${tls_servername_orig}] set ext_offset [expr {$ext_offset + $elen}] break } else { skip over other extensions set ext_offset [expr {$ext_offset + $elen}] } } } } if { ![info exists tls_servername] } { This isn't TLS so we can't decrypt it anyway SSL::disable clientside SSL::disable serverside } else { log local0. "tls_servername = ${tls_servername}" This is where you'd check a datagroup and disable SSL profiles as necessary } TCP::release }What you're looking at here is the standard iRule for SNI extraction at OSI layer 4 (TCP). At the end you see the clause that contains:
This is where you'd check a datagroup and disable SSL profiles as necessaryThis is where you have access the SNI in the ${tls_servername} variable, and where you could do your pool processing. You must also do this in a Standard VIP configuration to ensure client side TCP completes before starting server side TCP.
- jackmoscow_2940
Nimbostratus
Kevin, thank you for your response to excess.
- jackmoscow_2940
Nimbostratus
Can you show a simple example or link for CPM policy to load balance to different pools based on the SNI?
Help guide the future of your DevCentral Community!
What tools do you use to collaborate? (1min - anonymous)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