F5 iRule Conversion: Host and URL Rewrite, Content Matching and Redirecting

Those familiar with F5 iRules may wish to use similar configuration on the KEMP LoadMaster. These can be simply converted using the LoadMaster Content Rule Engine.

Below are some example iRules used for redirecting and rewriting URL and Host Headers.

Rewrites

Rewrite Hostname in HTTP Request

when HTTP_REQUEST {
    if { [HTTP::host] equals "domain.com" } {
        HTTP::header replace "Host" "newdomain.com"
    }
}

Rewrite URL in HTTP Request

when HTTP_REQUEST {
    if { [HTTP::uri] starts_with "/sometext" } {
        HTTP::uri "/newtext"
    }
}


Rewrite Hostname in Response
 

when HTTP_RESPONSE {
    if { [HTTP::host] equals "domain.com" } {
        HTTP::header replace "Host" "newdomain.com"
    }
}


Redirects
 

Redirect based on URL used

when HTTP_REQUEST {
    if { [HTTP::uri] equals "domain.com" } {
        HTTP::redirect "http://www.newdomain.com/index.htm"
    }
} 

Redirect based on Hostname used

when HTTP_REQUEST {
    if { [HTTP::host] starts_with "/sometext" } {
        HTTP::redirect "http://www.newdomain.com/index.htm"
    }
}

F5 iRule Breakdown

Typically the F5 iRule is broken into three parts:

  • When to apply the rule
  • What to compare
  • What to do

Refer to the sections below for further information on these parts.

 

When to apply the rule

These will typically determine where in the Virtual Service the Content Rule will be applied, i.e. Request or Response.

To get to the HTTP header modification Rule Management screen, go to Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Header Rules.

Here you can add request and response rules.

 

Request Rules

when HTTP_REQUEST {
}
Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Header Rules > Request Rules

 

Response Rules

when HTTP_RESPONSE {
}
Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Header Rules > Response Rules

 

Redirect Rules

Redirect rules are different - redirect rules should be applied under:

Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Selection Rules

The rule in this case will not change any headers but instead, cause the request to always fail. Using a second option under Not Available Redirection Handling, we can then add a redirect to take place when this forced fail happens. 

 

What to compare

Typically this will include looking at host headers and/or URL and will be contained in the content rule we create.

 

What to do

In most cases this will result in a rewrite of the host header/URL or in the case of a redirect, the rule will simply do a compare and if the result is matched - do a “Fail on Match”. This can then be used to trigger a predefined 302 redirection handling in the Virtual Service.

 

URL/Host Rewriting

URL

if {[HTTP::uri] equals "/exacttextmatch" }{
    HTTP::uri "/newtext"
}

 

Content Rule on the LoadMaster

Rule Name: RewriteURL

Rule Type: Modify URL

Match String: exacttextmatch

Modified URL: newtext

Apply the rule under:

Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Header Rules > Request Rules

Configured Example: Re-write wrong.png to welcome.png

Test: Re-write wrong.png to welcome.png

4     2015-08-24 11:46:02.294413     10.0.30.113     10.150.0.46     HTTP     179     GET /wrong.png HTTP/1.0                         Client->Virtual Service

9     2015-08-24 11:46:02.295818     10.110.0.160     10.110.0.150     HTTP     181     GET /welcome.png HTTP/1.0               LoadMaster->Real Server

Host

if { [HTTP::host] equals "domain.com" } {
    HTTP::header replace "Host" "newdomain.com"
}

Content Rule on the LoadMaster

Rule Name ReplaceHost

Rule Type Replace Header

Header Field host

Match String domain.com

Value of Header Field to be replaced newdomain.com

Apply the rule under:

Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Header Rules > Request Rules

Test: Re-write wronghost.com to iis151.contoso.com

Client->Virtual Service

Hypertext Transfer Protocol
    GET /wrong.png HTTP/1.0\r\n
    User-Agent: Wget/1.12.1-devel (mingw32)\r\n
    Accept: */*\r\n
    Host: wronghost.com\r\n

  

LoadMaster->Real Server

Hypertext Transfer Protocol
    GET /wrong.png HTTP/1.0\r\n
    User-Agent: Wget/1.12.1-devel (mingw32)\r\n
    Accept: */*\r\n
    Host: iis151.contoso.com\r\n

 

The same rules above (rewriting Host or URL) can be applied for HTTP responses by applying under:

Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Header Rules > Response Rules

 

302 Redirecting

Is this case the procedure is different as we need to match on the specific host header or URL and then cause a 302 redirect inside the Virtual Service.

Host

if { [HTTP::host] equals "domain.com" } {
    HTTP::redirect "http://www.newdomain.com/index.htm"
}

Content Rule on the LoadMaster

Rule Name redirectdomain

Rule Type Content Matching

Match Type RegExpression

Header Field host

Match String domain.com

Fail on Match <enable>

Apply the rule under:

Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Selection Rules

 

In Advanced Properties of the Virtual Service - add a redirect in the Not Available Redirection Handling section.

Error Code: 302 Found

Redirect URL: http://redirectdomain.com%s

Test: Redirect domain.com to redirectdomain.com

C:\GNUwin32\bin>wget-1.12 domain.com/welcome.png
--2015-08-24 11:35:58--  http://domain.com/welcome.png
Resolving domain.com... 10.111.0.173
Connecting to domain.com|10.111.0.173|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://redirectdomain.com/welcome.png
 [following]

--2015-08-24 11:35:58--  http://redirectdomain.com/welcome.png
Resolving redirectdomain.com... 69.172.201.208
Connecting to redirectdomain.com|69.172.201.208|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: unspecified [text/html]
Saving to: `welcome.png.1'

    [ <=>                                   ] 1,556       --.-K/s   in 0s

2015-08-24 11:35:58 (69.8 MB/s) - `welcome.png.1' saved [1556]

 

URL

For redirects based on the URL the procedure is the same except the rule will match on the URL (the Header field in the content rule can be left blank) rather than on hostname.

if { [HTTP::uri] starts_with "/sometext" } {
    HTTP::uri "/newtext"

Content Rule on the LoadMaster

Rule Name redirectdomain

Rule Type Content Matching

Match Type RegExpression

Header Field <blank>

Match String sometext

Fail on Match <enable>

 

Apply the rule under:

Virtual Services > View/Modify Services > Modify > Advanced Properties > Show Selection Rules

In Advanced Properties of the Virtual Service - add a redirect in the Not Available Redirection Handling section.

Error Code: 302 Found

Redirect URL: http://%h/newtext

 

Test: Redirect URL containing /sometext to http://<domain>/welcome.png where <domain> is the domain in initial request.

C:\GNUwin32\bin>wget-1.12 domain.com/wrong.png

--2015-08-24 11:32:30--  http://domain.com/wrong.png
Resolving domain.com... 10.111.0.173
Connecting to domain.com|10.111.0.173|:80... connected.
HTTP request sent, awaiting response... 302 Found
Location: http://domain.com/welcome.png
 [following]

--2015-08-24 11:32:30--  http://domain.com/welcome.png
Connecting to domain.com|10.111.0.173|:80... connected.
HTTP request sent, awaiting response... No data received.
Retrying.

--2015-08-24 11:32:31--  (try: 2)  http://domain.com/welcome.png
Connecting to domain.com|10.111.0.173|:80... connected.
HTTP request sent, awaiting response... 200 OK
Length: 184946 (181K) [image/png]
Saving to: `welcome.png'

100%[======================================>] 184,946     --.-K/s   in 0.03s

2015-08-24 11:32:31 (5.20 MB/s) - `welcome.png' saved [184946/184946]


 

F5 iRule Conversion Examples

 

Example 1

F5: Select pool based on HTTP host header

iRule

when HTTP_REQUEST { set hostpool [string tolower [HTTP::host]]_pool # Show us what the client sent in the host header - Turn this OFF in production log local0. "pool is $hostpool" # Use if/then with "Catch" to account for any bad host headers - otherwise TCL will throw an error to the client if { [catch {pool $hostpool} exc] } { # If a client sends a host header that does not match a pool, send to default pool pool P3 } }

KEMP Solution:

To Achieve, we will use Content Switching in conjunction with Sub Virtual Services.

Assuming two server pools, we create two content rules matching on "Host headers", and three
Sub Virtual Services (SubVS). The third SubVS is used as a "Catch all" for any host headers that
don't match.


1. Rules & Checking > content Rules > New Rule

Rule 1



Rule 2




2. Create Three Sub Virtual Services. Modify VS > Real Servers > Add SubVS
Name each Sub VS Accordingly e.g "Pool-1" and configure each SubVS as a regular VS, this includes
adding your pool of servers.


3. Enable Content Switching. If traffic is encrypted you will need to enable "SSL Acceleration"
located in "SSL Properties" within your Virtual Service.

Modify VS --> Advanced Properties






4. Assign Rules to Server Pools.

Navigate to SubVSs > Rules. Apply previously created Content Rule "Pool1" to Pool-1 Sub VS, and apply
Content Rule "Pool2" to Pool-2 Sub VS.

Apply "Default" rule to the "Default" Sub VS.





5. Testing
In your Browser enter e.g. web1.domain.com. You should receive the expected response from a server
within Pool-1.




Example 2

F5: Select Pool Based On Source IP Address

iRule


1 when CLIENT_ACCEPTED {
2 if { [IP::addr [IP::client_addr] equals 10.10.10.10] } {
3 pool my_pool
4 }
5 }


KEMP Solution

To Achieve, we will use Content Switching in conjunction with Sub Virtual Services.
Assuming two server pools, we create two content rules matching on "Source IP", and three 
Sub Virtual Services (SubVS). The third SubVS is used as a "Catch all" for any Source IP Addresses
that don't match


1. Rules & Checking > Content Rules > New Rule

Rule 1


Rule 2



NOTE: to include full Subnet range e.g 192.168.0.0 - 192.168.255.255 use below string.

/^192.168.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[0-9][0-9]?).(25[0-4]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)$/


2
. Create Three Sub Virtual Services. Modify VS > Real Servers > Add SubVS Name each Sub VS Accordingly e.g "Pool-1" and configure each SubVS as a regular
VS, this includes adding your pool of servers.


3. Enable Content Switching. If traffic is encrypted you will need to enable
"SSL Acceleration"








Navigate to SubVSs > Rules. Apply previously created Content Rule "Pool1" to Pool-1 Sub VS,
and apply Content Rule "Pool2" to Pool-2 Sub VS.

Apply "Default" rule to the "Default" Sub VS.






5. Testing
Connect to your virtual service using a client with source IP 10.10.10.10. You should
receive the expected response from a server within Pool-1.






Example 3

Modify Host Name and append URI/URL with directory and file
Customer requires a request containing "https://china.mysite.com/"  to be rewritten to 
"https://la.mysite.com/documents/china.pdf".
In this the client will see
https://china.mysite.com/document/china.pdf
but the backend server will see
https://la.mysite.com/document/china.pdf


F5 iRule

when HTTP_REQUEST { if { [HTTP::uri] equals "/" } { # the node command directs the request to the server # whether or not it is behind the BigIP. Make sure the BigIP # has a route to that server. node 1.2.3.4 # In case you don't have SNAT on the virtual, you may need it here. snat automap # In case the server complains, set the host header. HTTP::header replace Host "la.mysite.com" # Finally change the URI while on its way to server. HTTP::uri /documents/china.pdf } }


KEMP Solution

To achieve we will create two Content Rules. One rule will be used to modify "Host" and the other
rule used to append the URI/URL.


1. Create Rules

Rules & Checking > Content Rules > New Rule


Rule 1



Rule 2




2. Navigate to Virtual Services > Modify > Advanced Properties > HTTP Header Modifications

Apply both rules we created.






Example 4

Rule to allow access to a URI only from a specific source subnet


When HTTP_Request, if the uri contains "something/test/testing" and source IP matches
192.168.0.0/16,
then send to my pool. All other requests to uri's containing "something/test/testing"
and source IP does not match 192.168.0.0/16, then drop.


F5 iRule

when HTTP_REQUEST {
# The switch statement is good for conditionals and easy to manage.
# The '-glob' parameter marks the switch to allow wildcards (the "*")
switch -glob -- [string tolower [HTTP::uri]] {
"*/something/test/testing*" {
if { [IP::addr [IP::client_addr] equals 10.1.1.0/24] } {
# Process the traffic
pool POOL_NAME
} else {
HTTP::respond 200 content { <html> <head> <title>Sorry Page</title>
</head> <body> Sorry, this Page is restricted. </body> </html> }
}
}
}
}


KEMP Solution

To achieve we will make use of Content Matching and Flags. We can create Two Content Matching Rules.
One rule will match "/something/test/testing" where we will set Flag-1, and another content rule
to match on the Source Subnet e.g 192.168.0.0/24.

1. Create Rules

Rule 1
Match /something/test/testing and set Flag 1



Rule 2
Match Subnet 192.168.0.0/24 and Perform on Flag 1


2. Enable Content Switching

Navigate to Virtual Services --> Modify VS --> Advanced Properties --> Enable Content Switching



3. Apply Rules to Real Servers

Navigate to Virtual Services --> Real Servers --> Rules







Ensure "SomethingTest" Content Rule has precedence. Advanced Properties --> Rule Precedence


4.
If required, you can send failed connections to a redirect or display a "Unauthorized" message


Navigate to Virtual Services --> Modify VS -->  Advanced Properties --> Not Available Redirect Handling.

Select e.g 401 Unauthorized and enter an Error Message.



 

Was this article helpful?

0 out of 0 found this helpful

Comments