Forum Discussion

JRahm's avatar
JRahm
Icon for Admin rankAdmin
Mar 22, 2005

SSL, Cookie persistence, and Redirection

I have two sites that use BigIP, with 3DNS doing the global load balancing. We have no global persistence due to the ldns design of our clients, so request are round-robin currently. The application that we are delivering does a refresh every 60 seconds, and is pulling data subsequently from each site every other minute. Our db replication isn't that fast, so the data is inaccurate from the user perspective. All clients connect via SSL. I have one pool of servers at each location, and am doing cookie persistence to maintain users locally. I am trying to write a rule that will evaluate the cookie that the client is sending, determine if the cookie is on a local server or not. If it is local, persist to that server, if it is not, check the array for the server vip of the other location and redirect to that vip. If there is no cookie, load balance to the local pool. Below is my work flow and the chunks of code I have thus far. Can anyone offer assistance in helping me through this rule? Thanks.

 

 

 
   Work Flow   
  Terminate SSL  
  Inspect HTTP Header for cookie mycookie and decrypt it.  
  Exist?  
   NO --> use pool gdss2  
   YES -> Is server returned in cookie in the local BigIP node list?  
      YES --> persist to local  
      NO --> Look in array for vip for the server returned in cookie,  
             reencrypt cookie, send to client and redirect to that vip.  
    
    
  when RULE_INIT {   
  array set ::CLIENT_SERVERS {   
  SITE B CLIENT SERVERS  
  SERVER IP   SERVER VIP  
  10.10.70.128 10.10.69.50   
  10.10.70.129 10.10.69.50  
  10.10.70.130 10.10.69.50  
  10.10.70.131 10.10.69.50  
  10.10.70.132 10.10.69.50  
  10.10.70.133 10.10.69.50  
  10.10.70.134 10.10.69.50  
  10.10.70.135 10.10.69.50  
  SITE A CLIENT SERVERS  
  SERVER IP   SERVER VIP  
  10.10.22.130 10.10.21.50  
  10.10.22.131 10.10.21.50  
  10.10.22.132 10.10.21.50  
          10.10.22.133 10.10.21.50  
          10.10.22.134 10.10.21.50  
          10.10.22.135 10.10.21.50   
  }   
  }   
  when HTTP_REQUEST {   
    
  if { [HTTP::cookie exists "mycookie"] {  
    HTTP::cookie decrpt "mycookie" "iggus99!"  
   Pull out servername, set to $node (first string in array record)   
        if { not [info exists $::CLIENT_SERVERS($node)] {  
  log "Altered Cookie: $node"  
          reject  
          return  
        }  
         if server in cookie is remotely defined  {  
    $node_val second string in array record   
           redirect to "https://$::CLIENT_SERVERS($node_val)/[HTTP::uri]/"  
        }  
         if server in cookie is locally defined, persist to that server   
        { ?? }  
    }  
  else  
        {  
    use pool mypool  
        }  
    
  when HTTP_RESPONSE {  
    
  if { [HTTP::cookie exists "mycookie"] {  
    HTTP::cookie encrpt "mycookie" "iggus99!"  
    }  
  }  
 

3 Replies

  • In this line of code:

     

     

    HTTP::cookie insert name my_cookie value [concat [virtual name] [LB::server]]

     

     

    Does the virtual name get concatenated to the LB::server information, or vice versa?

     

     

    Also, what is the method to check if a resource is local? For instance, if I receive from the cookie (server) 10.1.1.50 (port) 80, what command verifies that this resource exists?

     

     

    Thanks. I like that methodology much better than populating an array.
  • unRuleY_95363's avatar
    unRuleY_95363
    Historic F5 Account
    It concatenates the 2nd argument to the 1st argument. So, in this case, the result is the virtual server name with the pool name, pool member addr and port following.

    As for verifying that the pool member is valid, there is not a specific command for doing that. However, when you set the pool/member, it is validated at that time. So, you would likely want to do something like the following using the Tcl catch command to catch the error if the member is not valid:

     
     if { [catch { use pool $poolname member $poolmbr }] } { 
        log "Invalid pool member $poolmbr - does not exist in pool $poolname" 
        reject 
        return 
     } 
     

  • Putting it all together, I have:

    when HTTP_REQUEST { 
       if { [HTTP::cookie exists "g2_cooks"] { 
         HTTP::cookie decrpt "g2_cooks" "iggus99!" 
         set vipid [lindex [HTTP::cookie g2_cooks] 0] 
         set poolid [lindex [HTTP::cookie g2_cooks] 1] 
         set serverid [lindex [HTTP::cookie g2_cooks] 2] 
         set portid [lindex [HTTP::cookie g2_cooks] 3] 
         if { [catch { use pool $poolid member $serverid $portid }] } { 
           log "$serverid:$portid not local, redirecting to https://$vipid/[HTTP::uri]/" 
           redirect to "https://$vipid/[HTTP::uri]/" 
           reject 
           return 
         } 
         else { 
           use pool $poolid member $serverid $portid 
         } 
       } 
     } 
      
     when HTTP_RESPONSE { 
       HTTP::cookie insert name g2_cooks value [concat [virtual name] [LB::server]] 
       HTTP::cookie encrpt "g2_cooks" "iggus99!" 
       }

    A couple of questions:

    1) Can I use lindex to pull arguments directly from the cookie, or do I need to set a variable first?

    2) In the event I'm redirecting instead of rejecting, do I need the return statement?