Forum Discussion

Chares_14893's avatar
Chares_14893
Icon for Nimbostratus rankNimbostratus
Jan 05, 2017

Limited host header redirection & question about irule statements processing order

Hi There,

 

I'm trying to achieve a one security irule to rule all types of redirects, and only allow specific applications, ensuring each application is accessed with its own asociated hostname,

 

I'm having a hard time understanding the "event disable" or "event disable all", as in some cases it doesn' work as expected,

 

I'm doing the following code basically:

 

when HTTP_REQUEST {
     Basically deny any other types of methods on the virtual server where this irule is attached.
    switch [HTTP::method] {
        "GET" -
        "HEAD" -
        "POST" {
        }
        default {
            reject  
            event disable all
        }
    }

    switch -glob [HTTP::uri] {
         Attempt to force the correct hostnames to the backend applications.
        "/App1*" {
            if { not ([string tolower [HTTP::host]] equals "hostname1.com") } {
                HTTP::respond 302 noserver Location "https://hostname1.com/App1/"
                event disable all
            }
        }
        "/App2*" {
            if { not ([string tolower [HTTP::host]] equals "hostname2.com") } {
                HTTP::respond 302 noserver Location "https://hostname2.com/App2/"
                event disable all           
            }
        }
    }

    switch -glob [string tolower [HTTP::host]] {
         Attempt to force redirection to the applications if the / URI is requested.
        "hostname1.com" {
            if { [HTTP::uri] equals "/" } {
                HTTP::respond 302 noserver Location "https://hostname1.com/App1/"
                event disable all
            }    
        }
        "hostname2.com" {
            if { [HTTP::uri] equals "/" } {
                HTTP::respond 302 noserver Location "https://hostname2.com/App2/"
                event disable all
            }    
        }   
        default {
        reject          
        event disable all
        }  
}

when HTTP_RESPONSE {
    
     Set httponly & secure attribute in the cookies.
     then remove server identification headers.
     And add security related headers.
    
    foreach mycookie [HTTP::cookie names] {
        HTTP::cookie httponly $mycookie enable
         the following only goes if the irule is attached to an SSL virtual server
        HTTP::cookie secure $mycookie enable
    }
    HTTP::header remove Server
    HTTP::header remove X-Powered-By
    HTTP::header remove X-AspNet-Version

 The following only goes if the irule is attached to virtual server with a login required.
HTTP::header insert "Cache-Control" "no-store"
HTTP::header insert "Pragma" "no-cache"       
    
     If the backend sends this headers, replace them with the following values.
    if { [HTTP::header exists "X-Frame-Options"] equals "true" } {
        HTTP::header replace "X-Frame-Options" "SAMEORIGIN"
    }
    if { [HTTP::header exists "X-Xss-Protection"] equals "true" } {
        HTTP::header replace "X-Xss-Protection" "1; mode=block"
    }
    if { [HTTP::header exists "X-Content-Type-Options"] equals "true" } {
        HTTP::header replace "X-Content-Type-Options" "nosniff"
    }
}

So the idea is: A.- If a know application is requested, redirect to its correspondent asociated host B.- If a host is requested on the root URI (/) forward it to the application root (ex: /App1/) C.- If neither of the conditions are met, reject the conection, reseting it. D.- If it is a response, modify cookies acordingly, remove some headers, add some headers, replace some headers.

 

I've attempted with and without the event disable on each condition, If i try to access with "; it should redirect to "; because of the first condition of the second switch on the HTTP_REQUEST, but it doesn't, it ends up on the "reject" of the third switch (the last condition), and by hitting cntrl-f5 (force refresh the browser) a couple of times, it goes through,

 

I don't know if i'm doing something wrong with the logic, or im not correctly understanding the irule processing order, shouldnt "event disable all" stop completely the next switch conditions on the HTTP_REQUEST event?

 

Any ideas what might be wrong?

 

Also, is there any way that the "HTTP::respond 302 noserver Location "location"" includes the mentioned headers in the HTTP_RESPONSE ? HTTP::Respond (and HTTP::Redirect) don't seem to be governed by the HTTP_RESPONSE event.

 

Should the HTTP_REQUEST and HTTP_RESPONSE live on the same iRule? i've seen a few recomendations about using as little as possible irules, but not about having the same or separating when you use Request/Response events.

 

Feel free to re-use this idea! 🙂

 

Thanks!

 

1 Reply

  • I am answering some of your questions:

     

    HTTP_REQUEST & HTTP_RESPONSE are two different events and can be used within a single iRule or multiple iRules. I would recommend using it within a single iRule.

     

    HTTP::respond is an action that is utilized within the HTTP_REQUEST event and not HTTP_RESPONSE.

     

    Personally, I would recommend using the "event disable" sparingly. Instead of using multiple switch-statements with event disable, can you try using if-else-statements ? Using if-else conditional statements such that the specific matches exist at the top of the iRule will help you to stay away from the event disable statements.