Forum Discussion

Joseph_Lindsly's avatar
Jan 25, 2016

Current reverse proxy irule having issues with the third party hosted site

I currently have a client requirement to reverse proxy specific URI traffic to a third party hosted site while the rest of the traffic is sent to our local datacenter servers. Also, the URL in the address bar must show our address instead of the third party URL. The below irule is working for the most part, but after further testing, we ran into this issue.

If i go to www.abc.com/it-jobs/login, the irule will redirect the traffic to the third party site. If i replace the /it-jobs/login with /testimonials, it should take me back to the local datacenter servers, but i get a 404 error and the third party site is seeing the errors on their side. If i open a new browser and go directly to https://www.abc.com/testimonials, it works every time. If I go to https://www.abc.com/it-jobs/login, i get redirected to the correct page on the third party site. If i replace the /it-jobs/login with /testimonials, i get the 404 error. The third party site is pointing to the reverse proxy irule but i can't see anything in the irule that would create that symptom.

Any help would be appreciated.

Thanks

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

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

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
}

1 Reply

  • Hi Joseph,

     

    your iRule covers already a lot of areas to translate the request and responses to/from the 3rd party site. Good job so far!

     

    I can name just a very few things that are left out...

     

    • Translate Referer information send to the 3rd party site.
    • Translate cookie domains send from the 3rd party site.

    But those things shouldn't create a server side redirect, that could bypass your Location header rewrite? Maybe a HTML / JScript based redirect on the client side?

     

    Anyhow, I've reworked a little your iRule to cover the additional rewrites, removed some death code and added some performance related things. The optimized iRule would look like this...

     

    when HTTP_REQUEST {
        if { ([HTTP::uri] starts_with "/it-jobs/")} {
            set www_xyz_com 1
            HTTP::header replace Host "www.xyz.com"
            if { [HTTP::header exists Referer] } then {
                HTTP::header replace Referer [string map -nocase { www.abc.com www.xyz.com } [HTTP::header value Referer]]
            }
            if { [set node [table lookup -notouch "DNS_www_xyz_com"]] eq "" } then {
                if { [set node [lindex [RESOLV::lookup @8.8.8.8 -a "www.xyz.com"] 0]]] ne "" } then {
                    table add "DNS_www_xyz_com" $ip_www_xyz_com indef 300
                } else {
                    HTTP::redirect "/errorpage_www_xyz_com_unreachable.htm
                    TCP::close
                    return
                }
            }
            node $ip_www_xyz_com
        }
    }
    when HTTP_RESPONSE {
        if { $www_xyz_com } then {
            if { [HTTP::header exists Location] } then {
                HTTP::header replace Location [string map -nocase { www.xyz.com www.abc.com } [HTTP::header value Location]]
            }
            if { [HTTP::header count Set-Cookie] == 1 } then {
                HTTP::header replace Set-Cookie [string map -nocase { www.xyz.com www.abc.com } [HTTP::header value Set-Cookie]]
            } elseif { [HTTP::header count Set-Cookie] > 1 } then {
                set cookies [string map -nocase { domain=www.xyz.com domain=www.abc.com domain=.xyz.com domain=.abc.com} [HTTP::header values Set-Cookie]]
                HTTP::header remove Set-Cookie
                foreach cookie $cookies {
                    HTTP::header insert Set-Cookie $cookie
                }
            }
            if { [HTTP::header value Content-Type] starts_with "text" } then {
                  STREAM::expression "@www.xyz.com@www.abc.com@"
                  STREAM::enable
            } else {
                STREAM::disable
            }
        }
    }

    If those changes are not working out for you, you may want to install Fiddler or HTTP-Watch to find the differences in the HTTP requests, HTTP responses and related HTML and JScript contents. There must be one!

     

    Cheers, Kai