Forum Discussion
iRule Choose pool base on SNI and disable ssl base on SNI
Hi
We have the need to select pool via irule but we don't want to decrypt all HTTPS traffic.
Can we do this? (This is outbound traffic)
-
We have list of URL in iRule Datagroup
-
if user access HTTPS website -> F5 detect SNI and check if that URL is in datagroup or not.
-
if it's in datagroup -> Load balance to pool A.
-
if it's not in datagroup -> disable http profile, ssl profile and other profile (if any) to just forward HTTPS traffic only. don't decrypt/encrypt anything.
-
Is this possible?
Thank you
- kridsanaCirrocumulus
Or we have to only rely on SSL Forward Proxy feature ?
- SurgeonRet. Employee
hmm, interesting. If you do no want offload ssl on server side than you need somehow to re-initiate ssl handshake between a client and back-end server, since ssl handshake is already finished with big-ip when iRule checks for URL
SSL forward proxy bypass looks reasonable. big-ip should bypass ssl, based on host name in the server cert If ssl forward proxy is enabled then ssl handshake on the client side will not finish until big-ip receives certificate from the back-end server.
- Stanislas_Piro2Cumulonimbus
I changed the Kevin Stewart's irule to solve your issue (not tested, developed with tcl shell out of box)
Updated to add unset command and remove useless temp variables
when CLIENT_ACCEPTED { TCP::collect set default_pool [LB::server pool] } when CLIENT_DATA { set payload [TCP::payload] set payloadlen [TCP::payload length] - tls_record_content_type : Reccord layer content-type (1 byte) Handshake value is 22 (required for CLIENT_HELLO packet) - tls_major_version : SSL / TLS version SSLv3 and TLS share major version value 3 (1 byte) - tls_minor_version : SSL / TLS minor version. (1 byte) SSLv3 value is 0 (doesn't support SNI, not valid in first condition) TLS_1.0 value is 1 TLS_1.1 value is 2 TLS_1.2 value is 3 - tls_recordlen : Reccord layer content length (2 bytes) : must match payload length TLS Hanshake protocol - tls_action : Handshake action (1 byte) : CLIENT_HELLO = 1 - handshake length not stored in a variable (3 bytes) - SSL / TLS handshake major version not stored in a variable (1 byte) - SSL / TLS handshake minor version not stored in a variable (1 byte) - hanshake random not stored in a variable (32 bytes) - tls_sessidlen : handshake sessionID length (1 byte) - handshake sessionID (length defined by sessionID length value, max 32-bit) - CipherSuites length (2 bytes) - CipherSuites (length defined by CipherSuites length value) - Compression length (2 bytes) - Compression methods (length defined by Compression length value) - Extensions - Extension length (2 bytes) - list of Extensions records (length defined by extension length value) - extension record type (2 bytes) - extension record length (2 bytes) - extension data (length defined by extension record length value) SNI extension data format: - SNI record length (2 bytes) - SNI record data (length defined by SNI record length value) - SNI record type (1 byte) - SNI record value length (2 bytes) - SNI record value (length defined by SNI record value length value) If valid TLS 1.X CLIENT_HELLO handshake packet if { [binary scan $payload cccScx37c tls_record_content_type tls_major_version tls_minor_version tls_recordlen tls_action tls_sessidlen] == 6 && \ ($tls_record_content_type == 22) && \ ($tls_major_version == 3) && ($tls_minor_version > 0) && \ ($tls_action == 1) && \ ($payloadlen == $tls_recordlen+5)} { skip past the session id set record_offset [expr {44 + $tls_sessidlen}] skip past the cipher list binary scan $payload @${record_offset}S tls_ciphlen set record_offset [expr {$record_offset + 2 + $tls_ciphlen}] skip past the compression list binary scan $payload @${record_offset}c tls_complen set record_offset [expr {$record_offset + 1 + $tls_complen}] check for the existence of ssl extensions if { ($payloadlen > $record_offset) } { skip to the start of the first extension binary scan $payload @${record_offset}S tls_extenlen set record_offset [expr {$record_offset + 2}] Check if extension length + offset equals payload length if {$record_offset + $tls_extenlen == $payloadlen} { for each extension while { $record_offset < $payloadlen } { binary scan $payload @${record_offset}SSx3S etype elen erlen if { ($etype == 0) } { if it's a servername extension read the servername SNI record value start after extension type (2 bytes), extension record length (2 bytes), record type (2 bytes), record type (1 byte), record value length (2 bytes) = 9 bytes binary scan $payload @[expr {$record_offset + 9}]A${erlen} tls_servername set record_offset [expr {$record_offset + $elen + 4}] break } else { skip over other extensions set record_offset [expr {$record_offset + $elen + 4}] } } } } else { log local0. "packet is not a valid TLS 1.X CLIENT_HELLO handshake" reject return } unset -nocomplain payload payloadlen tls_record_content_type tls_major_version tls_minor_version tls_recordlen tls_action tls_sessidlen record_offset tls_ciphlen tls_complen tls_extenlen etype elen erlen if { [info exists tls_servername] } { log local0. "tls_servername = ${tls_servername}" switch [string tolower $tls_servername] { "app1.company.com" {pool pool1} "app2.company.com" {pool pool2} default {pool $default_pool} } } else { log local0. "packet is a valid TLS 1.X CLIENT_HELLO handshake but doesn't contain server name extension" pool $default_pool } TCP::release }
- kridsanaCirrocumulus
Hi Surgeon
From irule stanislas provide below . Is the result is the same as SSL Forward proxy ?
I mean just choose pool base on Hostname. We don't want to do other than this.
Kridsana
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