Forum Discussion

Ert_27713's avatar
Ert_27713
Icon for Nimbostratus rankNimbostratus
Jan 21, 2008

Irule ACL based on URI

Can someone help me with creating a rule that can filter URI access based on IP address.

 

 

Something like

 

 

userIP1 can access /userDIR1

 

userIP2 can access /userDIR2

 

userIP3 can access /userDIR3

 

anyIP can access /publicDIR

 

default drop

 

 

Here is my stab at it, that doesn't work:

 

 

when CLIENT_ACCEPTED {

 

if {[matchclass [IP::remote_addr] equals $::userIP1] and [HTTP::uri] equals /userDIR1} then {

 

log local0.info "Allowed client to userIP1: [IP::remote_addr] requesting: [HTTP::uri]"

 

} elseif {

 

if {[matchclass [IP::remote_addr] equals $::userIP2] and [HTTP::uri] equals /userIP2} then {

 

log local0.info "Allowed client to userIP2: [IP::remote_addr] requesting: [HTTP::uri]"

 

} elseif {

 

if {[matchclass [IP::remote_addr] equals $::userIP3] and [HTTP::uri] equals /userIP3} then {

 

log local0.info "Allowed client to userIP3: [IP::remote_addr] requesting: [HTTP::uri]"

 

} else {

 

if {[HTTP::uri] equals /any}

 

} else {

 

default {

 

drop

 

log local0. "Dropped client [IP::remote_addr] requesting: [HTTP::uri]"

 

}

 

}

 

}

 

 

 

Thanks

 

 

Eric

2 Replies

  • I expect you'd get a parser error when trying to save that rule because the HTTP::uri command isn't valid in the CLIENT_ACCEPTED event. To access the HTTP request headers, you should use the HTTP_REQUEST event. The IP:: commands are still valid there as well, so you can just change CLIENT_ACCEPTED to HTTP_REQUEST.

     

     

    Is user IP just one IP or is it a set of hosts and/or networks? If it's just one IP or network, you can use IP::addr (Click here) to perform the comparison:

     

     

    if {[IP::addr [IP::client_addr] equals 1.2.3.4] and [HTTP::path] equals /userDIR1}{

     

     

    If you have a set of networks or hosts you want to compare for $::userIP1, then the matchclass method you were using will work well.

     

     

    Also, you can use HTTP::path instead of HTTP::uri to get the URI minus the query string.

     

     

    Aaron
  • Colin_Walker_12's avatar
    Colin_Walker_12
    Historic F5 Account
    So what hoolio's saying is, try something like:

    
    when HTTP_REQUEST {
      if {[matchclass [IP::remote_addr] equals $::userIP1] and [HTTP::uri] equals /userDIR1} {
        log local0.info "Allowed client to userIP1: [IP::remote_addr] requesting: [HTTP::uri]"
      } elseif {[matchclass [IP::remote_addr] equals $::userIP2] and [HTTP::uri] equals /userIP2} {
        log local0.info "Allowed client to userIP2: [IP::remote_addr] requesting: [HTTP::uri]"
      } elseif {[matchclass [IP::remote_addr] equals $::userIP3] and [HTTP::uri] equals /userIP3} {
        log local0.info "Allowed client to userIP3: [IP::remote_addr] requesting: [HTTP::uri]"
      } else {
        drop
        log local0. "Dropped client [IP::remote_addr] requesting: [HTTP::uri]"
      }
    }

    This is what it looked like you were trying to get to. Let us know if you've got further questions.

    Colin