Forum Discussion

John_Comstock's avatar
John_Comstock
Icon for Nimbostratus rankNimbostratus
Sep 13, 2006

iRule for URL Re-write

I have a requirement to rewrite the URL that external business partners connect to for both HTTP and HTTPS (will terminate SSL on the BigIP) traffic to forward to internal web sites. Can anyone direct me to posts that will get me started?

 

 

External business partners will hit https://theirsite.externaldomain.com

 

 

and I will need to forward them to another proxy server (for logging purposes)and forward them to the internal site http://oursite.internaldomain.com

 

 

while keeping the pertinent URI string.

 

 

Assistance would be much appreciated.

 

 

John

9 Replies

  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    I'm not sure I caught the part about needing to forward them to a proxy server. Are you saying you need to forward the traffic two places? Or are you just wanting to redirect a request from https://theirsite.externaldomain.com to http://oursite.internaldomain.com?

    If the latter is the case, then all you'd need is the redirect command, like this:

    
    when HTTP_REQUEST {
      if { [HTTP::host] eq "theirsite.externaldomain.com" } {
        HTTP::redirect http://oursite.internaldomain.com
      }
    }

    You would, of course, have to be sure that the BIG-IP is decrypting the SSL traffic by way of a client-ssl profile before inspecting things.

    Colin
  • Hi,

     

    Thank you for the feedback. Our external business partners for these applications connect to our enterprise network via dedicated circuits, frame relay or Internet VPN connections and some of the applications are available via the Internet. They all in an externaldomain. Lets call it external.com. Some of the apps require a reverse proxy. Our old reverse proxies terminated ssl. We have bigips deployed to load balance web servers for some apps and to load balance traffic across some proxy appliances. We need to translate the host portion of the URL and forward the connection to the proxy appliance which will log the session and set up connections to multiple back end applications.

     

     

    Redirects wont be feasible because the client would then try to resolve our internal domain and our external business partners don't have that access.

     

     

    I was thinking of something like this..

     

     

    when HTTP_REQUEST {

     

    if { ( [HTTP::host] equals "myservices.external.net" ) } {

     

    HTTP::header replace Host "myservices.internal.net"

     

    }

     

    if { ( [HTTP::host] equals "myservices2.external.net" ) } {

     

    HTTP::header replace Host "myservices2.internal.net"

     

    }

     

    }

     

     

    Is there a better way of doing the translation so that I wouldnt have to add another if then statement for each new app?

     

     

    -John
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Hi John -

    Try this:
    when HTTP_REQUEST {
      if { ( [getfield [HTTP::host] ":" 1] ends_with "external.net" ) } {
        HTTP::header replace Host [string map -nocase {"external.net" "internal.net"} [HTTP::host]]
      }
    }

    /deb
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    Great example Deb.

     

     

    This would also be a good place to use the domain command (Click here), which accomplishes the same thing as the getfield segment.

     

     

    Colin

     

  • G__Wesley_Rober's avatar
    G__Wesley_Rober
    Historic F5 Account
    Hi,

    If you need to do more detailed mappings, data group/classes might be useful.

    
    Given the following data group, if found replace one with two
    class urlrewrite  {
       "apples.com oranges.com"
       "foo.com bar.com"
       "peas.com carrots.com"
    }
    when HTTP_REQUEST {
        set entry [findclass [HTTP::host] $::urlrewrite " "]
        if {$entry != ""} {
            log "Entry not null, replacing Host: [HTTP::host] with: $entry"
            HTTP::header replace Host $entry
        }
    }

  • Hi,

     

     

    I have had to revisit this solution after some delays in testing and shifting priorities. The iRule above worked very well to swap the host in the HTTP header but our proxies need a different format.

     

     

     

    Our vendor partners will connect to our BigIPs using

     

     

    https://sitename1.externaldomain.net/VendorSite

     

     

    We are terminating ssl (and not re-encrypting) on the bigips and need an iRule to rewrite the URL to change the host name to the internal host name.

     

     

    We need to present the fqdn to the netcache proxy servers.

     

     

    So for every get

     

     

    https://sitename1.externaldomain.net/VendorSite

     

     

    We need to translate the url and present the following to the proxy

     

     

    https://sitename2.internaldomain.net/VendorSite

     

     

     

    Most of the examples of URL rewrite are load balancing web servers.. which can handle the GET /foo with a host header field with no problem… but since we need to forward to a proxy server.. I will need a different rule. Can you please help?

     

     

    Our Proxy servers don’t handle the following GET very well..

     

     

    GET /VendorSite HTTP/1.1\r\n

     

    Request Method: GET

     

    Request URI: /VendorSite

     

    Request Version: HTTP/1.1

     

    Accept: */*\r\n

     

    Accept-Language: en-us\r\n

     

    Accept-Encoding: gzip, deflate\r\n

     

    User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; InfoPath.1; .NET CLR 1.0.3705; .NET CLR 1.1.4322; .NET CLR 2.0.50727)\r\n

     

    Host: sitename2.internaldomain.net\r\n

     

    Connection: Keep-Alive\r\n

     

    \r\n

     

     

     

    They are expecting

     

     

    GET https://sitename2.internaldomain.net/VendorSite

     

     

     

    John

     

     

  • We modified our iRule to prepend the protocol and fqdn.

    
    when HTTP_REQUEST {
        set entry [findclass [HTTP::host] $::urlrewrite " "]
        if {$entry != ""} {
            log "Entry not null, replacing Host: [HTTP::host] with: $entry"
            HTTP::header replace Host $entry
    if {[HTTP::uri] starts_with "/"} {
    HTTP::uri http://$entry[HTTP::uri]
    }
        }
    }
    

    This works to rewrite the inbound traffic. Our internal server returns a 301 with the internal host name... so we'll need to address the response.
  • Our application was sending a 301 redirect back to the client with our internal url…

    The iRule below addresses the 301 problem, by replacing the location if there is a 301 with the original host set in the request.

    The tool I was using to test didn’t show the 301, (perhaps because the location host was the same as that originally requested) but the browser did go to the proper page.

    
    
    when HTTP_REQUEST {
    
      set myhost [HTTP::host]
    
      set entry [findclass [HTTP::host] $::urlrewrite " "]
    
      if {$entry != ""} {
    
        log "Entry not null, replacing Host: [HTTP::host] with: $entry"
    
        HTTP::header replace Host $entry
    
        if {[HTTP::uri] starts_with "/"} {
    
          HTTP::uri http://$entry[HTTP::uri]
    
        }
    
      }
    
    }
    
    when HTTP_RESPONSE {
    
      if {[HTTP::status] contains "301"} {
    
        if {$myhost != ""} {
    
          set myuri [findstr [HTTP::header Location] ".com/" 5]
    
          HTTP::header replace Location https://$myhost/$myuri
    
        }
    
      }
    
    }
    
    

    Now we just need to get the rule implemented in production and tested with our vendors.

    John