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

Log4j2's avatar
Log4j2
Icon for Altocumulus rankAltocumulus
Aug 02, 2021
Solved

Best way to limit what URI/Path is available

I currently have an iRule that will forward traffic to a destination pool based on what was in the host value:

when HTTP_REQUEST { 
 if { [string tolower [HTTP::host]] contains "example1.mydomain.com" } { 
pool /Common/App_Example_1.app/Pool_Example_1_pool
 } elseif { [string tolower [HTTP::host]] contains "example2.mydomain.com" } { 
pool /Common/App_Example_2.app/Pool_Example_2_pool
 } else { 
 pool /Common/App_Example_3.app/Pool_Example_3_pool
 }
}

For that second host (example2.mydomain.com) I want to make it so that only 3 URI's are actually available, let's say:

/v1/this/should/work*

/v1/this/will/also/work*

v2/this/one/too*

Everything else should be logged and blocked while presented a page about not being allowed

Here's what I tried:

when HTTP_REQUEST { 
 if { [string tolower [HTTP::host]] contains "example1.mydomain.com" } { 
pool /Common/App_Example_1.app/Pool_Example_1_pool
 } elseif { [string tolower [HTTP::host]] contains "example2.mydomain.com" } { 
  		 if { (([string tolower [HTTP::uri]] starts_with "/v1/this/should/work") or ([string tolower [HTTP::uri]] starts_with "/v1/this/will/also/work") or ([string tolower [HTTP::uri]] starts_with "v2/this/one/too")) } {
              pool /Common/App_Example_2.app/Pool_Example_2_pool
  		 } else {
  			log local0. "Blocked - [HTTP::host] - [HTTP::uri] from [IP::client_addr]"
  			HTTP::respond 200 content {
  				<html>
  				 <head>
  					<title>Access Denied</title>
  				 </head>
  				 <body>
  					You are not authorized to access the requested resource
  				 </body>
  				</html>
  			}
  		}
   } else { 
   pool /Common/App_Example_3.app/Pool_Example_3_pool
   }
  }

In this update it now just seems to block every request, regardless of the URI.

Is there a better way to do this outside of an iRule? What would make this iRule work? I also tried nesting "if" statements but that also didn't work.

Thanks!

  • This can be optimized using switch statement. Create string datagroup (example2_allowed_uri) for allowed uri. You can use default_pool to send traffic at the end or reject it if there is no match for the HOST.

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
            "example1.mydomain.com" 
           {
    	     pool /Common/App_Example_1.app/Pool_Example_1_pool
    	   } 
    	   "example2.mydomain.com"
    	   {
    	     if { [class match [string tolower [HTTP::uri]] starts_with example2_allowed_uri ] } { 
    		 pool /Common/App_Example_2.app/Pool_Example_2_pool
    	     } else {
    		   HTTP::respond 200 content "access denied" noserver Content-Type text/html Connection Close
    		 }
    	   }   
    	   "example3.mydomain.com"
    	   {
    	     pool /Common/App_Example_3.app/Pool_Example_3_pool
    	   }
    	   default {
             pool default_pool
          }
        }
     }

2 Replies

  • This can be optimized using switch statement. Create string datagroup (example2_allowed_uri) for allowed uri. You can use default_pool to send traffic at the end or reject it if there is no match for the HOST.

    when HTTP_REQUEST {
        switch -glob [string tolower [HTTP::host]] {
            "example1.mydomain.com" 
           {
    	     pool /Common/App_Example_1.app/Pool_Example_1_pool
    	   } 
    	   "example2.mydomain.com"
    	   {
    	     if { [class match [string tolower [HTTP::uri]] starts_with example2_allowed_uri ] } { 
    		 pool /Common/App_Example_2.app/Pool_Example_2_pool
    	     } else {
    		   HTTP::respond 200 content "access denied" noserver Content-Type text/html Connection Close
    		 }
    	   }   
    	   "example3.mydomain.com"
    	   {
    	     pool /Common/App_Example_3.app/Pool_Example_3_pool
    	   }
    	   default {
             pool default_pool
          }
        }
     }
    • Log4j2's avatar
      Log4j2
      Icon for Altocumulus rankAltocumulus

      Thank you ! This worked perfectly, I never thought to use DataGroups

       

      Thank you again, much appreciated!