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

Brian_H__Jones_'s avatar
Brian_H__Jones_
Icon for Nimbostratus rankNimbostratus
May 16, 2014

Irule for Load-Balancing Host Headers and Redirects

I have a customer that is moving to my F5, from a CSS. It's a migration, and the way the CSS is configured, I do not want to simply convert the rules from the CSS over the F5 as there were a lot of wasted IP addressing for all the different host headers that they used. I want to be able to use one VIP for http to deal with all the host headers and one VIP for https. So far, I don't believe I can do redirect to https the way the script is currently written. Here is the script:

class int_host_map { { "test.company-a.com" { server-pool-a } "test.company-b.com" { server-pool-b } "test.company-c.com" { server-pool-a } } } class int_redirect_map { { "test.company-a.com" { "test.company-a.com\testurl\login.jsp" } } }

rule internal_lb { when HTTP_REQUEST { Get URI from request set hostName [string tolower [HTTP::host]

   Select Pool from Data Class
  set poolName  "[class match -value -- $hostName starts_with int_host_map]

  if { [HTTP::uri] equals "/" } {
     set redirectTarget [class lookup $hostName int_redirect_map]
     if { $redirectTarget ne "" } {
        HTTP::redirect $redirectTarget
        return
     }
  } 

   Assign to pool if not found show 404 error
  if { $poolName ne "" } {
pool $poolName
  } else {
 log -noname local0.warn "URL: $hostName from: [IP::remote_addr] not found in int_host_map!"
     HTTP::respond 404 content {
        
          Not found
        
           Not found
           The requested page or resource was not found.
              
  }   

} }

I am hoping that the following will be completed for the script:

1.) When a request comes in for company-a, it will redirect, then come back through the script and assign it to server-pool-a 2.) For company-b, when the request comes in, the pool selected would be server-pool-b 3.) For company-c, when the request comes in, the pool selected would be server-pool-a 4.) For all other conditions, return a 404 and log it to the LTM Log.

If there are any suggestions on how to do the http to https redirect within the same irule, I would appreciate any suggestions.

5 Replies

  • class int_host_map { { "test.company-a.com" { pool-company-a } "test.company-b.com" { pool-company-b } "test.company-c.com" { pool-company-c } } } class int_redirect_map { { "test.company-a.com" { "test.company-a.com\testurl\login.jsp" } } } rule internal_lb { when HTTP_REQUEST { Get URI from request set hostName [string tolower [HTTP::host] Select Pool from Data Class set poolName "[class match -value -- $hostName starts_with int_host_map] if { [HTTP::uri] equals "/" } { set redirectTarget [class lookup $hostName int_redirect_map] if { $redirectTarget ne "" } { HTTP::redirect $redirectTarget return } } Assign to pool if not found show 404 error if { $poolName ne "" } { pool $poolName } else { log -noname local0.warn "URL: $hostName from: [IP::remote_addr] not found in int_host_map!" HTTP::respond 404 content { Not found

     

    Not found

     

     

    The requested page or resource was not found.

     

    } } }
  • You should be able to significantly simplify this code:

     

    int_host_map datagroup:

     

    class int_host_map {
        {
            "test.company-a.com"  {  pool-company-a  }
            "test.company-b.com"  {  pool-company-b  }
            "test.company-c.com"  {  pool-company-c  }
        }
    }

    int_redirect_map datagroup:

     

    class int_redirect_map {
        {
            "test.company-a.com"  { "/testurl/login.jsp" }
        }
    }

    iRule:

     

    when HTTP_REQUEST {
        if { ( [HTTP::uri] equals "/" ) and ( [class match [string tolower [HTTP::host]] equals int_redirect_map] ) } {
            HTTP::redirect "http://[HTTP::host][class match -value [string tolower [HTTP::host]] equals int_redirect_map]"
        } elseif { [class match [string tolower [HTTP::host]] equals int_host_map] } {
            pool [class match -value [string tolower [HTTP::host]] equals int_host_map]
        } else {
            HTTP::respond 404 content "...data..."
        }
    }

    This doesn't exactly meet your HTTP-to-HTTPS requirement though, and not 100% sure I understand what you're trying to do. If you want to redirect all HTTP to HTTPS, then you'd put a very simply redirect iRule on an HTTP VIP, and then use all of the above iRule logic on the HTTPS VIP.

     

  • Thanks for the response. As far as the HTTP-to-HTTPS requirement, typically you set up two VIPS, one on HTTP and one on HTTPS and just do a simple redirect on the HTTP VIP. This assumes that all the host headers are https for the IP address, which is not the case for me. So on the same CSS configuration, I have some host headers that are https and some that are only http, so what I am trying to figure out is how to put in a "selective" https redirect for the https host headers only.

     

  • I'd probably use a data group to define what Hosts need to be HTTP vs. HTTPS.

    HTTP VIP iRule:

    when HTTP_REQUEST {
        if { [class match [string tolower [HTTP::host]] equals my_https_dg] } {
            HTTP::redirect "https://[HTTP::host][HTTP::uri]"
        } elseif { ( [HTTP::uri] equals "/" ) and ( [class match [string tolower [HTTP::host]] equals int_redirect_map] ) } {
            HTTP::redirect "http://[HTTP::host][class match -value [string tolower [HTTP::host]] equals int_redirect_map]"
        } elseif { [class match [string tolower [HTTP::host]] equals int_host_map] } {
            pool [class match -value [string tolower [HTTP::host]] equals int_host_map]
        } else {
            HTTP::respond 404 content "...data..."
        }
    }
    

    where "my_https_dg" is a string-based data group containing all of the host names that have to be HTTPS.

    HTTPS VIP:

    when HTTP_REQUEST {
        if { ( [HTTP::uri] equals "/" ) and ( [class match [string tolower [HTTP::host]] equals int_redirect_map] ) } {
            HTTP::redirect "https://[HTTP::host][class match -value [string tolower [HTTP::host]] equals int_redirect_map]"
        } elseif { [class match [string tolower [HTTP::host]] equals int_host_map] } {
            pool [class match -value [string tolower [HTTP::host]] equals int_host_map]
        } else {
            HTTP::respond 404 content "...data..."
        }
    }