How to Write F5 iRules with Examples

If you’ve ever seen an F5 BIG-IP configuration page, you know it has a lot of different options. There are dozens of settings just for creating a simple virtual server and almost a hundred options to set up certain profiles. But even with all these options, you just can’t do some things.

But believe me, you could likely do those things, just not with the BIG-IP’s standard configuration. That’s where iRules come in, to save the day for us.

What are the F5 iRules?

F5 iRules is a powerful scripting language used on F5 BIG-IP load balancers to customize and control the behavior of traffic flowing through the network. iRules allow you to manipulate and make decisions about network traffic at various layers of the OSI model, providing advanced traffic management and application control capabilities.

They are based on the TCL (Tool Command Language) scripting language. The iRules include variables, conditional statements, loops, and other features for complex traffic processing. They provide a flexible and powerful framework for customizing the behavior of network traffic. We will see some examples later in this tutorial, of how an iRule can solve something, which could not be solved via the standard BIG-IP configuration.

How do iRules work?

When you create an iRule, you basically create a configuration object on the BIG-IP device, just like you create a pool or a virtual server. This object can be attached to a Virtual Server or multiple Virtual Servers, so then it will start working as intended inside of its code.

Based on the iRule code, the BIG-IP will modify the standard virtual server behavior, and after receiving traffic, it will act based on the iRule configuration.

Learning iRules – Let’s deep dive and see iRules in action

Example 1 – Using iRule to Redirect http to https

Isn’t it annoying, if you type a website’s name into your browser, hit enter, and then it just hangs… Because you didn’t specify https:// in front of the website’s name. By default, browsers will send simple HTTP traffic if you don’t specify HTTPS in the address bar. Fortunately, most of the websites on the Internet have an http-to-https redirection in place, let’s see how we can achieve the same if we have an F5 BIG-IP in front of our web server.

The initial setup is the following: We have two virtual servers on our BIG-IP, one is listening on HTTP, and the other one is on HTTPS, but they are configured with the same IP address.

Screenshot showing F5 Big IP irule setup with 2 separate Virtual Servers, one for http, the other for https

If our BIG-IP receives traffic on port 443, it will provide the backend web server content via HTTPS. But if it receives traffic on port 80, we need to make sure that the original client, who initiated the traffic, gets notified to use HTTPS instead of regular HTTP.

Let’s create a new iRule: Go to Local Traffic / iRules / Create

Give it some name (in our case HTTP-TO-HTTPS-REDIRECT), then paste the code.

Screenshot showing F5 Big IP with simple http-to-https redirect iRule
when HTTP_REQUEST {
  HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri]
}

Save it, then let’s apply it to the HTTP virtual server. Go to Local Traffic / Virtual Servers / the virtual server name with http / Resources

You can notice, there are no records under the iRules section. Click on Manage.

Screenshot showing F5 Big IP location of adding the iRule for the Virtual Server

Find the iRule you created in the Available section, select it by clicking on it, with the arrow button move it to the Enabled section, then click Finished.

Screenshot showing how to set up the iRule as enabled in F5 Big IP

With these steps, we enabled the iRule to control the traffic received by the HTTP virtual server.

Let’s break down how this iRule is set up.

when HTTP_REQUEST {
  HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri]
}

when HTTP_REQUEST: this is an event, which triggers every command and steps after it. This means the rest of the iRule config is only executed when an HTTP Request arrives at the virtual server. This is a Layer 7 event, so it’s not enough to get the IP packet, not enough to make the three-way TCP handshake, but in order to trigger this event, the virtual server needs to receive an HTTP Request.

HTTP::redirect: this is an iRule command, which basically sends an HTTP 302 (Temporary Redirect) status code back to the client, with the additional details of where to be redirected.

https://[getfield [HTTP::host] “:” 1][HTTP::uri]: this section basically tells the client what is the new URL they should use, in order to reach the website. It will use the getfield [HTTP::host] “:” 1 to get the HTTP host header from the original request, and it will send back the same URL, just with an additional https:// in the beginning. So the client browser now tries to reach the same URL but now with HTTPS.

So let’s test our setup. I created this iRule, I attached it to the http virtual server, and now I’m sending an http get to the virtual server:

curl -vk http://testwebsite.test
> GET / HTTP/1.1
> Host: testwebsite.test
> Accept: */*
>
< HTTP/1.0 302 Moved Temporarily
< Location: https://testwebsite.test/
< Server: BigIP

Notice the immediate response from the BIG-IP. It’s an HTTP 302 Moved Temporarily, and it also sends the new location, which now has the https, so the client can try again, now with HTTPS.

This iRule is ready and working successfully.

Example 2 – iRule Route based on HTTP Host Header

Sometimes you are short on public IPs. Or you have dozens of subdomains, and you want to make operations easier. This example will show you how to create a single Virtual Server and still host dozens of different applications/websites on the same IP address.

Let’s imagine the following scenario:
You have dozens of websites that run on the same domain but different subdomains (you could even run many websites with different domains on the same Virtual Server, but that is a topic for another tutorial).

app1.example.com
app2.example.com
testing.example.com
.
.
.

You get the idea. Usually, when you create a Virtual Server, you assign one specific Pool to it, so BIG-IP will forward traffic to members of that specific Pool. Now let’s imagine all of your websites are running on different servers or different ports.

pool_app1
pool_app2
pool_testing
.
.
.

By default, you can’t assign multiple pools to a single Virtual Server. Again, iRules can help us solve this situation.

You have all these pools already configured on your BIG-IP. Then you create an iRule with the following content:

when HTTP_REQUEST {
    # Extract the Host header from the request
    set var_host [HTTP::header "Host"]
    # Perform the pool selection based on the Host header value
    switch -glob $host {
        "app1.example.com" {
            pool pool_app1
        }
        "app2.example.com" {
            pool pool_app2
        }
        “testing.example.com” {
            pool pool_testing
        }
    }
}

Let’s again break down this iRule.

when HTTP_REQUEST: this is an event in iRule terminology, which makes the BIG-IP execute all other commands, and tasks after it.

set var_host [HTTP::header “Host”]: this creates a variable called “var_host” (you could pick any other name for it), examines the HTTP header of the received traffic, and then stores the HTTP Host header part in that variable.
In our previous example, you can see what a host header looks like:

> Host: testwebsite.test

The content of the host header will be stored in the variable called “var_host”.

switch -glob $var_host: switch is an operator, which does evaluate the pattern we specified in the “var_host” variable, and compares it with the rest of the statements below.

“app1.example.com” { pool pool_app1 }: if the switch operator sees a full match between the content of the “var_host” variable and “app1.example.com”, then it does set the pool “pool_app1” for this HTTP connection. If switch finds a match, then executes that part of the code, then it exits, so the rest of the code is not evaluated.

Make sure you add this iRule to the Virtual Server Resources, also make sure you don’t specify any pool on that page since now the iRule is doing the pool selection, there is no need to specify a default pool.

F5 Big IP showing adding a iRule but leaving the Default Pool as None

Now with this setup, we were able to save 2 public IPs, since we needed to create only one Virtual Server to host our 3 different applications/websites. You can imagine a similar solution with dozens or hundreds of websites.

Example 3 – iRule redirect old HTTP URI to new

In some cases, web server admins change the name of files. Or they rename website sections. Let’s see an example, where the website had a /blog/ section, with a lot of entries, but the admin decided to change that, and from now on all articles are available on the /tutorials/ section.

Of course, if people visit the website, and click on the right name, they will reach the /tutorials/ pages. But many times people bookmark pages or use hard-coded scripts to reach certain URLs.
We can help these visitors by applying an iRule, which redirects them to our new /tutorials/ section.

Let’s see this iRule:

when HTTP_REQUEST {
	if { [HTTP::uri] starts_with "/blog/"} {
			HTTP::uri [string map {"/blog/" "/tutorials/"}[HTTP::uri]]
			HTTP::redirect "[HTTP::uri]"
		}
}

iRule breakdown as usual:

if { [HTTP::uri] starts_with “/blog/”}: an IF statement, everything below this statement is executed if the statement is true. What is HTTP URI? It is everything behind the site’s main address, for example:

https://networkproguide.com/how-to-upgrade-f5-big-ip-software/

In this case, /how-to-upgrade-f5-big-ip-software/ is the HTTP URI. If this URI contains /blog/, then our if statement is true, and the rest of the iRule is executed.

HTTP::uri [string map {“/blog/” “/tutorials/”}[HTTP::uri]]: this line replaces the /blog/ text with the /tutorials/, using the “string map” command, which replaces texts according to our setup. You can notice an additional [HTTP::uri] at the end of the line, this makes sure that anything the user typed after the original /blog/, will be added back to the request. So if the user typed /blog/article-1, then after the execution of this iRule, the request would look like this: /tutorials/article-1

HTTP::redirect “[HTTP::uri]”: this is our usual redirect command, so eventually the user’s browser will get a redirect message, which will contain the new URI, so the browser can visit the new address.

Let’s see this iRule in action:

curl -vk http://testwebsite.test/blog/article-1
> GET / HTTP/1.1
> Host: testwebsite.test
>
< HTTP/1.0 301 Moved Permanently
< Location: http://testwebsite.test/tutorials/article-1
< Server: BigIP

When to use iRules

If you spend some time with the iRules documentation, you will see the options and capabilities are basically infinite. You need to understand the logic of the iRules, and you need some time to practice the syntax.

However, F5 has a recommendation on when to use iRules. You can do everything with iRules, even stuff that is not available through the GUI or F5 CLI, but just because you can doesn’t mean you should. While iRules are precompiled into a byte-code state, which means “mostly” compiled, and the BIG-IP software can use it very quickly and efficiently, using an iRule is a bit slower than using an already builtin feature of the GUI or CLI. So, as a general recommendation, if a feature or configuration is available on the GUI or CLI, then use that. If the setup you want to create is not available, you can create an iRule to solve it.

For example, if you want to restrict network access from specific IP addresses or ranges, you could write an iRule to do that, but most probably applying Local Policies is a better way to do this, at least from a performance perspective.

In summary, feel free to learn how to write iRules, since this knowledge will make you stand out from a herd of “I only do enable/disable pool members” F5 engineers. This knowledge will make you a better network engineer, and you will get to know a lot more about Layer 7 traffic handling.

Sources

https://clouddocs.f5.com/api/irules/
https://community.f5.com/t5/technical-articles/to-irule-or-not-to-irule-introduction-to-local-traffic-policies/ta-p/279536

Recommended Tool: ManageEngine OpManager

  • Multi-vendor Network Monitoring
  • Simple Installation & Setup
  • Intuitive UI
  • Complete Visibility
  • Intelligent Detections
  • Easy Resolutions

Leave a Reply

Your email address will not be published. Required fields are marked *