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/” (, the “/old_URI/” will be replaced with “/new_URI/old_URI” and this will be passed to the servers (

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:

set URI [string tolower [HTTP::uri]]
if {$URI starts_with "/m/" }{ 
set NEW_URI [string map {"/m/" "/"} [HTTP::uri]] 
HTTP::respond 301 Location "$NEW_URI"


$ curl -I
HTTP/1.0 301 Moved Permanently
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,été is encoded as follows:


set ENCODED_URI [ b64encode [HTTP::uri]]

    switch [HTTP::host] { "" { 

          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> {

Commonly used iRULE Events:


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 “” } {

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 “” 🙂

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

Migrating DNS Providers

When migrating your DNS records from a DNS provider to another DNS provider, make sure to follow the following:

  • Lower the TTL for your DNS records to the lowest possible value provided by your DNS provider
  • Create a copy of the DNS records at the new DNS provider.
  • Do NOT delete the DNS records at your old DNS provider.
  • Update the name servers at your domain registrar.
It takes about 48 hours for the NS record to be updated as the TLD (Top Level Domains) have a default TTL of 48 hours. For the duration of 48 hours, both your old and new DNS provider will be queried for DNS record information, depending on the cached DNS records information at the Local DNS servers. After you can verify from different locations in the world that the NS record has changed, I would recommend waiting for another 2 days before deleting the old NS records.

Changing DNS Records

Whenever you have to change your existing DNS records, without migrating your DNS provider (without changing the name servers), make sure to lower the TTL value of your DNS records to as low as possible. Some DNS providers have a default TTL value and your DNS record’s TTL will reset to the default value after a specific number of days. In order to prevent this reset to your DNS provider’s default TTL value, make sure to “freeze” the TTL value for a few days before and after the actual change is made.