Forum Discussion

RobS's avatar
RobS
Icon for Altostratus rankAltostratus
Jan 22, 2014

HTTP to HTTPS policy injecting "/Location: https:///" into URL and breaking application

We have an application I'm load balancing with my LTMs that I was initially told would just need basic load balancing and http to https redirection. Now I find out they are running it out of Citrix so they can use single signon for multiple apps and when they go to a different app it then makes a request to this one and then fails. If I disable the http-https it works in http or https. When enabled it fails trying to go to the URL: https://myapp.domain.com/Location:%20https:///ibex1h.ibx?acctnum=9248789&medrec=T01275160&cibex=&pid=&ssn=Server and I think the https rewrite is somehow inserting the "Location:%20https:///" which I don't want. I think the path should be: https://myapp.domain.com/ibex1h.ibx?acctnum=9248789&medrec=T01275160&cibex=&pid=&ssn=Server and would work. If anyone has any suggestions on how to prevent this or delete "Location:%20https:///" I'd greatly appreciate the help! The right answer would be for the application owner to alter the request they are making but in this environment it is not going to happen and I need to resolve with the LTM.

 

10 Replies

  • Are you using the default, or a generic HTTP-to-HTTPS redirect iRule? If so, do you by chance have that iRule applied to HTTPS VIP? "Location" is generally the header name used in an HTTP 30x redirect. Can you elaborate on your configuration?

     

  • Right, so assuming this is applied to the HTTP VIP, and is working there, do you also have it applied to the HTTPS VIP?

     

  • If you don't, let's level set with something we know should work. Instead of the policy applied to the HTTP VIP, apply the built-in _sys_https_redirect iRule and see what that does. It provides the same functionality, but in iRule form. This is just on the HTTP VIP, with no pool applied.

     

  • Interesting. In the absence of any other influences, the iRule (and most probably the policy) would not be inserting anything into the redirect URI that wasn't in the original URI. So that leads me to believe there are other influences at play. Do you have any other iRules applied to the HTTP and/or HTTPS VIPs? Can you run a client side traffic analyzer like Fiddler or HTTPWatch to see where the "Location" string is introduced into the URI? Can you also capture on the server side, traffic coming directly from the web server, to see if the Location string is coming from there?

     

  • Well, let's back up and talk about how this should work.

    1. With the HTTP-HTTPS iRule applied to the HTTP VIP, a user might navigate to:

      http://myapp.domain.com/ibex1h.ibx?acctnum=9248789&medrec=T01275160&cibex=&pid=&ssn=Server
      

      which hits the HTTP VIP, which issues an immediate redirect to:

      https://myapp.domain.com/ibex1h.ibx?acctnum=9248789&medrec=T01275160&cibex=&pid=&ssn=Server
      
    2. That redirect sends the user to the HTTPS VIP, where the application request is served.

    The really weird thing is the "Location:%20https://" string in the URI, which is what you would normally find in the header of a redirect. Example:

    HTTP/1.0 302 Found
    Location: https://something...
    ...
    

    So I'd suspect something is either intercepting/mangling the HTTP-HTTPS redirect, or this is coming from the application. So let me ask this. From a sequence perspective, when does the client try to make this goofy request, given the following flow:

  • Very interesting. This iRule would suggest that it's being used on multiple VIPs, because otherwise all requests on a port 80 only VIP would satisfy the "[TCP::local_port] == 80" requirement.

    Just as a test, add some log statements into your HTTP-HTTPS iRule like this:

    when HTTP_REQUEST {
        log local0. [HTTP::host]
        log local0. [getfield [HTTP::host] : 1]
        log local0. [HTTP::uri]
        HTTP::respond 302 Location "https://[getfield [HTTP::host] : 1][HTTP::uri]"
    }
    
  • Is there any chance that the client used to make this call isn't a standard browser? Even with an HTTP/1.0 request, most browsers would insert a Host header (though not expressly required). Maybe something like this might help:

     

    when HTTP_REQUEST {
        set host [HTTP::host]
        if { $host eq "" } {
            set host "myapp.domain.com"
        }
        HTTP::respond 302 Location "https://$host[HTTP::uri]"
    }

    It'll hard code the Host value if it doesn't exist in the request.

     

  • Okay, one more idea. Try to capture the HTTP redirect response on the wire from the HTTP VIP.

    tcpdump -lnni 0.0 -Xs0 port 80
    

    You may need to add some additional filters to clean up the capture, but the -Xs0 option will show you the clear text HTTP payload in the HTTP response from the HTTP VIP. What you're specifically looking for is the HTTP/1.x 302 Found message and following Location header. What you find here will determine WHO is actually sending this funky URL.

  • That might just work. Going back to the original HTTP-HTTPS redirect code, when the URI looked like this:

     

    /Location:%20https:///ibex1h.ibx?acctnum=9248789&medrec=T01275160&cibex=&pid=&ssn=Server:%20BigIPConnection:%20closeContent-Length:%200

    You could do something like this in your HTTPS VIP:

     

    when HTTP_REQUEST {
        if { [HTTP::uri] starts_with "/Location:" } {
            HTTP::uri [findstr [HTTP::uri] "///" 2]
        }
    }

    This will extract all of the URI string after the "///", but leave one "/" behind.

     

  • RobS's avatar
    RobS
    Icon for Altostratus rankAltostratus

    Hi Kevin,

    Wanted to say thanks again for your help and guidance. I fought with this and ended up decrypting some captures to get an idea of what was going on. My final solution that seems to work is:

     when HTTP_REQUEST {
        if { [HTTP::uri] starts_with "/Location:" } {
             set fixuri [findstr [HTTP::uri] "/Location" 13 ]
             HTTP::redirect https://[HTTP::host]/$fixuri
        }
    }
    

    Thanks, Rob