Forum Discussion

Julian_Grunnell's avatar
Julian_Grunnell
Icon for Nimbostratus rankNimbostratus
Jun 12, 2007

Cookie Rewrite & ASPSESSIONID

Hi - got a problem with session persistence and am wondering if an iRule can help? The scenario is:

 

 

10 x (customer) IIS web servers that make use of ASPSESSIONID's.

 

 

A pair of LTM's that use round robin LB and also have Cookie Rewrite enabled for persistence. So the LTM intercepts the blank BIGipCookie cookie from the IIS web server. BUT the IIS server also sometimes sends the ASPSESSIONID cookie depending on whether a user has got to a particular page. So they are not always sent.

 

 

The problem we are seeing is if the LTM just receives the blank BIGipCookie all is fine, but if it receives the ASPSESSIONID cookie as well the client gets re-load balanced.

 

 

Hope someone can help.

 

 

Thanks - Julian.

6 Replies

  • Hello,

     

     

    If the IIS servers are setting the ASPSESSIONID cookie with no time expiration (ie session-based), I believe they'll only set it once when the client doesn't present a valid ASPSESSIONID in the request. Ideally, this happens only on the initial client request. So I think you're looking at a symptom of a persistence failure that has already occurred when you see the IIS server setting a new ASPSESSIONID cookie for an existing client.

     

     

    The ASPSESSIONID cookie name (ASPSESSIONID plus eight characters: ASPSESSIONIDABCDEFGH) should be the same per IIS server, so long as the server is not restarted. So if you see a client sending an ASPSESSIONID cookie name that doesn't match what that particular IIS server is currently using, you know a persistence failure has occurred or the IIS server was restarted and all its past cookies are invalid.

     

     

    To figure out why persistence is failing, you can check to see if the BIG-IP is marking the node(s) down. Else, try tracing on the client (using LiveHttpHeaders for FF or HttpWatch for IE) and BIG-IP to see what ASPSESSIONID cookies are being set.

     

     

    Or better yet, why not just have the BIG-IP insert the persistence cookie, rather than trying the more complicated option of cookie rewrite persistence?

     

     

    Aaron
  • Hi - yes I believe these are session based to ensure that once a user logs into this website not only can we direct them back to the same server but the ASPSESSIONID refers to a specific user on that server if that makes sense. As we don't admin the web servers at all, just the LTM's I don't have a great deal of knowledge on this area. We have been told that an ASPSESSIONID from server "A" is useless on server "B".

     

     

    We tried cookie insert which meant no web server changes and got the exact same results, from my understanding cookie rewrite just intercepts a blank cookie from the web server and rewrites / adds the relevant persistence info, thus removing some of the work from the LTM.

     

     

    So I can see why the ASPSESSIONID is needed, but also see why the BIGipCookie is needed, just that the LTM doesn't appear to like both at the same time.

     

     

    I've used livehttpheaders and can see this happening.

     

     

    Thanks - J.
  • The ASPSESSIONID cookie name is specific to the IIS server and is based on the process ID of the IIS instance. The name should be remain unchanged so long as the PID for IIS stays the same. The value of the cookie is specific to the user session.

    I think the first issue to address is why persistence is failing. Until you know that, I don't think there is much you can do with an iRule to fix the problem.

    You can use a rule to track the request and response info. Here is a draft rule I've been working on to validate persistence for a customer. Hopefully this will shed some light on when the failure occurs for you.

    
    when HTTP_REQUEST {
       set persist_cookie_name "persist_cookie"
       set request_info "client: [IP::client_addr] -> [HTTP::uri]; Request cookies:"
       
        inspect cookies if any are sent in the request
       if {[HTTP::header exists "Cookie"]}{
           loop through the names of all the cookies in the request
          foreach aCookie [HTTP::cookie names] {
              it's the ASPSESSIONID cookie, save the full name of the cookie (ASPSESSIONIDABCDEFGH)
             if { [string tolower $aCookie] starts_with "aspsessionid"}{
                set aspsessionid_name_request $aCookie
                set request_info "$request_info $aCookie=[HTTP::cookie value $aCookie];"
             } elseif {[string tolower $aCookie] eq $persist_cookie_name}{
                 save the cookie value if it's the persistence cookie
                set persist_cookie_value_request [HTTP::cookie value $aCookie]
                set request_info "$request_info $aCookie=[HTTP::cookie value $aCookie];"
             }
          }
       }
    }
    when LB_SELECTED {
        save the pool name, IP and port for the selected node
       set request_info "$request_info selected node info: [LB::server]"
    }
    when HTTP_RESPONSE {
       set request_info "$request_info; Response cookies: "
        loop through the names of all the cookies in the response
       foreach aCookie [HTTP::cookie names] {
              it's the ASPSESSIONID cookie, save the full name of the cookie (ASPSESSIONIDABCDEFGH)
             if { [string tolower $aCookie] starts_with "aspsessionid"}{
                set aspsessionid_name_response $aCookie
                set request_info "$request_info $aCookie=[HTTP::cookie value $aCookie];"
             } elseif {[string tolower $aCookie] eq $persist_cookie_name}{
                 save the cookie value if it's the persistence cookie
                set persist_cookie_value_response [HTTP::cookie value $aCookie]
                set request_info "$request_info $aCookie=[HTTP::cookie value $aCookie];"
             }
       }
        If the request contained an ASPSESSIONID or persist cookie, then the response should not.  
        This is because the BIG-IP and IIS servers servers only set the cookies if the client doesn't present a cookie
          or the cookie the client does present is invalid
       if { ([info exists persist_cookie_value_request] and [info exists persist_cookie_value_response])
          or ([info exists aspsessionid_name_request] and [info exists aspsessionid_name_response])}{
          set request_info "$request_info; PERSIST FAILURE!"
       }
       log local0. "\$request_info: $request_info"
    }

    The output looks like this:

    : $request_info: client: 192.168.99.33 -> /test.html; Request cookies: ASPSESSIONID192.168.101.46=value2; selected node info: test_http_pool 192.168.101.45 80; Response cookies: ASPSESSIONID192.168.101.45=value1; persist_cookie=761637056.20480.0000;; PERSIST FAILURE!

    Note that I was faking the IIS servers with two "nodes" that respond with cookies named ASPSESSIONID[node IP address].

    Aaron

  • Why not just use cookie insert persistence? It eliminates any dependence on the nodes setting cookies and is much less complex to configure and maintain.

     

     

    Aaron

     

  • Posted By hoolio on 06/12/2007 8:01 AM

     

     

    Why not just use cookie insert persistence? It eliminates any dependence on the nodes setting cookies and is much less complex to configure and maintain.

     

     

    Aaron

     

     

     

     

    Cookie insert or rewrite, we don't mind. The problem appears to be the presence of the ASPSESSIONID which is unique to each web server and holds user information.

     

     

    So as willms has put if you can use the ASPSESSIONID when present somehow to store the web server details and use this in a cookie to ensure the client always gets served by the same web server.

     

     

    This would do away with the conventional cookie setup and let the iRule handle it.

     

     

    Thanks - J.

     

  • If you are using cookie insert persistence, the client request should be load balanced to the same node irrespective of what cookie the node might set. There might be application level errors but these shouldn't affect the LTM's reading of the persistence cookie or selecting the node specified in the cookie.

     

     

    When a failure occurs, does the ASPSESSIONID cookie name that the node sets in the response change from what the client presented in that request? Or does the name stay the same as what the client presented in the request, but the value change?

     

     

    If the name changes, I'm thinking the issue is that persistence is failing for some reason and as a result, the LTM sends the request to a new IIS server. As the ASPSESSIONID cookie the client presents in the request isn't valid for the new IIS server, the IIS server sets a new ASPSESSIONID cookie with its specific ASPSESSIONID cookie name.

     

     

    When you see a failure, is the selected node different than the one selected in past requests?

     

     

    If anyone else has ideas, feel free to jump in.

     

     

    Aaron