Forum Discussion

umiotoko_95283's avatar
umiotoko_95283
Icon for Nimbostratus rankNimbostratus
Feb 03, 2011

Select node based on URI value

Hi Everyone,

I have a HTTPS / SSL web app, the end user is LB across a server farm with persistence, this works fine. It's a kind of remote support application.

When a phone call for remote support comes in, the app support guys fire off a HTTPS / SSL session. This session must connect to the same server the end user is connected to.

Working in the lab:

 

1. End user request https://server.domain.net/app is LB round robin across 10 servers.

 

2. App support gets request to help user xxx, we know this user is actually talking with server 7.

 

3. App support connects to https://server.domain.net/app?server=7.

Under development:

 

4. F5 iRule needs to read the URI "?sessionServer=7" and direct the entire session to server 7. Needs to be persistent on the destination server until the end user or app support guy drop off.

iRule code:

when HTTP_REQUEST {

log local0. "Http query is [HTTP::uri] "

 

if {[HTTP::uri] contains "/?server=7" } {

 

log local0. "*** Request is for server 7 *** "

 

node 192.168.1.7 80

 

}

if {[HTTP::uri] contains "/?server=8" } {

 

log local0. "*** Request is for server 8 *** "

 

node 192.168.1.8 80

 

}

}

My question - is there a better way to do this ? I'll need 1 entry per server. Will mangling HTTP_REQUEST based on the URI + a persistence profile always send the traffic to the same place ? My thought is doing this under when LB_SELECTED would be a one time per connect request, and therefore lower overhead than by http::request.

FWIW:

 

SSL terminates on the F5.

 

Version is 10.2.0

 

I'm a complete noobie to F5.

  • I assume these servers all in the same pool? If so, it'd be better to specify a pool member than a node. You can't use [HTTP::uri] from LB_SELECTED so HTTP_REQUEST is a good spot for this.

    You'll probably end up with something like this:

     

    when HTTP_REQUEST {
       switch -glob [string tolower [HTTP::uri]] {
                 "*/server=7*" { pool poolname member 192.168.1.7 80 }
                 "*/server=8*" { pool poolname member 192.168.1.8 80 }
                default { pool defaultpool }
                 }
       }
    

     

    Will also possibly need OneConnect for this,

  • Here's an example iRule to do URI based pool member selection with persistence:

     

     

     

    http://devcentral.f5.com/wiki/default.aspx/iRules/Select_pool_member_based_on_HTTP_query_string_parameter.html

     

     

    The iRule allows clients to select a pool member based on a parameter set in the HTTP query string. The manual selection can be specified on any URI by appending member=1 to the query string. On responses, a session cookie is set to ensure the client requests are manually persisted to the same server as long as the browser is kept open. To have LTM clear the cookie, the member number can be set in the URI to 0.

     

     

    For versions lower than 10.0, you could use a shell script run nightly to create a datagroup containing all of the pool members, regardless of state. This could be done on any LTM version. Then replace [active_members -list ..] with [lindex [lsort $::my_pool_members_class] $member_num] for 9.x or [lindex [lsort [class -get my_pool_members_class]] $member_num] for 10.x.

     

     

     

    Aaron