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
LoadMaster->Real Server Hypertext Transfer Protocol
|
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 |
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 |
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.