iRule – Altering Header Information

This iRULE example will alter the incoming URI before passing the request to the servers:

when HTTP_REQUEST { switch -glob [HTTP::uri] { /old_URI/* { HTTP::uri /new_URI[HTTP::uri] } } }

In this case, for any incoming request that starts with the URI “/old_URI/” (http://domain.com/old_URI/), the “/old_URI/” will be replaced with “/new_URI/old_URI” and this will be passed to the servers (http://domain.com/new_URI/old_URI/)

The various interpretations within the switch statement:

/old_URI/      – URI equals /old_URI/
/old_URI/*    – URI starts with /old_URI/
*/old_URI/* – URI contains /old_URI/

Instead of the “switch” statement, we can also use an “if-statement” like this:

when HTTP_REQUEST { if { [HTTP::uri] starts_with "/old_URI/" } { HTTP::uri /new_URI[HTTP::uri] } }

A slightly more complex version of the URI function alteration is provided here:

when HTTP_REQUEST { set HOST [string tolower [HTTP::host]] set URI [string tolower [HTTP::uri]] if { $URI contains "/NEW_Session_ID=" } {HTTP::uri [string map {/NEW_Session_ID= /OLD_Session_ID=} [HTTP::uri]] pool POOL-WEB-Server } } when HTTP_RESPONSE { if { [HTTP::header values Location] contains "/OLD_Session_ID=" } { HTTP::header replace Location [string map {/OLD_Session_ID= /NEW_Session_ID=} [HTTP::header value Location]] } }

For any incoming HTTP Request, “/NEW_Session_ID=” within the URI is replaced with “/OLD_Session_ID=” and passed to the servers in the pool “POOL-WEB-Server”.

For any HTTP Response from the server to the client that contains the HTTP Header Location, “/OLD_Session_ID=” is replaced with “/NEW_Session_ID=”

This can be used to “mask” the URI or any other header information between the client and the server.

The following iRule will remove “/m/” in the incoming URI and send a redirect:


when HTTP_REQUEST {
set URI [string tolower [HTTP::uri]]
if {$URI starts_with "/m/" }{ 
set NEW_URI [string map {"/m/" "/"} [HTTP::uri]] 
HTTP::respond 301 Location "http://www.domain.com$NEW_URI"
}
}

TEST:

$ curl -I http://10.10.10.10/m/OLD_URI
HTTP/1.0 301 Moved Permanently
Location: http://www.domain.com/OLD_URI
Server: BigIP
Connection: Keep-Alive
Content-Length: 0

The “/m/” in the URI is replaced with “/” as seen in the “Location” header.

This has been tested in production environment on 10.x code of F5 LTM

iRULE – non-English Characters

The web browser will URL encode URI’s that contain special characters.

For example, http://www.domain.com/été is encoded as follows: http://www.domain.com/%C3%A9t%C3%A9

when HTTP_REQUEST { 

set ENCODED_URI [ b64encode [HTTP::uri]]

    switch [HTTP::host] { "domain.com" { 

          if { (($ENCODED_URI eq "LyVDMyVBOXQlQzMlQTk=") or ($ENCODED_URI eq "L2ZyLyVDMyVBOXQlQzMlQTk=")) } 

{ pool POOL_Web-Servers } 

} 

}

}

“/été” URL encodes to “/%C3%A9t%C3%A9″ which base64 encodes to “LyVDMyVBOXQlQzMlQTk=”

“/fr/été” URL encodes to “/fr/%C3%A9t%C3%A9” which base64 encodes to “L2ZyLyVDMyVBOXQlQzMlQTk=”

An Intro to iRULE

This post will provide basic information related to iRULE. The intention of writing this post is to provide someone new to iRULE with basic introduction and cover some of the often used Functionality. This isn’t an in-depth coverage of iRule.

What is an iRULE:

TCL based scripting that is utilized by F5 Application Delivery Modules to manipulate traffic.

Structure of an iRULE:

when <EVENT> {
<PERFORM ACTION>
}

Commonly used iRULE Events:

  • HTTP_REQUEST
  • HTTP_RESPONSE
  • CLIENT_ACCEPTED

Having worked with iRules for almost 5 years, the above 3 events are what I utilize on a daily basis. Almost 9 out of 10 iRules that I have written cover the above events. For an iRule rookie, I would recommend understanding the above 3 events.

Within the structure of the iRule, <PERFORM_ACTION> provides the ACTION to be performed if certain CONDITIONS are matched. For example:

if { [HTTP::host] equals “domain.com” } {
pool POOL_WEB-SERVER
}

Even if you don’t understand scripting, the above information should be quite clear that you are sending the traffic to the pool: POOL_WEB-SERVER, if the incoming host header equals “domain.com” 🙂

Common ACTIONS that I have utilized:

  • Load Balancing based on incoming header values
  • Redirection based on incoming header values
  • Persistence based on incoming header values

As seen above, the vast majority of ACTIONS involve one of three actions based on the incoming header value. We can also perform more complicated actions based on the content of the incoming packet. However, in my opinion, it is better to avoid performing such actions on the load balancer. As the code gets complex, there is a serious question on accountability and ownership – who owns the code (Dev guys, Network guys ?!?) – this requires a separate post just to hash out the realms of control.

Points to Remember:

  • iRULE is TCL based scripting utilized to manipulate traffic on an F5 device
  • iRULE, like TCL is EVENT based
  • iRULE’s structure consists of EVENT, CONDITIONAL statements & ACTION to perform