HTTP Request Throttle version 10.1 and above

Problem this snippet solves:

I tested the CMP friendly version from Kirk Bauer click here and found out that it counts the number of Requests per TCP connection, but when from the same source openes multiple connections with one Request per connection then the rule does not throttle the requests.

This iRule is based on subtables that utilizes the lifetime parameter of subtable objects. It offers a sliding window of seconds that can be defined and counts all GET requests that come within this sliding window from the same sourceIP, regardless of the number of TCP connection the client openes. My Rule below uses the client source IP as user identifier (userID) and counts in a slidings window the number of GET reqests. this iRule is based on the counting subtable options that came with version 10.1 and is tested with version 11.1. Here the Link to the subtable counting options: https://devcentral.f5.com/Default.aspx?tabid=63&articleType=ArticleView&articleId=2381

Basically what happens is that each user (in this case the client source IP) creates a subtable with the name and adds an object in this subtable for each GET request. Each object has a lifetime timer that removes the object after it expires. Before the new request is send to the server the number of existing objects in the subtable is counted and if a threshold is reached LTM responds with a predifined HTTP message - in this case 501 HTTP status code with a text.

so... here is my iRule. enjoy:

How to use this snippet:

This iRule requires LTM v10. or higher.

Code :

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

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

            return
        }
    }
}

Tested this on version:

10.0
Published Mar 18, 2015
Version 1.0

Was this article helpful?

2 Comments

  • Hello,

     

    If I can have one question.

     

    Let's start that we have the "TCP-Based Detection" defined in the DOS-Profile properties where threshold are defined by the Source-IP and/or Device-IP.

    The blocking mode blocks the requests when an attack has been detected according to the threshold values configured.

     

    Now, what is then the difference between this irule and the policy "TCP-Based Detection" defined in the DOS-Profile properties?

     

    Thanks a lot for this explanation.

    Luigi

     

  • Hello dears,

     

    sorry for the direct approach.

    Has anyone had the same question and faced the same thing?

     

    Thanks