Quantcast



Docs


Blogs


Forums


Samples


Media


Labs


Resources

 




DevCentral > Weblogs > Colin Walker - Off the map where the wild things grow...
 20 Lines or Less #7
posted on Wednesday, May 21, 2008 2:04 PM

What could you do with your code in 20 Lines or Less? That's the question I ask every week, and every week I go looking to find cool new examples that show just how flexible and powerful iRules can be without getting in over your head.

This week we've got some more great examples from the community. I've had the chance to sit in with some fellow F5 iRulers the past couple of days and wow, is it ever inspiring to hear all the things they're doing/seeing with iRules, and the kind of stuff heading our way in the future. The 20 Lines or Less series is meant to show off the cool things you can do with just a simple iRule and that list just seems to go on forever. What's not to love about that?

It seems more and more people are checking out the 20LoL each week, which is awesome, so keep on coming back to see what other cool things you can do with your iRule foo without breaking a sweat. Here's this weeks' dose:

 

JSessionID Persistence

http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=24165#24170

Like a childhood friend, this topic is one that I can always count on coming back to again and again. We laugh, we cry, we talk about "the way things were" ... it's beautiful, really.  Honestly though, JSessionID persistence is a very common theme that repeats itself in the forums time and time again. The truth of the matter is there are only so many ways to address this problem, and F5's iRules offers one of the coolest, simplest ways of doing just that, so it's bound to be popular. Here's one example of just that courtesy of the forums.

when HTTP_RESPONSE {
  if { [HTTP::header exists "jsessionid"] } {
    set jsess_resp [findstr [HTTP::header "jsessionid"] "!" 1 "!"]
    if { $jsess_resp != "" } {
      persist add uie $jsess_resp
    }
  }
}

Cookie Based Virus Scan Decisions

http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=24045#24173

This cool example shows how a user is making use of a combination of information, including cookies and the HTTP URI, to determine whether or not incoming traffic needs to be passed through an AV gateway. The code itself is relatively straight-forward, but it's another great example of one of the many, many things you might use an iRule for that just doesn't have another clear, simple solution. Nice one.

when HTTP_REQUEST {
  set ID [findstr [HTTP::cookie "CookieX"] "Cookie" 10 ";"]
  set my_uri [string tolower [HTTP::uri]]
  log local0.info "ID is $ID default pool is [LB::server pool] URI is $my_uri"
  if {($ID equals "")} {
    log local0.info "sending user to pool [LB::server pool]"
    pool [LB::server pool]
  } elseif { ($my_uri ends_with "/attachmentshare/upload.aspx") and not ($ID equals "")} {
    log local0.info "URI contains $my_uri sending user to pool AVPool$ID"
    pool AVG$ID
    snatpool SNAT$ID
  } else {
    log local0.info "Cookie found sending user to Pool Pool$ID"
    pool Pool$ID
  }
}

Multi-Pass HTTP Redirect

http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=24124#24129

Power user hoolio is at it again! In his latest escapades he's helped dacrud come up with a solution that actually uses multiple passes through a single iRule to get the traffic sorted the way they want it.  By first redirecting the request to change the hostname, then routing based on URI, this single iRule packs a 1-2 punch that's code-efficient, powerful, and inventive.

when HTTP_REQUEST {
  if {not ([string tolower [HTTP::host]] eq "www.domain.com")}{
    HTTP::redirect http://www.domain.com[HTTP::uri]
  } else {
    switch -glob [HTTP::path] {
      "/us*" {
        pool US_pool
        log local0. "[IP::client_addr]:[TCP::client_port]: using pool US_pool"
      }
      "/au*" {
        pool AU_pool
        log local0. "[IP::client_addr]:[TCP::client_port]: using pool AU_pool"
      }
      default {
        pool default_pool
        log local0. "[IP::client_addr]:[TCP::client_port]: using default pool"
      }
    }
  }
}

That's it for this week. Be sure to check back for more iRules under that magical 21 line mark next week. Until then, toss out some ideas or feedback and let me know what you're thinking.

#Colin



Email This
  del.icio.us
      

Feedback


5/22/2008 7:10 AM
Gravatar I am from Kodak Gallery. We recently started to use F5 8800 & 6800 in our environment. But we aren’t able to make sticky sessions work.
I browsed through the dev central and found couple of solutions (
http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=6084#8691
http://devcentral.f5.com/default.aspx?tabid=53&view=topic&forumid=5&postid=8098 ) but it isn’t working or robust enough. For instance
a) how to delete entries from persistence hash
b) if browser is not closed for a long time and it sends an old stale jsessionid, this iRule should forward the request to the virtual server rather than rejecting the request.

In the following Universal persistence rule should we use set SessionId [findstr [[HTTP::header] Set-Cookie] "JSessionId" 11] ?

when HTTP_RESPONSE {
if { [HTTP::cookie exists "JSESSIONID"] } {
set trimID [lindex [split [HTTP::cookie "JSESSIONID"] "!" ] 0]
if { [persist lookup uie $trimID] equals "" } {
persist add uie $trimID 1800
log "added persistent entry $trimID for server [LB::server addr]"
} else { log "continued sessionID $trimID for server [LB::server addr]" }
}
}
when HTTP_REQUEST {
if { [active_members MyPool] == 0 } {
HTTP::redirect "http://[HTTP::header "X-Forwarded-Host"]/myUri.html"
}
if { [HTTP::header exists "X-Forwarded-Host"] } {
HTTP::header replace "Host" [HTTP::header "X-Forwarded-Host"]
}
if { not [HTTP::cookie exists "MyCookie"] } {
set jsess [findstr [HTTP::uri] "jsessionid" 11 "!"]
if { $jsess != "" } {
persist uie $jsess 1800
log "Used URI, value is $jsess, server [LB::server addr]"
}
} else {
log "used Cookie Insert, value is [HTTP::cookie "MyCookie"]"
}
}
Jsessionid is session cookie which does not have time stamp when it is received by F5 from the server.
In the above iRule, when a http request is received the F5 will route the request to the original physical node where the jsessionid was created?
Now how do I flush the persistence hash in F5?

You may be aware that jsessionid cookie is created by a Java Application server. The server also determines when the cookie is stale and generates a new session cookie. Since this is a session (inline) cookie, cookie expiration is not set. This is a standard Java implementation.
As a result both the browser and the F5 do not have the logic to determine when the jsessionid cookie has expired. This is particularly a problem where there is no explicit “user logout” call from the browser.

One more point is, that jsessionid expiration is an idle timeout value. This means it is renewed on the server side with every request.

Is there a more robust iRule to make the sticky session work?

Appreciate your help.

Mahesh

6/18/2008 10:42 AM
Gravatar I'm trying to plug a security hole with a persist lookup call; however i'm getting some odd behaviour i don't understand from my implementation where the ltm log shows the following error message:

01220001:3: TCL error: Rule irule_test <HTTP_REQUEST> - Prerequisite operation not in progres (line 35) invoked from within "persist lookup uie $persist_string"

but it doesn't happen on every request, only some requests. When I put
iRule (truncated):

when CLIENT_ACCEPTED {
set add_persist 1
}

when HTTP_REQUEST {
set req_uri [URI::path [HTTP::uri] 1 1]
if { [HTTP::cookie exists JSESSIONID] } {
set persist_string "[HTTP::cookie JSESSIONID]:$req_uri"
set ret_val [persist lookup uie $persist_string]
if { $ret_val ne "" } {
persist uie $persist_string
} else {
#if we get here, we have an error
HTTP::respond 403 "<HTML><HEAD><TITLE>Access Forbidden</TITLE></HEAD><BODY>This security violation has been logged.<p></BODY></HTML>"
}
}
...
...
...
}

when HTTP_RESPONSE {
if { [HTTP::cookie exists "JSESSIONID"] and $add_persist } {
set persist_string "[HTTP::cookie JSESSIONID]:$req_uri"
persist add uie "$persist_string" 1920
set add_persist 0
}
...
...
...
}
steve
 Leave Feedback
Title  
Name  
Email
Url
Comments   
Please add 6 and 3 and type the answer here: