Forum Discussion

Kevin_Stewart's avatar
May 08, 2007

Where do session cookies live?

This is a quick question that I hope is easy to answer.

 

 

When a BigIP (9.x) creates a cookie, clearly its a "session" (in-memory) cookie, and not a file-based cookie. Where then is that cookie stored? In BigIP server memory or client memory? Also, is there a way for multiple connections (to different VIPs) to share that cookie?

 

 

Thank you.

 

Kevin Stewart

4 Replies

  • Session cookies are stored in memory by the client. No data for cookies is stored on the BIG-IP. This is an advantage of cookie insert persistence.

    Can you describe what you're trying to do and what's going wrong?

    Are you trying to test cookie persistence? Are you trying to persist clients to the same node in the same pool regardless of whether they make a request to one VIP or another?

    If you're on 9.4, you can use a rule like the following to log the Set-Cookie header in responses sent back to clients.

    Else, you can use LiveHTTPheaders for Firefox or IEwatch/HTTPwatch for IE to view the cookie headers being sent from the BIG-IP to the client and from the client to BIG-IP.

    
    rule log_cookies_rule {
       when HTTP_REQUEST {
          if {[HTTP::header exists "Cookie"]}{
             foreach aCookie [HTTP::cookie names] {
                log local0. "Cookie: $aCookie=[HTTP::cookie $aCookie]"
             }
          }
       }
       when HTTP_RESPONSE {
          foreach aCookie [HTTP::cookie names] {
             log local0. "Cookie: $aCookie=[HTTP::cookie $aCookie]"
          }
       }
    }

    If you've configured cookie persistence with a named cookie, you should see something like the following logged to /var/log/ltm:

    Rule log_cookies_rule : Set-Cookie: persist_cookie=761637056.20480.0000; path=/

    On subsequent requests, if the client presents the cookie, you should see:

    Rule log_cookies_rule : Cookie: persist_cookie=761637056.20480.0000

    The cookie name in the example is persist_cookie. By default it is BIGipServer. The value is an encoding of the node IP address and port. Click here for details on decoding the value. The path is set to a default of / so a client will send the cookie for any requested URI. There is no domain set on the cookie, so it's host-specific (the client will only send the cookie if it's making a request to that exact host). If a domain was specified, the client would send that cookie in requests to any host on the domain more specific than the domain specified:

    If the client is making requests to app1.example.com and the app specifies no domain on the cookie, the client will only send that cookie in requests to app1.example.com. If app1.example.com set's the domain to .example.com, then the client "should" present that cookie in requests to any host on the example.com domain.

    There are a few requirements in the RFC's (2109, 2965) which describe when clients should include a cookie with their requests.

    http://www.ietf.org/rfc/rfc2109.txt

    http://www.ietf.org/rfc/rfc2965.txt

    It sounds like you're trying to persist clients to the same node across multiple virtual servers. To do so, you'd need to add the same persistence profile to both VIPs. The virtual servers would need to be on the same domain (vip1.example.com and vip2.example.com). The pool on each VIP would need to be the same. And the domain set on the cookie would need to be the same for both virtual servers.

    To set the domain on the cookie you can use a rule. You should be able to use this example if you haven't modified the cookie name in the cookie persistence profile:

    
    when LB_SELECTED {
        get the pool name used for this request
       set my_pool [LB::server pool]
    }
    when HTTP_RESPONSE {
        Check if the persistence cookie exists in the response
       if {[HTTP::cookie exists "BIGipServer$my_pool"]} {
           set the domain attribute on the persistence cookie
          HTTP::cookie domain "BIGipServer$my_pool" ".example.com"
       }
    }

    Else, if you've customized the name, you could use this rule. Make sure to update MY_PERSIST_COOKIE_NAME to the name in the cookie persist profile.

    
    when HTTP_RESPONSE {
        Check if the persistence cookie exists in the response
       if {[HTTP::cookie exists "MY_PERSIST_COOKIE_NAME"]} {
           set the domain attribute on the persistence cookie
          HTTP::cookie domain "MY_PERSIST_COOKIE_NAME" ".example.com"
       }
    }

    I haven't tested the rule, but the format looks correct.

    Aaron
  • Thanks Aaron. I think I'll be able to work with what you've given me. Oddly, our intentions are quite different than what you expected. We have a "portal" product that we secure with client cert authentication and ocsp. Some of the resources within the portal are not "portalized", meaning they aren't rendered from within the portal. The user must request the objects on their own. In an attempt to keep the user from having to re-authenticate their client certificate, as is policy for every web application, we need to turn off client certificate request. In doing so though, we need to make sure that the client is already authenticated at the main site. So the idea is to create a session cookie at the portal with the given domain. When the user receives a redirect for content on another host, the BigIP needs to make sure that a session cookie exists from the portal. If it doesn't, then redirect the user to the main portal login page. It is then important to know whether VIPs can share session cookies, which you've verified. The question of where the session cookie lives is of greatest importance to our IA group. Although session cookies should go away when the browser is closed, the data may actually remain in memory until written over. I know this sounds paranoid, but we may still need to insert some encrypted TTL data into the cookie so that it actually expires.

     

     

    Thanks again.

     

    Kevin Stewart
  • Michael_Everet1's avatar
    Michael_Everet1
    Historic F5 Account
    Hoolio - Thanks for the post, helpful.. I have not needed to use iRules beyond simple redirects from HTTP to HTTPs and pool selection based on URI.. However, during our migration from v4 to v9 BigIP's we noticed a change in behavior on how the v9 BigIP (v9.1.2) handles cookie insert. In version 4, if the client present a BigIP cookie, the bigip would continue to set the same cookie on subsequent 200 responses. In v9, this is no longer the case. Unfornately, we have some apps that function a middle-man between our BigIP and the client, they work with the BigIP persistence cookie. They require the cookie be set on all 200 responses (or so it appears).. V9 broke the app, but I think an iRule can be used to work-around. Below is a snapshot of the rule that I have working in a lab environment. I would appreciate any comments/suggestions..Or, is there a simpler approach.. Note: logging statements are just for debug, will be removed....

     

     

    when HTTP_REQUEST {

     

    set poolname [LB::server pool]

     

    set need_bigip_cookie 0

     

    if { [HTTP::cookie exists "BIGipServer$poolname"] } {

     

    set bigip_cookie [HTTP::cookie BIGipServer$poolname]

     

    set need_bigip_cookie 1

     

    log "cookie exists: $bigip_cookie"

     

    }

     

     

    }

     

     

    when HTTP_RESPONSE {

     

    Only if HTTP 200 response, re-insert the same cookie

     

    if { [HTTP::status] contains "200" and $need_bigip_cookie == 1 } {

     

    HTTP::cookie insert name BIGipServer$poolname value $bigip_cookie

     

    log "reset cookie, value: $bigip_cookie"

     

    }

     

    }
  • Michael_Everet1's avatar
    Michael_Everet1
    Historic F5 Account
    Thanks for the response...

     

     

    The cookie is a session cookie in both v4 and v9.. Problem is that our cookie isn't handled directly by the client browser, but by code in the middle. The worst part, the application team cannot locate the source code that is handling this function. I suspect it easier for me to implement a rule, then get app developers to change code they can't find, for a project they aren't accountable for.

     

     

    I am still using a cookie insert profile, to generate the cookie on the first request. I was thinking the logic that checks to see if the cookie is present in the request, then setting the need_bigip variable would suffice for checking..

     

     

    Is there a better way..