Forum Discussion

Richard_'s avatar
Richard_
Icon for Nimbostratus rankNimbostratus
Sep 05, 2016

How to filter client access based on source IP and URI

Hi,

 

For a webservice we have to give clients access to a specific uri, but only from a specified list of ip adresses. So access to www.site.foo/uri1 only from 1.1.1.1 and 1.1.1.2 and access to www.site.foo/uri2 only from 2.2.2.1 and 2.2.2.2. And that for 106 uris and about 10 ip adresses per uri.

 

Is there a best practice for this? Using an iRule? Or using an access policy? Any idea is more than welcome.

 

Thanks in advance.

 

Regards,

 

Richard

 

3 Replies

  • I think you would have to identify some kind of pattern in order to see if you can have a simplified iRule. As a general suggestion, datagroup containing IP addresses can be used to match on client IP.

     

    If there is only 1 IP or a single network, you can try to leverage the key:value aspect of the datagroup and use something like this "1.1.1.1:=/uri1" i.e., identify the allowed uri based on the matched key (IP Address).

     

    If you know any geographic information of the client IP, you can explore the whereis option in iRule.

     

  • Hi Richard,

    you may try one of the following examples...

    Example 1: Using a single datagroup to assign allowed IPs to restricted URIs

    Datagroup (DG_MY_URI Type STRING):

    "/folder1" := "1.1.1.1 2.2.2.2 3.3.3.3 4.4.4.4"
    "/folder2" := "1.1.1.1 2.2.2.2"
    "/folder3" := "3.3.3.3 4.4.4.4"
    "/folder4" := "5.5.5.5"
    

    iRule:

    when HTTP_REQUEST {
        if { [set uri_result [class match -value [string tolower [HTTP::path]] starts_with DG_MY_URI]] ne "" } then {
            if { [lsearch -inline $uri_result [IP::client_addr]] eq "" } then {
                HTTP::respond 403 content "Access denied..." "Content-Type" "text/html"
            } else {
                 Allow trusted IP 
            }
        } else {
             Allow requests to unknown URIs
        }
    }
    

    Example 2: Using two datagroups to support a "kind of" object based ACL.

    Datagroup (DG_MY_URI Type STRING):

    "/folder1" := "Internal Customer1 Customer2 Customer3"
    "/folder2" := "Internal Customer2 Customer3"
    "/folder3" := "Internal Customer3"
    "/folder4" := "Location1 Location2"
    

    IP Datagroup (DG_MY_IP Type IP-Adrress):

    "10.0.0.0/8" := "Internal"
    "10.10.10.0/24" := "Internal Location1"
    "10.10.11.0/24" := "Internal Location1"
    "10.10.12.0/24" := "Internal Location1"
    "10.10.13.0/24" := "Internal Location1"
    "10.10.14.0/24" := "Internal Location2"
    "10.10.15.0/24" := "Internal Location2"
    "10.10.16.0/24" := "Internal Location2"
    "10.10.17.0/24" := "Internal Location2"
    "111.111.111.111" := "Customer1"
    "172.16.0.0/12" := "Internal"
    "190.190.190.190" := "Customer2"
    "192.168.0.0/16" := "Internal"
    "212.212.212.212" := "Customer3"
    

    iRule:

    when CLIENT_ACCEPTED {
        set ip_result [class match -value [IP::client_addr] equals DG_MY_IP]    
    }
    when HTTP_REQUEST {
        if { [set uri_result [class match -value [string tolower [HTTP::path]] starts_with DG_MY_URI]] ne "" } then {
            if { $ip_result eq "" } then {
                 Disallow the request
            } else {
                foreach uri_entry $uri_result {
                    if { [lsearch -inline $ip_result $uri_entry] ne "" } then {
                         Allow trusted IP
                        return
                    }
                }
                 Disallow the request
            }
        } else {
             Allow requests to unknown URIs
            return
        }
         Trigger the error page...
        HTTP::respond 403 content "Access denied..." "Content-Type" "text/html"
    }
    

    Cheers, Kai