Forum Discussion

Leslie_South_55's avatar
Leslie_South_55
Icon for Nimbostratus rankNimbostratus
Nov 06, 2006

Persist with multiple cookies

I have posted this question in an older thread, but I thought I would start a new one to see if I can get any bites.

I have the need to persist to weblogic servers using 1 of any 5 cookies, including a JESSIONID. After doing some tcpdumps, it appears that the client web browser can present any of 5 cookies sent by the web server, 3 of which are session based and 2 that have expiration dates.

I am currently only persisting using an iRule for JSESSIONID; this works until the client presents one of the other cookies.

when HTTP_RESPONSE {
       set key [HTTP::cookie "JSESSIONID"]
       set value [IP::server_addr]:[TCP::server_port]
       if {$key != ""} {
          log local0. "Adding jsess of: $key, value of: $value"
          session add uie $key $value
          set value2 [session lookup uie $key]
          log local0. "Re-looking up key: $key, provides value: $value2"
       }
     }
     when HTTP_REQUEST {
       set jsess [findstr [HTTP::uri] "jsessionid" 11 ;]
       log local0. "Entering REQUEST, jsess is: $jsess"
       if { $jsess != "" } {
          set server [session lookup uie $jsess]
          log local0. "Server IP is: $server"
          if { $server != "" } {
             pool pool_weblogic_pool_http member $server
          }
       }
     }

using the above rule which was posted in an older thread.

How can I, using an iRule, allow persistence on what ever cookie is presented?

8 Replies

  • Based off of one of the iRule 2005 contest 1st place winner, I am now trying to insert yet another cookie from the LTM and base my persistence off of the new cookie that where I also have created a Cookie Hash Persistence Profile

    profile persist pr_cookie_hash_irule {
       defaults from cookie
       mode cookie
       mirror enable
       cookie mode hash
       cookie name ltmcookie
       cookie hash offset 6
       cookie hash length 3
       across services enable
       across virtuals enable

    when HTTP_REQUEST {
     if { [HTTP::cookie exists "ltmcookie"] }{
            HTTP::cookie decrypt "ltmcookie" "ltmcookiepassword" 
     set vipid [lindex [HTTP::cookie ltmcookie] 0]
     set poolid [lindex [HTTP::cookie ltmcookie] 1]
     set serverid [lindex [HTTP::cookie ltmcookie] 2]
     set portid [lindex [HTTP::cookie ltmcookie] 3]
     persist cookie
                              }
     else {
              use pool pool_myhttp-pool
              }  
      }
    when HTTP_RESPONSE {
    HTTP::cookie insert name ltmcookie value [concat [virtual name][LB::server]] 
    HTTP::cookie encrypt "ltmcookie" "ltmcookiepassword" 
    }

    So far I am only seeing persistence based on my fallback of src_addr

    This is killing me, anyone want to jump in and help?
  • In this case, you don't need the cookie persistence since you have the server information in the inserted cookie. By extracting this information in the request, you can send the connection directly to the server defined in the cookie. You don't need the virtual server name for your application, so I cleaned that up as well.

    
    when HTTP_REQUEST {
      if { [HTTP::cookie exists "ltmcookie"] }{
        HTTP::cookie decrypt "ltmcookie" "ltmcookiepassword"
        set poolid [lindex [HTTP::cookie ltmcookie] 0] 
        set serverid [lindex [HTTP::cookie ltmcookie] 1]
        set portid [lindex [HTTP::cookie ltmcookie] 2]
        pool $poolid member $serverid $portid
        log local0. "Sending request to pool $poolid, member $serverid, port $portid"
      } else {
          pool pool_myhttp-pool
      }  
    }
    when HTTP_RESPONSE {
    HTTP::cookie insert name ltmcookie value [LB::server] 
    HTTP::cookie encrypt "ltmcookie" "ltmcookiepassword" 
    }

    Standard warning...untested (in this form, anyway!)

    Updated to include a logging statement.
  • Thank you for your help; I have a few more questions:

    1)using this rule, should I set a default pool on the VS or let the rule take care of it

    2)should I use a fallback persistence of src_addr or none

    3)I have another rule for this VS to redirect to a HTTPS VS

    rule rule_http_https_redirect {
       when HTTP_REQUEST {
    if { [HTTP::uri] contains "/SEUILibrary/controller/checkout.workflow:" } {
    HTTP::redirect https://[HTTP::host][HTTP::uri]
    }
    else {
    pool pool_pool_myhttp-pool
     }
    }
    }

    and I have the same rule applied to that VS as well (this VS uses the same pool of webservers, but the VS listens on 443 versus 80)at this point in the UI the page hangs and I cannot redirect.

    The log statement helped a ton, I can now actively see who is getting the connection.

    Thanks again!
  • 1)It doesn't hurt to have the default pool defined in both places. Best practices from what I've gathered is to define the default pool as a catch-all if you will be doing pool manipulation in an iRule.

     

     

    2)Depends on your requirements.

     

     

    3)If you are terminating SSL on your 443 virtual, this second rule will put you in a loop if applied to that virtual, as it will redirect to itself continuously. I'd recommend the second rule only be applied to the nonSSL virtual.

     

     

  • Here come more questions: Since our install of weblogic uses both dynamic and static content, pulled from different directories, I need to use this rule to check for the static content directory (contains /static/) if so, then loadbalance using the pool; if not then create, insert, and persist with a cookie created by the LTM. So I will no be using the persistenc profile, I will be doing it all in the iRule.

     

     

    I am going to make a stab at creating this rule, but if you have done this before and can get me going in the right direction, that would be great.

     

     

    Thanks
  • Here is what I have so far

     when HTTP_REQUEST {
    if { [HTTP::uri] contains "/ISS_Static/" } {
         pool pool_my-http-pool}
         log local0. "Sending static request to pool $poolid, member $serverid, port $portid"
     }
    when HTTP_RESPONSE {
    HTTP::cookie insert name ltmcookie value [LB::server]
     HTTP::cookie encrypt "ltmcookie" "ltmcookiepassword"
    elseif {
    when HTTP_REQUEST {
     if { [HTTP::cookie exists "ltmcookie"] }{
        HTTP::cookie decrypt "ltmcookie" "ltmcookiepassword"
         set poolid [lindex [HTTP::cookie ltmcookie] 0]
         set serverid [lindex [HTTP::cookie ltmcookie] 1]
         set portid [lindex [HTTP::cookie ltmcookie] 2]
         pool $poolid member $serverid $portid
         persist cookie
         log local0. "Sending cookie request to pool $poolid, member $serverid, port $portid"
      } 
     }
    }
    else {
          pool pool_my-http-pool
      }
    }

    I get the following error

    line 8: [wrong args] [HTTP::cookie encrypt "ltmcookie" "ltmcookiepassword"
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    Remember that the HTTP::cookie encrypt command takes an extra argument:

    
    HTTP::cookie encrypt    ["128" | "192" | "256"]

    You're not supplying a value, hence the error. Keep in mind that you can also use the AES::encrypt and AES::decrypt commands for this type of encryption, which might make more sense depending on your scenario.

    Joe wrote a great example rule showing this functionality here: Click here

    HTH,

    Colin
  • I think I am missing the actual syntax here, the "data" value can anything? and I assume the values at the end are optional?

    HTTP::cookie decrypt "ltmcookie" "ltmcookiepassword"

    Thanks