For more information regarding the security incident at F5, the actions we are taking to address it, and our ongoing efforts to protect our customers, click here.

Forum Discussion

murali_125469's avatar
murali_125469
Icon for Nimbostratus rankNimbostratus
Oct 22, 2013

HTTP rewrite with uri modification

Hello everyone !! I am fairly new to irules and below is my client requirement.

we have multiple websites like portal.ourcompany.com , sites.ourcompany.com , extranet.ourcompany.com etc now as the company name has changed so now we have new websites like portal.newcompany.com , sites.newcompany.com , extranet.newcompany.com.

our requirement is whenever client enters the old urls and any uri along with it (users saved in browser favorites) like

http://portal.ourcompany.com/path/it/docs it should redirect to "http://redirect.ourcompany.com/home.html?u=portal.ourcompany.com/path/it/docs" i tried one irule and it worked but client requirement is like redirection should be transparent so browser shouldn't change the url.

http://redirect.ourcompany.com/home.html will display a message that urls has been changed and will provide a link to new url

Also if user enters https://portal.ourcompany.com/path/it/docs it should do the same thing as above (no https) i.e it should change as http://redirect.ourcompany.com/home.html?u=portal.ourcompany.com/path/it/docs

i dont have a VIP configured for redirect.ourcompany.com not sure if required.

i am thinking of below irule for at least one url to test with could anyone check and let me know if that works ......many thanks in advance !!

when RULE_INIT { set static::aportal "aportal.csmcosmos.com" set static::aredirector "aredirector.csmcosmos.com" } when HTTP_REQUEST {

       HTTP::query "?u=[HTTP::host][HTTP::uri]"
       HTTP::uri "/home.html"                       
       HTTP::header replace Host $static::aredirector     

} when HTTP_RESPONSE { if { [string tolower [HTTP::header "Location"]] contains $static::aredirector} { HTTP::header replace Location [string map "$static::aredirector $static::aportal" [HTTP::header Location]]

}

}

10 Replies

  • Ultimately, if you don't want the URI to change, then you can't issue a redirect. Here's a thought.

    1. Create a new pool for the redirector server instance.

    2. Use an iRule like this on both HTTP and HTTPS VIPs:

      when HTTP_REQUEST {    
          if { [string tolower [HTTP::host]] ends_with ".ourcompany.com" } {        
              HTTP::uri "/home.html?u=[HTTP::host][HTTP::uri]"                
              pool redirector_pool
          }
      }        
      

    With this you can host .newcompany.com and .ourcompany.com sites on the same VIPs and send the .ourcompany.com requests to the redirector pool (with the new URI). You could also technically host this content within the iRule.

  • We have same server in the pool hosting multiple websites

     

    Does that mean you're doing host header redirection at the web server? How do you separate and send the requests to their respective websites? Is redirect.ourcompany.com a separate website on the same server?

     

  • For easier readability:

    when HTTP_REQUEST { 
        if { [string tolower [HTTP::host]] contains ".csmcosmos.com" } { 
            set hostname [HTTP::host] 
            HTTP::uri "/home.html?u=[HTTP::host][HTTP::uri]" 
            HTTP::header replace Host "aredirector.csmcosmos.com" 
            pool pool_sharepoint-uat 
        } 
    } 
    when HTTP_RESPONSE { 
        HTTP::header replace Location hostname 
    }
    

    If the websites are all hosted on the same server, you shouldn't need the pool command as that's defined in the VIP configuration. Also, your HTTP_RESPONSE event is sending a redirect header to the client to send it back to itself. So for example, if the request is for portal.csmcosmos.com/foo, the URI is changed to to /home.html?u=portal.csmcosmos.com/foo and the Host header is changed to aredirector.csmcosmos.com - which should go to the redirector website based on your host header redirect configuration on the web server. The response from that website will then trigger the insertion of a Location header that points to portal.csmcosmos.com, which probably won't do do anything because the response is a 200 and not a 301 message.

    Here's a minor modification of that iRule:

    when HTTP_REQUEST { 
        if { [string tolower [HTTP::host]] contains ".csmcosmos.com" } { 
            HTTP::uri "/home.html?u=[HTTP::host][HTTP::uri]" 
            HTTP::header replace Host "aredirector.csmcosmos.com" 
        } 
    }
    

    For any request that ends in csmcosmos.com, host header redirection on the web server should send the user to the redirector web site with the altered URI. It's then assumed that the links on that page will send the user to a new URL that does not end with csmcosmos.com.

    As for the HTTPS certificate warnings, if you're using a single VIP to host all URLs (old and new), the server certificate in the client SSL profile must either be a SAN (subject Alt Name) certificate, or be using SNI (server name indicator). Otherwise the client will get a mismatch warning when attempting to access a server by name that doesn't match the subject name presented in the server certificate.

  • will that above irule works transparently ? because client is not willing to publish the redirector website in dns.

    There is no physical redirect involved in this iRule. It is simply sending all traffic to the defined server pool with a different host header so that the web server can redirect the traffic (locally) to the correct website based on host header injection. The client will remain on the one URL.

    i've added http response to avoid dns lookup of redirector so while responding back to client it will be from aportal

    I see. The redirector website will respond with its own Host value and you want the client to see the originally-requested Host value. For that, re-add the set hostname [HTTP::host] line in the HTTP_REQUEST event, and then simply change the Host header in the HTTP_RESPONSE event.

    when HTTP_RESPONSE {
        if { [info exists hostname] } {
            HTTP::header replace Host $hostname
        }
    } 
    
  • also if i have to create another vip for old websites....what changes i need to do with regards to dns publishing and certificates

     

    If you create a separate VIP for the older websites, you're necessarily going to need the browser to see both URLs. For example, the client will request portal.csmcosmos.com and go to the older website VIP. The above iRule will change the Host header and URI and the web server should send the request (internally) to the redirector website. That website will, I assume, display a list of links for the new site. When the user clicks on one of these links, it must be able to resolve, via DNS, the corresponding VIP address, and then navigate to that (separate) VIP.

     

  • thank you very much so my code should be as below , i will try tomorrow and let you know. also if i want to implement new VIP for old sites with the same pool member do i need to map the vip to the dns and reverse proxy ? or shall i go for SAN certificate

     

    when HTTP_REQUEST {

     

    if { [string tolower [HTTP::host]] contains ".csmcosmos.com" } { 
        set hostname [HTTP::host]
        HTTP::uri "/home.html?u=[HTTP::host][HTTP::uri]" 
        HTTP::header replace Host "aredirector.csmcosmos.com" 
    } 

    }

     

    when HTTP_RESPONSE {

     

    if { [info exists hostname] } {
        HTTP::header replace Host $hostname
    }

    }

     

    • murali_125469's avatar
      murali_125469
      Icon for Nimbostratus rankNimbostratus
      hi kevin the above code is not working i got page can't be displayed , but when i add pool to the code and while http response mentioned location as original i am getting the redirection message but not the link to the new website :(
  • also if i want to implement new VIP for old sites with the same pool member do i need to map the vip to the dns and reverse proxy ? or shall i go for SAN certificate

     

    You'll have two VIPs with different IP addresses, so you'll need two DNS entries. You can use the same pool for both VIPs. As for the SAN certificate, that depends. Let's say that https://portal.ourcompany.com, https://sites.ourcompany.com, and https://extranet.ourcompany.com all resolve to the same VIP. That VIP will need either a SAN certificate, a wildcard certificate (ie. .ourcompany.com), or use SNI with three separate server certificates and client SSL profiles. You'll need to do the same thing on the new websites VIP.

     

  • the above code is not working i got page can't be displayed , but when i add pool to the code and while http response mentioned location as original i am getting the redirection message but not the link to the new website

     

    For any request to a host that ends with ".csmcosmos.com", the iRule will change the Host header and URI, and nothing more. It is up to the web server to send the request to the correct website based on the host name. The HTTP_RESPONSE event should simply change the Host header back as it flows to the client. Is that not what you need it to do?