Forum Discussion

JCMATTOS_41723's avatar
JCMATTOS_41723
Icon for Nimbostratus rankNimbostratus
Jul 09, 2009

Restrict access to certain url's by sourceIP?

Hello Forum,

 

We are trying to utilize some irules to allow only certain users to only access specific url's? Essentially, user A, B, C are trying to access the same virtual server IP, but have different url subdirectories which we would like to restrict access to. Is it possible to have an irule that can look at the source IP and restrict access to only certain url's and deny the rest? Also, typically what kind of performance degradation can we expect to see with this implemented on a 8400 w/9.4.7?

 

User A => /www.abccompany.com/folderA

 

User B => /www.abccompany.com/folderB

 

User C => /www.abccompany.com/folderC

 

Default => Deny all

6 Replies

  • Hi JC,

    You could do this all in an iRule or you could create three address type datagroups (users_A_class, users_B_class & users_C_class) and then reference them in an iRule:

      
     when HTTP_REQUEST {  
         Check the requested URI  
        switch -glob [string tolower [HTTP::path]] {  
           "/folderA*" {  
               Reset the request if if the source IP is not allowed  
              if {not ([matchclass [IP::client_addr] equals $::users_A_class])}{  
                 reject  
              }  
           "/folderB*" {  
               Reset the request if the source IP is not allowed  
              if {not ([matchclass [IP::client_addr] equals $::users_B_class])}{  
                 reject  
              }  
           "/folderC*" {  
               Reset the request if the source IP is not allowed  
              if {not ([matchclass [IP::client_addr] equals $::users_C_class])}{  
                 reject  
              }  
           default {  
               Reset the request  
              reject  
           }  
        }  
     }  
     

    Be aware that a malicious user could potentially bypass the validation using path manipulations if they were part of any of the allowed clients datagroups. For example a client in user_A made a request for /folderA/../any/other/directory/, it would pass the iRule logic but potentially be parsed as /any/other/directory/ by the webserver.

    See this post for more examples (http://devcentral.f5.com/Default.aspx?tabid=53&forumid=5&tpage=1&view=topic&postid=30900).

    Aaron
  • Very Cool...Thx Hoolio! Question, would there be any peformance difference in using the datagroups vs the other? Also, do you have a sample of the datagroup setup as well?
  • If you had a single subnet for each group of users, it would probably be about the same to use IP::addr in the iRule versus matchclass against a datagroup. If you have more than one subnet, I expect matchclass to be faster.

    Here is an example address datagroup:

     
     class hosts_subnets_class { 
        host 1.1.1.1 
        network 2.0.0.0/8 
     } 
     

    You can create the datagroup in the GUI under Local Traffic >> iRules >> Datagroups list tab.

    Aaron
  • I tried applying the irule to the VIP and it does not appear to be working? It just times out. Any ideas?

     

     

    when HTTP_REQUEST {

     

    Check the requested URI

     

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

     

    "/FilterTest*" {

     

    Reset the request if if the source IP is not allowed

     

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

     

    reject

     

    }

     

    }

     

    default {

     

    Reset the request

     

    reject

     

    }

     

    }

     

    }

     

     

  • If you want to test a single IP address/subnet, you can use IP::addr (Click here). If you want to compare the client IP to a group of IP addresses and subnets, you can create them in a datagroup (aka class) and then use matchclass:

     
     class users_A_class {  
        host 1.1.1.1  
        network 2.0.0.0/8  
     }  
     

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

    The class definition is separate from the iRule.

    Aaron
  • Thx Aaron, I created a datagroup called users_A_class thru the GUI and still no luck? Am I missing something?

     

     

    [root@Active] config b class list all

     

    class users_A_class {

     

    type ip

     

    filename none

     

    mode rw

     

    partition Common

     

    host 172.24.4.50

     

    none

     

    none

     

    }

     

    ---------------------------------------------

     

     

    when HTTP_REQUEST {

     

    Check the requested URI

     

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

     

    "/FilterTest*" {

     

    Reset the request if if the source IP is not allowed

     

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

     

    reject

     

    }

     

    }

     

    default {

     

    Reset the request

     

    reject

     

    }

     

    }

     

    }