Forum Discussion
Send DNS request to specific pool member
I created an iRule to attempt to send a couple of FDQNs to specific pool members and in testing with an openssl connect command it's failing. So I just wanted to confirm that there isn't and issue with the iRule or how the virtual server/pools are setup.
! Note: the virtual server is doing SSL passthrough - is there a potential that since the data is not being decrypted by the LTM that it's not seeing the FDQN?
! Also, the pools aren't directly tied to the virtual server, could this cause an issue?
- PG0581
Cirrus
Adding in the config as my question was being marked as spam
Virtual server config:
ltm virtual Test123-8892 { destination 1.1.1.1:8892 ip-protocol tcp mask 255.255.255.255 profiles { fastL4 { } } rules { FQDN-pool-select } source 0.0.0.0/0 translate-address enabled translate-port enabled vs-index 170 } `
Pool config: ` ltm pool Test_Pool-8892-pool { members { 2.2.2.2:8892 { address 2.2.2.2 session monitor-enabled state up } } monitor tcp ` } `ltm pool Test_Pool_2-8892-pool { members { 3.3.3.3:8892 { address 3.3.3.3 session monitor-enabled state down } 4.4.4.4:8892 { address 4.4.4.4 session monitor-enabled state up } } monitor tcp ` } iRule config:
` ltm rule FQDN-pool-select { when HTTP_REQUEST { if { [HTTP::host] eq "test.abc.com" } { pool Test_Pool-8892-pool } elseif { [HTTP::host] eq "test2.def.com" } { pool Test_Pool_2-8892-pool }
} }
- Simon_Blakely
Employee
That won't work, because without SSL offload on the virtual to decrypt the request and an HTTP profile, you will not trigger the HTTP_REQUEST event.
 
Take a look at
 
iRule Choose pool base on SNI and disable ssl base on SNI 
This irule snoops the (unencrypted) SNI request header from the SSL ClientHello packet, and then chooses the pool member based on that. 
It will work with SSL passthrough 
- PG0581
Cirrus
Thanks for your reply! Creating iRules are a new thing for me and this one looks fairly complicated, but would I be right in thinking that I only need to edit the below part of the rule that is in the link you provided, to match the specific FQDNs and pools I'm using?
if { [info exists tls_servername] } { log local0. "tls_servername = ${tls_servername}" switch [string tolower $tls_servername] { "test.abc.com" {pool Test_Pool-8892-pool} "test2.def.com" {pool Test_Pool_2-8892-pool} default {pool $default_pool}
If so, the fully configured iRule would look like this?
Code when CLIENT_ACCEPTED { TCP::collect set default_pool [LB::server pool]
} when CLIENT_DATA { set payload [TCP::payload] set payloadlen [TCP::payload length]
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] { "test.abc.com" {pool Test_Pool-8892-pool} "test2.def.com" {pool Test_Pool_2-8892-pool} 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
}
Lastly, is there anything else that needs to be added to the virutal server? Or is what I have enough?
Thanks again!
- Simon_Blakely
Employee
That is correct.
At some point after testing, comment out the debug log lines
withlog local0. ...
log local0.
so you don't clutter up your log files.
- PG0581
Cirrus
Great! I will try this out this week and get back to you. And just to confirm, the virtual server config is fine as it is? Doesn't need an HTTP profile added or anything?
- Simon_Blakely
Employee
No - that SNI inspection irule works on TCP data only.
- PG0581
Cirrus
Ah okay, thanks.
One other question for you when you have a moment. I noticed a default pool is referenced in the rule, how does this line of code work?
set default_pool [LB::server pool]
As I believe this line would reference the above?
pool $default_pool
- PG0581
Cirrus
So the requirements have now changed since we don't know for sure if the clients will include an SNI field, so we're going to terminate the SSL on the LTM. That being said, will the initial configuration I posted work to base the pool selection on the HTTP host header?
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