Forum Discussion

Robert_Pagano_7's avatar
Robert_Pagano_7
Icon for Nimbostratus rankNimbostratus
May 30, 2013

deny access to certain URIs based on client source IP address and URI being accessed

I have been asked to deny access to a virtual server if ...

 

[1] the client is coming from a "non-private" (i.e. not RFC 1918) IP address

 

and

 

[2] the client is trying to access any one of three specific URIs.

 

 

Based on what I've read in other threads in this forum, this is what I've come up with ...

 

-=-=-=-=-=

 

----- data group list -----

 

 

INTERNAL_NETWORKS_class

 

 

network 10.0.0.0 / 255.0.0.0

 

network 172.16.0.0 / 255.240.0.0

 

network 192.168.0.0 / 255.255.0.0

 

 

 

----- irule -----

 

 

when HTTP_REQUEST {

 

if {not ([matchclass [IP::client_addr] equals $::INTERNAL_NETWORKS_class]) } {

 

switch [HTTP::uri] {

 

"blah-blah-blah" -

 

"system/yada-yada-yada?CONFIG=1&USERTYPE=1&other-stuff=true" -

 

"system/yada-yada-yada?CONFIG=1&USERTYPE=2&other-stuff=true" { drop }

 

}

 

}

 

}

 

-=-=-=-=-=

 

I haven't tried this yet but I am just wondering if this is the best approach?

 

Also, would I need a "catch-all" statement at the end? The behavior should be that, if there is no match, the traffic should flow unimpeded.

 

Any help will be greatly appreciated!

 

Thanks!

 

5 Replies

  • There's easily dozens of ways to logically enforce this requirement, and yours looks pretty sound. A few things I would change though:

     

     

    1. If this is a v10 box or above, you need to get rid of the "$::" in the data group name.

     

     

    2. It would be safer to add [string tolower ] to the [HTTP::uri] in the switch statement.

     

     

    3. A URI will always start with a forward slash "/" (ex. "/system/yada-yada-yada...).

     

     

    4. I would also recommend a switch -glob syntax. If the user adds a silly query string or hash to the end of one of the forbidden URIs, it won't be caught by your current conditions.

     

     

    So in this case, if the client IP does NOT match something in the data group, ignore the rest of the condition and fall through. No catch all needed. If the client IP DOES match something in the data group, and the client is attempting to access one of three specific URIs, drop the request. You could also preemptively send the user some HTML via HTTP::respond, like a "go away" message.

     

  • Kevin:

     

     

    Thank you for your response and your suggestions.

     

     

    This iRule will be deployed on a box running 9.x code so I suppose the "$::" is required.

     

     

    Also, based on your comments, I've made a few edits to the iRule.

     

     

    ----- irule -----

     

     

    when HTTP_REQUEST {

     

    if {not ([matchclass [IP::client_addr] equals $::INTERNAL_NETWORKS_class]) } {

     

    switch -glob [string tolower [HTTP::uri]] {

     

    "/blah-blah-blah" -

     

    "/system/yada-yada-yada?config=1&usertype=1&other-stuff=true" -

     

    "/system/yada-yada-yada?config=1&usertype=2&other-stuff=true" { drop }

     

    }

     

    }

     

    }

     

    -----

     

     

    In the above, I manually converted the URIs to lower case but I suppose it should be possible to do something like ...

     

     

    [string tolower ["blah-blah-blah"] -

     

    [string tolower ["system/yada-yada-yada?CONFIG=1&USERTYPE=1&other-stuff=true"] -

     

    [string tolower ["system/yada-yada-yada?CONFIG=1&USERTYPE=2&other-stuff=true"] { drop }

     

     

    Thanks again!

     

  • The switch -glob syntax allows you to catch wildcard data, so if the user added a hash tag and some text at the end of the URI, the application would probably ignore it, but then so would your static evaluation. I would then recommend something like this:

     

     

    switch -glob [string tolower [HTTP::uri]] {

     

    "/blah-blah-blah*" -

     

    "/system/yada-yada-yada?config=1&usertype=1&other-stuff=true*" -

     

    "/system/yada-yada-yada?config=1&usertype=2&other-stuff=true*" { drop }

     

    }

     

     

    Just added the star "*" to the end of each URI to catch anything AFTER that string as well.

     

  • This may be a stupid question but I'm going to ask it anyway ... :-)

     

     

    Is there any way to get this sort of functionality for an HTTPS connection (i.e. when the path/filename portion of the URI is encrypted)?
  • Is there any way to get this sort of functionality for an HTTPS connection (i.e. when the path/filename portion of the URI is encrypted)?clientssl profile will take responsibility to decrypt traffic. the irule should not be changed.