Forum Discussion

Raj_57800's avatar
Raj_57800
Icon for Nimbostratus rankNimbostratus
Nov 24, 2008

iRule for Http redirect

I have defined a irule to forward http request to be converted as https. But when any https request to the same server is not being forwarded. This is the irule

 

 

when HTTP_REQUEST {

 

if {[TCP::local_port] == 80} {

 

HTTP::redirect https://xxx.com } {

 

else {

 

HTTP::fallback "https://xxx.com

 

}

 

}

 

 

Can anyone help me in finding the correct irule

 

raj

7 Replies

  • Hi Raj,

    If you have an 'any port' virtual server that can receive HTTP and HTTPS traffic you can add a client SSL profile and then disable it for requests to an HTTPS port. Assuming you have a pool defined on port 0 (any), you can use a rule like this:

     
     when CLIENT_ACCEPTED { 
      
         Check the requested port 
        switch [TCP::local_port] { 
           80 { 
               HTTP request, redirect to HTTPS using the same URI 
      
               Check if Host header value has a length 
              if {[string length [HTTP::host]]}{ 
      
                  Redirect to the requested host and URI (minus the port if specified) 
                 HTTP::redirect https://[getfield [HTTP::host] ":" 1][HTTP::uri] 
      
              } else { 
      
                  Redirect to VIP's IP address 
                 HTTP::redirect https://[IP::local_addr][HTTP::uri] 
              } 
           } 
           443 { 
               HTTPS request.  Disable client SSL profile to prevent decryption 
              SSL::disable 
           } 
           default { 
               Request to undefined port.  Take some default action? 
      
       Send a reset? 
               reject 
      
       Drop the request? 
               drop 
           } 
        } 
     } 
     

    If this doesn't work as you'd expect for your scenario, you can add debug logging to determine what's happening.

    Aaron
  • But why is that when my if statement is not true the traffic is not being diverted to a specific pool.

     

     

    when HTTP_REQUEST {

     

    if {[TCP::local_port] == 80} {

     

    HTTP::redirect https://xxx.com } {

     

    else {

     

    pool test_pool

     

    }

     

    }

     

  • What port is your VIP defined on? Does your VIP have a client and/or server SSL profile? Is the client making an HTTPS request? Is the server expecting SSL or non-SSL traffic?

     

     

    If the client makes a request to the VIP on a port other than port 80, the traffic should be sent to the test_pool using your last rule.

     

     

    Is this failing? If so, what is happening? If you run tcpdump on interface 0.0 filtering on the client or pool members' IP addresses, do you see packets going to/from the pool members?

     

     

    You can use a tcpdump command like this to look for the traffic:

     

     

    tcpdump -ni 0.0 -Xs0 host CLIENT_IP or host POOL_MEMBER1_IP or host POOL_MEMBER2_IP

     

     

    Aaron
  • The VIP has a wildcard port enable(all ports) and there is no ssl enabled on it. The SSL is provided by the pool memeber.

     

     

    My redirect works but when its a rirect URL with https its not being forwarded to the default pool. I am able to see the packet hitting the VIP but not the pool member.

     

     

    When I remove the irule my https works good.

     

     

    Need help on my its not falling back to the default pool and do I need to make any specific config.
  •   
      when HTTP_REQUEST {  
         if {[TCP::local_port] == 80} {  
           HTTP::redirect https://xxx.com } {  
          else {  
             pool test_pool  
          }  
      }   
     

    This iRule won't work for HTTPS since you didn't specify a Client SSL profile. You cannot use when HTTP_REQUEST for HTTPS request in this case.

    you should then do something like this:

      
      when CLIENT_ACCEPTED {  
         if {[TCP::local_port] == 443} {  
           HTTP::disable   
           pool test_pool    
         }   
      }   
        
      when HTTP_REQUEST {  
         if {[TCP::local_port] == 80} {  
           HTTP::redirect https://xxx.com   
         }   
      }   
     
  • You could consider changing the HTTP_REQUEST check to either send a redirect to https for all ports or add an else statement. As it is, if you added a default pool to the VIP and the request wasn't on 80 or 443 clients could access any other port on the default pool.

     
       when CLIENT_ACCEPTED {   
          if {[TCP::local_port] == 443} {   
            HTTP::disable    
            pool test_pool     
          }    
       }    
          
       when HTTP_REQUEST {   
          if {[TCP::local_port] == 80} {   
            HTTP::redirect https://xxx.com    
          } else {   
              Reject the request 
             reject 
          }    
       } 
     

    Aaron