Forum Discussion

Casey_Parman_24's avatar
Casey_Parman_24
Icon for Nimbostratus rankNimbostratus
Jan 11, 2016

iRule https redirection

Hello all, I'm new to the f5 world and I'm looking to create an irule for an HTTPS redirection. The main problem that I'm having is that three different FQDN's are used for the same site and redirection will be different depending on the uri.

 

Lets say the tree sites are abc.com iabc.com mabc.com

 

What needs to happen is when they go to abc.com iabc.com or mabc.com they need to be redirected to https://abc.com/foo, but if they're going to http://abc.com/foo/bar they would need to be redirected to the uri. https://abc.com/foo/bar or http://abc.com/foo/bar/foo needs to be redirected to https://abc.om/foo/bar/foo.

 

Overall, if the user is navigating to the FQDN they need to be redirected to a specific uri (parent uri) once they're past that redirection only need to occur from http to https.

 

Thanks

 

15 Replies

  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    Just assign this rule to the VIP for port 80. You won't need a pool.

     Permanently redirect HTTP to HTTPS
    
    when HTTP_REQUEST {
    
        HTTP::respond 301 Location "https://[HTTP::host][HTTP::uri]"
    
    }
    
  • You could probably use a Local Traffic Policy to do this (assuming you are on BIG-IP v11.4 or newer), depending on whether or not other traffic (besides the three FQDNs) are processed by the same virtual server. Local Traffic Policies are almost always more efficient than iRules, although they don't have all of the same capabilities as iRules. Thankfully, HTTP to HTTPS redirects are something they can do.

     

    Your local traffic policy will have a matching strategy of "First Match" and will require http. (See https://support.f5.com/kb/en-us/solutions/public/14000/900/sol14996.html for a similar example.) You will need two rules: One to handle the case where the URI starts with "/foo" and one where it doesn't.

     

    For the case where the URI starts with "/foo" your condition will probably look something like this...

     

    Operand: http-uri Event: request Selector: all Condition: starts-with Value: /foo

     

    ...and your action will probably look something like this:

     

    Target: http-reply Event: request Action: redirect Parameters: location Value: https://abc.com[HTTP::uri]

     

    For the case where the URI does not start with "/foo" your condition will probably look something like this...

     

    Operand: http-uri Event: request Selector: all Negate: (checked) Condition: starts-with Value: /foo

     

    ...and your action will probably look something like this:

     

    Target: http-reply Event: request Action: redirect Parameters: location Value: https://abc.com/foo[HTTP::uri]

     

    Apply the policy to the virtual server configuration on the Resources tab in the Policies section.

     

    No guarantees since I am not able to test the complete solution here, but I was able to log what the redirects looked like.

     

    When connecting using the redirect is to https://abc.com/foo/ When connecting using http://anyhost.com/foo/bar/foo, the redirect is to https://abc.com/foo/bar/foo

     

    Hopefully this is what you wanted.

     

  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    I'm afraid I overlooked the requirement for the handling of the home page. Here's the updated rule:

     Permanently redirect HTTP to HTTPS
     Redirect requests for the home page to /foo/ (retaining query string if present)
    
    when HTTP_REQUEST {
    
        if { [HTTP::path] eq "/" || [string tolower [HTTP::path]] eq "/index.php" } {
    
            HTTP::respond 301 Location "https://[HTTP::host]/foo[HTTP::uri]"
    
        } else 
    
            HTTP::respond 301 Location "https://[HTTP::host][HTTP::uri]"
    
        }
    
    }
    

    You'll want to make sure

    index.php
    is replaced with the proper default page name for the home page.

    However, is there a good reason to redirect the home page? Wouldn't it be better to keep the URL for the root the same while serving

    /foo/
    ?

    By the way, crodriguez's solution is also worth considering, although I'm personally a bit hesitant about the increased complexity that's introduced with you deploy an LTP (mainly because it tends to become harder to troubleshoot).

  • I'm currently running BIG-IP 11.5.1, I will look into Local Traffic Polices and let you know.

     

    Thanks!

     

    • Arie's avatar
      Arie
      Icon for Altostratus rankAltostratus
      Sure, but that doesn't mean that /foo/ has to be part of the path (URL). You can remap the root to simply show the contents of /foo/ without changing the URL in the browser.
    • Casey_Parman_24's avatar
      Casey_Parman_24
      Icon for Nimbostratus rankNimbostratus
      this is when in said "oh"... please continue... All of our applications are like this and if they could be accessible easier I'm all ears.
  • Arie's avatar
    Arie
    Icon for Altostratus rankAltostratus

    You can change the request to the Origin Web Servers independent of the request from the client. To accomplish this you would can use HTTP::uri to change the request before it is handed to the back-end.

    In your case you would end up with something like this:

    HTTP::uri "/foo[HTTP::uri]"
    

    However, since you are also required to force all traffic from port 80 to 443 you'll have to use a two-tier approach:

    1. Force all traffic to HTTPS. (on the VIP for port 80)
    2. Rewrite requests to the home page to include /foo/ (on the VIP for port 443)

    Rule for Port 80 VIP:

     Permanently redirect HTTP to HTTPS
    
        when HTTP_REQUEST {
    
            HTTP::respond 301 Location "https://[HTTP::host][HTTP::uri]"
    
        }
    

    Rule for Port 443 VIP:

     Rewrite requests for the home page to /foo/ (to the OWS only - no change to client URL)
    
    when HTTP_REQUEST {
    
        if { [HTTP::path] eq "/" || [string tolower [HTTP::path]] eq "/index.php" } {
    
            HTTP::uri "/foo[HTTP::uri]"
    
        } 
    
    }
    

    Depending on the way the links are constructed on the resources on the OWS (HTML, JS, CSS, etc.) you may need to tweak this a bit to accommodate your specific situation.

  • Even Stranger,

     

    So I did two different curl request to the https version of the website.

     

    [root@F5:Active:Standalone] config nfig curl -iv https://abc.com - -insecure * About to connect() to abc.com port 443 (0) * Trying IP... connected * Connected to abc.com (IP) port 443 (0) * successfully set certificate verify locations: * CAfile: /etc/pki/tls/certs/ca-bundle.crt CApath: none * SSLv3, TLS handshake, Client hello (1): * SSLv3, TLS handshake, Server hello (2): * SSLv3, TLS handshake, CERT (11): * SSLv3, TLS handshake, Server finished (14): * SSLv3, TLS handshake, Client key exchange (16): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSLv3, TLS change cipher, Client hello (1): * SSLv3, TLS handshake, Finished (20): * SSL connection using AES256-SHA256 * Server certificate:

     

    GET / HTTP/1.1 User-Agent: curl/7.19.7 (x86_64-redhat-linux-gnu) libcurl/7.19.7 OpenSSL/1.0.1 e zlib/1.2.3 libidn/0.6.5 Host: abc.com Accept: /

     

    • SSL read: error:00000000:lib(0):func(0):reason(0), errno 104
    • Closing connection 0

    The next time, i get expected results, but in the chrome browser, https://abc.com is still taking me to a blank page. When I try IE 11 it works without any problems. Then a few minutes later its back to taking me to the F5. at https://abc.com/tmui/login.jsp

     

    F5 is strange.

     

    • Casey_Parman_24's avatar
      Casey_Parman_24
      Icon for Nimbostratus rankNimbostratus
      Also if i browse to the specific /foo then i get Object not found until I remove the iRule.
    • Arie's avatar
      Arie
      Icon for Altostratus rankAltostratus
      Can you try accessing the home page from a fresh incognito/private browser window (make sure you close any open incognito/private instances first). By the way, "curl -I https://abc.com" would give you less noise in the output. Lastly, if you still don't get satisfactory results I'd try the rewrite on port 80 first. Once it's working you can move it to 443.
    • Arie's avatar
      Arie
      Icon for Altostratus rankAltostratus
      Dev mode in the browser might give you some clues also. Or use Fiddler to monitor what's happening (HTTP headers mainly).