Forum Discussion

Joseph_Lindsly's avatar
Sep 06, 2016

HTTP reverse proxy irule help

I currently have an irule that redirects a specific URI to a third party site while rewriting the headers to keep the original URL in the address bar. Currently, the URIs are required to match between what the users types in and what is at the third party site. For example, www.abc.com/jobs/ ==> www.xyz.com/jobs/.

I now have a request to perform a similar redirect but the URIs don't match. www.abc.com/en-gb/jobs ==> www.xyz.com/en-gb.

I am looking for assistance in modifying my existing irule to make the new request work.

Here is an example of my current irule:

when CLIENT_ACCEPTED {
     Store the default pool name 
    set default_pool [LB::server pool]
}

when HTTP_REQUEST {
  if { ([HTTP::uri] starts_with "/jobs")} {
    HTTP::header replace Host "www.xyz.com"
    set host [HTTP::host]
    log local0. "client [IP::client_addr]:[TCP::client_port] server [IP::remote_addr]:[TCP::release] host $host"
    log local0. "URI: [HTTP::uri]"
    set dest [lindex [RESOLV::lookup @208.67.222.222 -a [HTTP::host]] 0]
    if { $dest ne "https://www.xyz.com" } {
         SSL::enable clientside
      log local0. "Destination IP is $dest"
      node $dest
    }
  } else {
   log local0. "-->[HTTP::uri] $default_pool"
     pool $default_pool
  }
}

when HTTP_RESPONSE {
  if {[HTTP::header exists Location]} {
    set location [HTTP::header Location] 
    set locationrewrite [string map { www.xyz.com www.abc.com } $location]
    HTTP::header replace Location $locationrewrite
  }
  STREAM::expression "@www.xyz.com@www.abc.com@"
  STREAM::enable
}

Thanks

3 Replies

  • I have trouble to understand this part:

        set dest [lindex [RESOLV::lookup @208.67.222.222 -a [HTTP::host]] 0]
        if { $dest ne "https://www.xyz.com" } {
             SSL::enable clientside
          log local0. "Destination IP is $dest"
          node $dest
        }        
    

    How would this lookup ever resolve to https://www.xyz.com? The lookup would return an ip address.

  • The third party hosted site is located within AWS and has many IP addresses, so I had to use the URL of the third party site. The F5 isn't going to know how to get there unless it resolves the URL to an IP address and then it will be able to route the traffic to the third party site.

     

  • Hi Joseph,

    you may use the iRule below as a starting point...

    when CLIENT_ACCEPTED {
         Store the default pool name 
        set default_pool [LB::server pool]
        set orig_hostname "www.abc.com"
        set orig_base_uri "/en-gb/jobs"
        set new_hostname "www.xyz.com"
        set new_base_uri "/en-gb"
    
    }
    when HTTP_REQUEST {
        if { [string tolower [HTTP::path]] starts_with $orig_base_uri } then {
            HTTP::header replace Host $new_hostname
            if { [set dest [lindex [RESOLV::lookup @208.67.222.222 -a [HTTP::host]] 0]] ne "" } then {
                node $dest
                set rewrite_enabled 1
            } else {
                HTTP::redirect "/dns-error.html"
                set rewrite_enabled 0
            }
        } else {
            pool $default_pool
            set rewrite_enabled 0
        }
        STREAM::disable
    }
    
    when HTTP_RESPONSE {
        if { $rewrite_enabled } then {
            if { [set location [HTTP::header value "Location"]] ne "" } then {
                HTTP::header replace "Location" [string map [list $orig_hostname $new_hostname $orig_base_uri $new_base_uri] $location]
            }
            STREAM::expression "@$orig_hostname@$new_hostname@@$orig_base_uri@$new_base_uri@"
            STREAM::enable
        }
    }
    

    Note: I've streamlined some parts of the original iRule and also remove some parts which may cause trouble.

    Note: Make sure to use a ONECONNECT profile on your Virtual Server to switch the

    [node]
    /
    [pool]
    on each request. Also make sure to use a COMPRESSION profile on your Virtual Server with "Keep Accept Encoding" option DISABLED.

    Cheers, Kai