Forum Discussion

Brett__01_13258's avatar
Brett__01_13258
Icon for Nimbostratus rankNimbostratus
Oct 20, 2015

2 http request rules merge to one - one referer the other set access only

Hi I have two rules that work individually. But when i try and combine get no luck and just redirects everything to the default location.

The first rule is to only allow the uri path in the irule, otherwise redirect to Unathorized page. Second is to only allow the request if it comes via 3 set referers.

It would be much appreciated if someone can please help combine both of these?

1st RULE

when HTTP_REQUEST {

   set uri [string tolower [HTTP::uri]]
      switch -glob $uri {
    "/path1/path2/path3*" -
    "/path4/path2/path3*" -
    "/path1/path2/path5*" -
    "/path4/path2/path5*"
{
     redirect to Pool
     pool POOL_Servers_to_access-80 
                                }
                default { 
         log local0. "Other access not allowed $uri”
         HTTP::redirect "http://www.notallowed.asp"
        }
                }

}

2nd RULE

when HTTP_REQUEST {
  switch -glob [string tolower [URI::host [HTTP::header "Referer"]]] {
    "goodlocation.com/*" -
    "anothergoodlocation.com/*" -
    "youcanalsologin.com/*" {
          }
     redirect_to_location_to_sign_in_first
    "" {
      HTTP::redirect "http://goodlocation.com"

    }
     Allow Request to go through...
    default {
       pool POOL_Servers_to_access-80

    }
  }
}

Thanks in advance.

cheers Brett

  • I normally prefer a switch over if/else, but in your case, multiple conditions aren't as pretty as to combine you'd end up with nested switch statements. Doable, but ugly. It looks like the flow is:

    1. Make sure the path is allowed, if not, redirect to
    2. If the path has already been verified as allowed, check that the referer header contains (X)
    1. If it doesn't, proceed
    2. If it does, redirect to http://goodlocation.com

    If this is the case, I'd simplify all the logic down to two data-groups and a short iRule:

    ltm data-group internal allowed_paths {
        records {
            /path1/path2/path3 { }
            /path1/path2/path5 { }
            /path4/path2/path3 { }
            /path4/path2/path5 { }
        }
        type string
    }
    ltm data-group internal login_required_paths {
        records {
            anothergoodlocation.com { }
            goodlocation.com { }
            youcanalsologin.com { }
        }
        type string
    }
    when HTTP_REQUEST {
      if { [class match [string tolower [HTTP::uri]] starts_with allowed_paths] } {
        if { [class match [strint tolower [URI::host [HTTP::header "Referer"]] starts_with login_required_paths] } {
          HTTP::redirect "http://goodlocation.com"
        }
      } else { HTTP::redirect "http://www.notallowed.asp" }
    }
    

    This assumes of course you have defined pool POOL_Servers_to_access-80 as the default pool on your virtual server.

  • Hi,

    How can the second irule work with the switch condition???

    if the referer is

    http://goodlocation.com/mypath
    , the command
    [string tolower [URI::host [HTTP::header "Referer"]]]
    returns only
    goodlocation.com
    and you search
    goodlocation.com/*

    another issue may be the redirect in both irules: if there is no referer and path is wrong, the second redirect may cause TCL error. to solve this issue, add a

    return
    command after each redirect command

  • Thanks for the reply guys and they got me wondering if i was doing the best way.

    Now going to accept all except the part of the url i dont want to give access and use cookies as the allowed access.

    So have decided to go with two other rules instead and will merge these together.

    Is this a better way to go?

    when HTTP_REQUEST {
    
        Check for referer
        if { ([HTTP::header Referer] starts_with "http://allowsite.com") } {
            log local0. "Our referer is - [URI::host [HTTP::header Referer]]"
    
                Check for cookie
                if { not ( [HTTP::cookie value ACCESS-AUTHORIZED] contains "Go1234") } {                   
                log local0. "Does a cookie exist? [HTTP::cookie exists IMHERE-COOKIE] ...Lets set a cookie"
                set ckname " ACCESS-AUTHORIZED "
                set ckvalue "Go1234"
                set cookie [format "%s=%s; path=/; domain=%s" $ckname $ckvalue "mysite.com.au"]
                set cookie [format "%s=%s; path=/; expires=[clock format [expr {[clock seconds]+300}] -format "%a, %d %h %Y %T GMT" -gmt true]; domain=%s" $ckname $ckvalue "mysite.com.au"]
                HTTP::respond 302 Location "https://mysite.com.au/ /correctlocation" "Set-Cookie" $cookie
                    } else {
                    log local0. "Cookie already exists"
                    pool POOL_TheCorrectPool-80
                }
        } elseif { ( [HTTP::cookie value ACCESS-AUTHORIZED] contains "Go1234") } {  
            log local0. "We already have a cookie..."
            pool POOL_TheCorrectPool-80
            } else {
            log local0. "No Cookie...whoops"
            HTTP::redirect "https://notauthorized.com/"
                    }
        }
    

    2nd rule

    when HTTP_REQUEST { 
        log local0. "uri is [HTTP::uri]" 
        switch -glob -- [string tolower [HTTP::uri]] {
            "*admin*" {
                HTTP::respond 200 content { The URL you requested is incorrect. For other information, please contact IT Administrator @ 999999 }
                log local0. "Request from [IP::client_addr] for [HTTP::uri] has been rejected." 
            }
        }        
    }
    
  • Thanks for the reply guys and they got me wondering if i was doing the best way.

    Now going to accept all except the part of the url i dont want to give access and use cookies as the allowed access.

    So have decided to go with two other rules instead and will merge these together.

    Is this a better way to go?

    when HTTP_REQUEST {
    
        Check for referer
        if { ([HTTP::header Referer] starts_with "http://allowsite.com") } {
            log local0. "Our referer is - [URI::host [HTTP::header Referer]]"
    
                Check for cookie
                if { not ( [HTTP::cookie value ACCESS-AUTHORIZED] contains "Go1234") } {                   
                log local0. "Does a cookie exist? [HTTP::cookie exists IMHERE-COOKIE] ...Lets set a cookie"
                set ckname " ACCESS-AUTHORIZED "
                set ckvalue "Go1234"
                set cookie [format "%s=%s; path=/; domain=%s" $ckname $ckvalue "mysite.com.au"]
                set cookie [format "%s=%s; path=/; expires=[clock format [expr {[clock seconds]+300}] -format "%a, %d %h %Y %T GMT" -gmt true]; domain=%s" $ckname $ckvalue "mysite.com.au"]
                HTTP::respond 302 Location "https://mysite.com.au/ /correctlocation" "Set-Cookie" $cookie
                    } else {
                    log local0. "Cookie already exists"
                    pool POOL_TheCorrectPool-80
                }
        } elseif { ( [HTTP::cookie value ACCESS-AUTHORIZED] contains "Go1234") } {  
            log local0. "We already have a cookie..."
            pool POOL_TheCorrectPool-80
            } else {
            log local0. "No Cookie...whoops"
            HTTP::redirect "https://notauthorized.com/"
                    }
        }
    

    2nd rule

    when HTTP_REQUEST { 
        log local0. "uri is [HTTP::uri]" 
        switch -glob -- [string tolower [HTTP::uri]] {
            "*admin*" {
                HTTP::respond 200 content { The URL you requested is incorrect. For other information, please contact IT Administrator @ 999999 }
                log local0. "Request from [IP::client_addr] for [HTTP::uri] has been rejected." 
            }
        }        
    }