Rewrite Host Header to Server Name
Problem this snippet solves:
On each HTTP request, the selected pool member IP address is looked up against a datagroup and the corresponding hostname is inserted in the HTTP host header.
The iRule expects one string type datagroup to be defined: ip_to_host_dg
If you're using a version lower than 10.0, see the second example. For versions lower than 9.4.4, change the class reference in the second iRule from ip_to_host_dg to $::ip_to_host_dg.
Code :
# Name : host_header_rewrite_rule
#
# HTTP host header rewrite rule
#
# BIG-IP LTM
# Tested on version 11.1.0 (but should work on 10.x or 11.x)
#
# Version: 1.1 - Initial version tested
#
# Description:
#
# On each HTTP request, the selected pool member IP address is looked up against a datagroup and the corresponding hostname
# is replaced in the HTTP host header.
#
# Configuration requirements:
#
# 1. This iRule expects a string datagroup named ip_to_host_dg to be defined with the following format:
#
#ltm data-group internal ip_to_host_dg {
# records {
# 1.1.1.1 {
# data host1.example.com
# }
# 1.1.1.2 {
# data host2.example.com
# }
# 1.1.1.5 {
# data host3.example.com
# }
# }
# type string
#}
#
# 2. Each pool member must be configured and any time the pool membership changes, this data group must be updated.
#
when HTTP_REQUEST_SEND {
# Log debug messages to /var/log/ltm? 1=yes, 0=no.
set host_debug 1
# Need to force the host header replacement and HTTP:: commands into the clientside context
# as the HTTP_REQUEST_SEND event is in the serverside context
clientside {
if {$host_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: [HTTP::method] request to [HTTP::host][HTTP::uri]"}
# Look up the selected server IP in the datagroup to get the host header value
set host_header_value [class match -value [IP::server_addr] equals ip_to_host_dg]
if {$host_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Looked up [IP::server_addr], found: $host_header_value."}
# Check if the lookup returned a value
if {$host_header_value ne ""}{
# Replace the host header value
HTTP::header replace Host $host_header_value
if {$host_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Replaced Host header with $host_header_value."}
}
}
}
# v9.x
# Name : host_header_rewrite_rule (v9.x)
#
# HTTP host header rewrite rule
#
# BIG-IP LTM
# Tested on version 9.4.8
#
# Version: 1.0 - Initial version tested
#
# Description:
#
# On each HTTP request, the selected pool member IP address is looked up against a datagroup and the corresponding hostname
# is replaced in the HTTP host header.
#
# Configuration requirements:
#
# 1. This iRule expects a string datagroup named ip_to_host_dg to be defined with the following format:
#
# pool member IP | host header to insert
# ---------------|-------------------
# 1.1.1.1 | host1.example.com
# 1.1.1.2 | host2.example.com
# 1.1.1.5 | host3.example.com
#
# 2. Each pool member must be configured and any time the pool membership changes, this datagroup must be updated.
#
when HTTP_REQUEST_SEND {
# Log debug messages to /var/log/ltm? 1=yes, 0=no.
set host_debug 1
# Need to force the host header replacement and HTTP:: commands into the clientside context
# as the HTTP_REQUEST_SEND event is in the serverside context
clientside {
if {$host_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: New [HTTP::method] request to [HTTP::host][HTTP::uri]"}
# Look up the selected server IP in the datagroup to get the host header value
set host_header_value [findclass [LB::server addr] ip_to_host_dg " "]
if {$host_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Looked up [LB::server addr], found: $host_header_value."}
# Check if the lookup returned a value
if {$host_header_value ne ""}{
# Replace the host header value
HTTP::header replace Host $host_header_value
if {$host_debug}{log local0. "[IP::client_addr]:[TCP::client_port]: Replaced Host header with $host_header_value."}
}
}
}Published Mar 18, 2015
Version 1.0hoolio
Cirrostratus
VP of Solutions at WorldTech IThoolio
Cirrostratus
VP of Solutions at WorldTech IT3 Comments
- paymon_199568
Altostratus
Hey, I used the code above and it worked perfectly when I wanted to replace the hostheader from www.abc.com to "site1" for pool member 1 and "site2" for pool member 2. However the webpage has been hosted on site1/reports and site2/reports. When I enter in my browser http://www.abc.com/reports my url address change to http://site1/reports(it get redirected). How can I fix this? in other words when I enter http://www.abc.com/reports below happens. For Node member 1: Hostheader=site1 uri=site1/reports For Node member 2: Hostheader=site1 uri=site2/reports However we need to have this uri change being transparent from the user perspective. Thanks, Peyman - neeraj2901_2661
Nimbostratus
Answer please to above question
- skelle_296888
Nimbostratus
Hi paymon, maybe a bit late (2018 *cough*) but here are some ideas.
- You could configure your AppServer that its sending relative redirects and no absolute ones.
- Configure your AppServer to accept "X-Forwarded-Host"-Headers
- Create an iRule with a "HTTP_RESONSE"-Event wich is scanning for redirects and modify the Location-Header
Have a nice day.