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?
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