Forum Discussion

Tom_185829's avatar
Tom_185829
Icon for Nimbostratus rankNimbostratus
Dec 09, 2015

LTM iRule recursive redirect

Hi I have virtual server configuration with : irule policy

Policy create select pool when you give a name for example: virtual server IP: 10.10.10.1 CNAME: app1.example.com to 10.10.10.1

For context(uri) i use data group file REDIRECTS with data: app1:=/app1 When you wrote in browser : irule redirect to https://app1.example.com/app1, but if it's only root context (/) then redirect to / location.

when HTTP_REQUEST {
 set HostName [getfield [HTTP::host] "." 1 ]
    if { [HTTP::uri] equals "/" } {
     set uri [class lookup ${HostName} REDIRECTS]
     if { ${uri} ne "" } {
       HTTP::respond 301 noserver Location "${uri}" Connection Close
       } else {
       HTTP::respond 301 noserver Location "https://${HostName}[HTTP::uri]" Conection Close
     }
     event disable all
     TCP::close
     return
   }
}

For some reaseon when application have only root context, when I am checking with curl command I have error: * Maximum (50) redirects followed curl: (47) Maximum (50) redirects followed

I run tcpdump and from server side I see, that server response ith page, but I have only in browser illegal redirect. I think it's something with iRule, but I don't know what. Could someone help me with this issue

Regards

8 Replies

  • Hi,

    the irule provided by Kai is right except the order of conditions:

    if uri equals /, it never executed the

    elseif { ${uri} eq "/" }
    because it entered in the first condition

    when HTTP_REQUEST {
        set HostName [getfield [HTTP::host] "." 1 ]
        if { [HTTP::uri] equals "/" } {
            set uri [class lookup ${HostName} REDIRECTS]
            if { ${uri} eq "/" } {
                allow request to root app if selected by class lookup
                return
            } elseif { ${uri} ne "" } {
                HTTP::respond 301 noserver Location "${uri}" Connection Close
                return
            } else {
                HTTP::respond 301 noserver Location "https://${HostName}[HTTP::uri]" Conection Close
                return
            }
            event disable all
            TCP::close
            return
       }
    
    }
    
  • Why are your redirecting to hostname without domain in the last else statement? in this redirect, the "https://${HostName}[HTTP::uri]" can be replaced by "https://${HostName}/" as it is inside the "if { [HTTP::uri] equals "/" }" condition
  • Hi Because first I have redirect from 80 to 443 and at virtual server 80 I am changing HostName to with domain
  • So if a user request http://mywebserver1, it will be redirected to https://mywebserver1.company.com/ as you describe. if the hostname Uri is / and mywebserver1 is not found in data group, it will be redirected to http://mywebserver1/ with a permanent (301) redirect... it will create another loop :)
  • I know, but I don't know how to prevent this situation. To be honest I still learn about F5 and I rules, form it seems OK. If you have solution I will be appreciated. Regards
  • Another issue is, when user request http://myweb the F5 redirect to https://myweb.company.com, but when user request https://myweb there is no redirect to FQDN, but only to https://myweb/blabla
  • Another issue is, when user request http://myweb the F5 redirect to https://myweb.company.com, but when user request https://myweb there is no redirect to FQDN, but only to https://myweb/blabla
  • To limit loop, you can apply the following irule to both http and https VS:

    when HTTP_REQUEST {
        set redirect 0
        set host [HTTP::host]
        set uri [HTTP::uri]
        set domain "company.com"    
        if { !($host contains ".")} {
             If domain is not set, append domain to host variable and force redirect
            set HostName $host
            set host "$host.$domain"
            set redirect 1
        } else {
            set HostName [getfield $host "." 1 ]
        }
        if { $uri equals "/" } {
            set newuri [class lookup ${HostName} REDIRECTS]
            if { !(${newuri} eq "/") && (${newuri} ne "") } {
                set redirect 1
                set uri $newuri
                unset newuri
            }
        }
        if {$redirect} {
            HTTP::respond 301 noserver Location "https://$host${uri}" Connection Close
        }
    }