Limit the number of HTTP requests by a client within a specified time

Contributed by: Bhanu

Description

This iRule limits the number of HTTP Requests from a specific client IP address to 100 HTTP Requests per 5 minutes. These values can be easily changed by changing the number of requests and timeout (change values 100 and 300 in the iRule) to the desired values. A Data Group IP_Throttle_List will contain the IP addresses that require throttling. Please remove logging if not required. This code has been tested only in a lab environment with a small data set. The results were as expected. Please test thoroughly before using this on production systems.
Note: The client does not have to be inactive after the throttling begins, to regain access. For example, if the clients reaches the 100 request limit after 250 seconds, the error page will be presented only for the remainder of 50 seconds. After that, the client will get a fresh quota of 100 requests / 5 minutes!
Since this iRule uses tables, this introduces a potential bug. Please see the below link for workarounds. http://support.f5.com/kb/en-us/solutions/public/11000/100/sol11149.html

iRule Source

# This iRule limits the number of HTTP Requests from a specified client IP address to 100 HTTP Requests for 5 minutes
# A Data Group IP_Throttle_List will contain the IP addresses that require throttling

when HTTP_REQUEST {

# Check if the IP address is within the defined list of addresses to throttle
if { [class match [IP::client_addr] equals IP_Throttle_List ] } {

        # Check if there is an entry for the client_addr in the table
        if { [ table lookup -notouch [IP::client_addr] ] != "" } {
        # If the value is less than 100 increment it by one
            log local0. "Client Throttle: Value present for [IP::client_addr]"
                        if { [ table lookup -notouch [client_addr] ] < 100 } {
                        log local0. "Client Throttle: Number of requests from client = [ table lookup -notouch [client_addr] ]"
                        table incr -notouch [IP::client_addr] 1
                        } else {
                            log local0. "Client Throttle: Client has exceeded the number of allowed requests of [ table lookup -notouch [client_addr] ]"
                            # This else statement is invoked when the table key value for the client IP address is more than 100. That is, the client has reached the 100 request limit
                                    HTTP::respond 200 content {
                                        <html>
                                        <head>
                                        <title>Information Page</title>
                                        </head>
                                        <body>
                                          We are sorry, but the site has received too many requests. Please try again later.
                                        </body>
                                        </html>
                                    }
                       }
            } else {
                    # If there is no entry for the client_addr create a new table to track number of HTTP_REQUEST. Lifetime is set to 5 minutes
                    log local0. "Client Throttle: Table created for [IP::client_addr]"
                    table set [IP::client_addr] 1 300
                    }

} else {
    return
}

}

]

The BIG-IP API Reference documentation contains community-contributed content. F5 does not monitor or control community code contributions. We make no guarantees or warranties regarding the available code, and it may contain errors, defects, bugs, inaccuracies, or security vulnerabilities. Your access to and use of any code available in the BIG-IP API reference guides is solely at your own risk.