Forum Discussion

Andrew_Husking's avatar
Sep 03, 2013

iRule/http profile to change server side host header.

We are using the F5's as a central portal that can be presented anywhere on the network.

 

What we want to be able to do is go http://portal.company.com/application and have /application go to web server X instead of Y. Now we have that part sorted, but the issue is that web server X only listens on certain host headers (which we can't use or change) and i'm looking for a way to get the F5 to change the HTTP host header on the server side, without changing it on the client side.

 

Cheers

 

  • Is this an APM access portal, or just LTM-based? If the latter, you'll probably want to use a data group to map the URI pattern to a given internal host name. Example:

     

    Data group (ex. my_uri_dg):

     

    "/application1" := "server1.domain.com"
    "/application2" := "server2.domain.com"
    "/application3" := "server3.domain.com"

    And then an iRule like this:

     

    when HTTP_REQUEST {
        if { [class match [string tolower [HTTP::uri]] starts_with my_uri_dg] } {
            HTTP::header replace Host [class match -value [string tolower [HTTP::uri]] starts_with my_uri_dg]
        }
    }

    Alternatively, if it's a small static set of hosts you can hard-code it into the iRule, or if it's a large set of dynamically changing hosts, you could potentially perform a reverse DNS query from the load balanced server IP to get the server's name.

     

  • It's done through LTM (APM is there for some parts, but for most it's turned off).

     

    The issue i had when using an iRule similar to the one you have provided is it changes the client to use the new hostname instead of portal.company.com

     

    Cheers

     

  • The iRule doesn't change the hostname client side, it's just the responses from the server obviously have the 'correct' hostname specified. You'll need to rewrite the responses with a stream profile to replace the actual correct hostname with the one clients expect/use. If you need more information on how to do that, let us know.

     

  • Just to amplify Steve's comments, the HTTP_REQUEST event is an ingress filter event, so it only affects traffic going to the server. The client would not see this change unless the server itself was sending something back in the response (ie. object links, redirects, etc.). For that your best bet is a stream iRule to replace those values on the way back out to the client.

     

  • I found my issue, it was that the server was sending a 301 redirect to the client to force all clients to use that host header.

    I used the following iRule to fix it up (from here)

        when HTTP_RESPONSE {
       do replace on Location header if we get one (e.g. http redirections) - not covered by stream profile
      if { [HTTP::header exists Location] } {
        regsub "remotedomain.com" [HTTP::header Location ] "localdomain.com" newlocation
        HTTP::header replace Location $newlocation
      }
    }
    

    Thanks for all the help guys 🙂