Forum Discussion

Dave_12595's avatar
Dave_12595
Icon for Nimbostratus rankNimbostratus
Oct 14, 2016

Using iRules to make a table with both source IP and URI get request count... "stuck F5 scenario"

We have a situation where we have had instances of the F5 key being stuck in the past which eventually causes an overload on the backend database that the frontend is serving for. Now I like the limit based on number of get requests from an IP address in X time period, but the problem is legitimate traffic sometimes hits 600 GETs within 30 seconds, while other situations is only around 50 GETs in 30 seconds. One way I thought this could be fixed is by using a combination of a concat'd table ID of IP:URI. But when I tried doing a concat of the values I kept getting my counter only = 0. Any one have this type of situation or an example I can check into. Right now I am just setting up in monitor only mode with a syslog server receiving the data.

Here is what we have.

     found at https://devcentral.f5.com/codeshare?sid=565


when RULE_INIT {
     this is the life timer of the subtable object. defines how long this object exist in the subtable
    set static::maxRate 100000
     This defines how long is the sliding window to count the requests. This example allows 10 requests in 3 seconds
    set static::windowSecs 30
    set static::timeout 1200
}

when HTTP_REQUEST {
    if { [HTTP::method] eq "GET" } {
        set getCount [table key -count -subtable [IP::client_addr]]
        log local0. "SERVERNAME: ip=[IP::client_addr] getCount=$getCount timeout=$static::timeout windowSecs=$static::windowSecs URI=[HTTP::uri]"
        if { $getCount < $static::maxRate } {
            incr getCount 1
            table set -subtable [IP::client_addr] $getCount "ignore" $static::timeout $static::windowSecs
        } else {
            log local0. "SERVERNAME: [IP::client_addr] has exceeded the number of requests allowed. $getCount / $static::maxRate TTL $static::windowSecs seconds"
             HTTP::respond 501 content "Request blockedExceeded requests/sec limit."

             return
        }
    }
}

The rate is set high so we are just using it to see how high we can really get under "normal" circumstances.

Thanks

1 Reply

  • This iRule was written for a version 10 of BIG-IP released in 2009(7 years ago). Since then F5 made Layer7 Denial of Service protection a proper built-in feature of the BIG-IP ASM as a DoS Profile, I would recommend that you use ASM and DOS Profile Protection instead of the iRule that you have found as it is only relevant to versions 10.x

     

    Here is the Chapter of F5 Implementation Manual describing configuring the DoS Profile:

     

    Preventing DoS Attacks on Applications

     

    Going back to your example your suggestion of concatenating IP with URL for LEGITIMATE use simply will not work - no legitimate web application will generate 600 GET requests per 30 seconds to the SAME URL - they will all be to different URLs with different purposes - style sheets, images, javascripts, HTML pages etc.

     

    An attacker might do that (e.g. bombard you with hundreds of GET requests to the same URL from the same IP, however it would be trivial to detect your protection and they could easily change their script to add a random bit to the URL (or even something simply like the current timestamp in milli/microseconds). However then this iRules will not work at all, as it will never increase the count. A properly configured DoS profile in ASM can protect from such attacks