Forum Discussion

Net_Admin_24240's avatar
Net_Admin_24240
Icon for Nimbostratus rankNimbostratus
Jul 27, 2006

block public access allow private

I want to block access to URL's from any public address but allow access if the client initiates the connection using a private address.

 

 

For example: block access to http://mycompany.com/Debug or http://mycompany.com/admin but allow access if client has a private IP address.

 

 

Also, would it be more efficient to check the client address first or the URL, or is there another way to do this? Thanks.

10 Replies

  • If you have separate VLANs for internal clients versus external clients, you could just create a VIP enabled on the VLAN the internal clients access the VIP over.

    If the external and internal clients are connecting to the VIP over the same VLAN, you could use a pair of classes (data groups) and a rule to block requests from external client IP addresses to "protected" URI's:

    
    class internal_hosts_networks_class  {
       network 10.0.0.0 mask 255.0.0.0
       host 192.168.0.100
    }

    
    class my_protected_uris {
       "/path1/"
       "/path2/"
    }

    
    when HTTP_REQUEST {
       if { [matchclass [HTTP::uri] starts_with $::my_protected_uris] and (not [matchclass [IP::remote_addr] equals $::internal_hosts_networks_class]) } {   
          log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"
          discard
       }
    }

    I haven't tested this, but I think it should work based on the description you gave.

    Aaron
  • A couple of quick, related notes:

     

     

    To create datagroups in the GUI, go to Local Traffic >> iRules >> Datagroups. Add the URI's as strings. Add the IP addresses/networks as addresses.

     

     

    The rule basically checks to see if the requested URI starts with any of the URIs in the second datagroup. If the requested URI doesn't match, the second comparison for IP address shouldn't be made and the request will be handled by the pool configured on the VIP. If the URI does start with one of the protected URIs, the client IP address is compared with the internal hosts/networks datagroup. If there isn't a match there, the request is dropped.

     

     

    Aaron
  • I am running BIG-IP 9.1.2 Build 40.6. Do I need to reference the datagroups in the rule besides in the "if" statement? I have not been able to discard traffic using the following:

     

     

    class AdminDebugURI {

     

    "www.mycompany.com/Debug/Debug/ecv.jsp"

     

     

    when HTTP_REQUEST {

     

    if { [matchclass [HTTP::uri] contains $::AdminDebugURI ] and (not [matchclass [IP::remote_addr] equals $::private_net ]) } {

     

    log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"

     

    discard

     

    }

     

    }

     

     

    If I reference the URI & private IP address string as text in the rule I get "LOGIN: Re-starting tmm" when using tcpdump to filter on the public IP address.

     

     

    when HTTP_REQUEST {

     

    if { [matchclass [HTTP::uri] contains "www.mycompany.com/Debug" ] and (not [matchclass [IP::remote_addr] equals "10.10.10.10" ]) } {

     

    log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"

     

    discard

     

    }

     

    }
  • Deb_Allen_18's avatar
    Deb_Allen_18
    Historic F5 Account
    Hostname is not part of the URI, so try this for your class entry instead:
    class AdminDebugURI {
      "/Debug/Debug/ecv.jsp"
    }
    If you need to check the hostname as well, you'll need to add another condition using [HTTP::host].

    HTH

    /deb
  • Hi,

    If you want to compare just a single IP address, you should use [IP::addr [IP::remote_addr]]. If you want to test to see if a client request made from 10.10.10.10 for a URI that contains "debug" is dropped, you can use a rule like this:

    
    when HTTP_REQUEST {
       if { [string tolower [HTTP::uri]] contains "debug" ] and [IP::addr [IP::remote_addr] equals 10.10.10.10 ]) } {
          log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"
          discard
       }
    }
  • I want to check against all private address space but was using 10.10.10.10 since there were earlier posts indicating that datagroups may not work with version 9.1.2.

     

     

    I am also getting the error "LOGIN: Re-starting tmm" when processing the following irule when the remote_addr is not 10.10.10.10:

     

     

    when HTTP_REQUEST {

     

    if { [matchclass [HTTP::uri] contains "Debug" ] and (not [matchclass [IP::remote_addr] equals "10.10.10.10" ]) } {

     

    log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"

     

    discard

     

    }

     

     

    The tmm restart drops all connections.
  • Hi,

    I tested and was able to reproduce the TMM restart using the last rule you posted. I think the reason TMM is restarting is that the matchclass function is expecting a class for the comparison, but you are passing it a string.

    I would suggest contacting support to address this failure as the GUI should either prevent you from adding this, or TMM should handle the error more gracefully.

    As far as getting the rule working, I would start by creating a class/datagroup called "internal_hosts_networks_class" with your IP address and the following rule. Verify your request is dropped:

    
    when HTTP_REQUEST {
       if { [matchclass [IP::remote_addr] equals $::internal_hosts_networks_class]) } {   
          log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"
          discard
       }
    }

    If that works, then add the class for the protected URIs (my_protected_uris) and retest. All requests that match the class should be dropped.

    
    when HTTP_REQUEST {
       if { [matchclass [HTTP::uri] contains $::my_protected_uris] } {   
          log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"
          discard
       }
    }

    Then combine these rules and test again:

    
    when HTTP_REQUEST {
       if { [matchclass [HTTP::uri] starts_with $::my_protected_uris] and (not [matchclass [IP::remote_addr] equals $::internal_hosts_networks_class]) } {   
          log local0. "client: [IP::remote_addr] requested [HTTP::host][HTTP::uri] and was dropped"
          discard
       }
    }

    With the last rule, your request should not get dropped if your IP address or network is in the internal_hosts_networks_class.

    Hope this helps.

    Aaron
  • Actually, the TMM restart is noted in CR49375. The trigger for the failure is using a string instead of a class for a matchclass comparison. To avoid the issue make sure to use matchclass correctly:

    
    if { [matchclass $A_STRING contains $::A_CLASS] } {
    ...
    }

    -Aaron
  • Thanks, I was able to get the rule working with datagroups.

     

     

    I am filtering on client side IP address but that is not sufficient. Can I replace the address match with ldap auth? Can this validate against Windows Active Directory? There is an iRule preloaded, _sys_auth_ssl_cc_ldap, but obviously will need some modification.
  • I would imagine you could modify the ldap rule to authenticate against an AD server when clients request a specific URI.

     

     

    I haven't played around with that rule though. You could try searching the forums for the rule name or Active Directory and look for related posts.

     

     

    Perhaps you could test it and post again if you get stuck. Or if anyone else has input...?

     

     

    Aaron