Forum Discussion

Chares_14893's avatar
Chares_14893
Icon for Nimbostratus rankNimbostratus
Jan 12, 2017
Solved

is it possible with an irule to reject a connection if the redirec is not followed?

Hi There,

Is it possible with an irule that if a browser does not follow a redirect (examples: non-standard browser, custom client, IE10 redirect bug, etc), to reject the connection altogether?

right now i'm doing something similar to this, but in cases that the client doesn't follow redirects to an https url in another virtual server, i cannot force them at the moment, and they can pass through the HTTP virtual server without passing through the HTTPS one.

when HTTP_REQUEST {
    switch -glob [string tolower [HTTP::host]] {
        "www.hostname1.com" {
            if { [HTTP::uri] equals "/" } {
                HTTP::respond 302 noserver Location "https://www.hostname1.com/App1/"
            }    
        }
        "www.hostname2.com" {
            if { [HTTP::uri] equals "/" } {
                HTTP::respond 302 noserver Location "https://www.hostname2.com/App2/"
            }    
        }
        default {
            reject
        }
    }
}

I still cannot find a way to limit the connection. i was thinking of something with TCP::local_port with something like this, but i'm not so sure it will work, since i think it will never get into the second nested if:

when HTTP_REQUEST {
    switch -glob [string tolower [HTTP::host]] {
        "www.hostname1.com" {
            if { [HTTP::uri] equals "/" } {
                HTTP::respond 302 noserver Location "https://www.hostname1.com/App1/"
                if { not ([TCP::local_port] equals "443") } {
                    reject
                }                   
            }
        }
        "www.hostname2.com" {
            if { [HTTP::uri] equals "/" } {
                HTTP::respond 302 noserver Location "https://www.hostname2.com/App2/"
                if { not ([TCP::local_port] equals "443") } {
                    reject
                }   
            } 
        }
        default {
            reject
        }
    }
}

will the irule stop processing as soon as it hits the HTTP:respond (when redirect works)? or it will continue to evaluate and get into the nested if?

What do you think?

Thanks!

  • Hi there, after much testing and considering your comments, I finally found the problem,

     

    a 302 redirect, if the client ignores redirects, let's the connection pass trough, for example:

     

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
            "www.hostname1.com" {
                HTTP::respond 302 noserver Location "https://www.hostname1.com/App1/"
            }
            default {
                reject
            }
        }
     }

    This code above, will let a client through LTM to http://www.hostname1.com/App1/ if the redirect is ignored.

     

    So the solution is simply doing a 301:

     

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
            "www.hostname1.com" {
                HTTP::respond 301 noserver Location "https://www.hostname1.com/App1/"
            }
            default {
                reject
            }
        }
     }

    This code above will correct the problem, and when the client attempts to bypass the redirect by ignoring them, instead of getting the 200 from the backend, it will only get the 301 response from the LTM, regardless of ignoring the redirect.

     

    Seems to me a behaviour not contemplated in the HTTP::respond documentation regading LTM VSs iRule processing (Or something that has been commented somewhere else, but not on the respond doc).

     

    Thanks for the help Odaah!

     

2 Replies

  • Within the iRule, if there are say, 2 matches, the 2nd match will be utilized to execute corresponding action.

     

  • Hi there, after much testing and considering your comments, I finally found the problem,

     

    a 302 redirect, if the client ignores redirects, let's the connection pass trough, for example:

     

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
            "www.hostname1.com" {
                HTTP::respond 302 noserver Location "https://www.hostname1.com/App1/"
            }
            default {
                reject
            }
        }
     }

    This code above, will let a client through LTM to http://www.hostname1.com/App1/ if the redirect is ignored.

     

    So the solution is simply doing a 301:

     

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
            "www.hostname1.com" {
                HTTP::respond 301 noserver Location "https://www.hostname1.com/App1/"
            }
            default {
                reject
            }
        }
     }

    This code above will correct the problem, and when the client attempts to bypass the redirect by ignoring them, instead of getting the 200 from the backend, it will only get the 301 response from the LTM, regardless of ignoring the redirect.

     

    Seems to me a behaviour not contemplated in the HTTP::respond documentation regading LTM VSs iRule processing (Or something that has been commented somewhere else, but not on the respond doc).

     

    Thanks for the help Odaah!