1

I need to set-up a custom filter for a virtual host that requires both ip address checks and URL check. Like so:

_if_  _(_ http-request matches url _and_ ip is from certain host/net range _)_  
      _or_ ip is     from a certain VIP range _then_ let the request through  

I wonder should I try to move IP checks to packet filters and then do the IP check twice (to bypass URL checks for VIP range) or is it OK to leave it within the irule performance wise?

2 Answers 2

2

This is a very common thing to do in an iRule and unless you have a severely loaded BIG-IP you shouldn't have an issue.

If you're concerned, you can turn on iRule timings to see how many CPU cycles are being used by the rule. DevCentral has an old but good article on how to do this. The only out of date part is on v11 you'll want tmsh instead of bigpipe (e.g. "show /ltm rule").

If you really want to avoid iRules, an alternative method is HTTP Class (Local Traffic > Profiles > Protocol > HTTP Class) however this classifies by URI and not source IP. It gives you the ability to send matching URIs to a different pool or return a redirect. You could combine this with the new Source attribute on Virtual Servers in v11.3 to make multiple Virtual Servers that each only handle traffic from a particular network.

However if you have many source ranges to cover, I'd just use an iRule and an address type Data Group (use the "match class .. equals" command to search for the client IP in the Data Group a bit like you would with a routing table).

Packet Filters are brutal and will cause timeouts to the client, whereas the HTTP Class or iRule options let you choose whether to drop the request, choose a different pool, return a redirect, or return an error page.

1
  • Thanks for the answer. I haven't thought of using profiles for this, definitely will look into them, and we went with iRules at the end.
    – iddqd
    May 20, 2013 at 0:10
2

I'd do it all in one iRule.

Here's an example which performs layer 4 ACLs per virtual server:

https://devcentral.f5.com/wiki/iRules.AccessControlBasedOnNetworkOrHost.ashx

You could check the client IP against a data group in CLIENT_ACCEPTED and then check the URI in HTTP_REQUEST using [HTTP::uri].

Here's an example using the class command:

https://devcentral.f5.com/wiki/iRules.class.ashx

when CLIENT_ACCEPTED {
    # Check if the client IP is in the allowed_hosts_dg data group
    if {[class match [IP::client_addr] equals allowed_hosts_dg]}{
        set allowed_ip 1
    } else {
        set allowed_ip 0
    }
}
when HTTP_REQUEST {
    # If the client is a legal source IP check if the HTTP path is in the allowed_paths_dg data group
    if {$allowed_ip == 1 && [class search allowed_paths_dg contain [string tolower [HTTP::path]]]}{
        # allow the request
    } else {
        # Send a 403 blocking response
        HTTP::respond 403 content {Illegal request!}
    }
}

Aaron

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .