Forum Discussion

fmoghimi's avatar
fmoghimi
Icon for Nimbostratus rankNimbostratus
Jul 09, 2021

Connection limit for a URI path.

Hi

 

I just got the question to put a connection limit for a single URI path of a virtual server.

The virtual server is used for multiple applications. so like, www.example.com/app1 or /app2.

So If i set the connection limit for the example.com virtual server, the connection limit is set for both app1 and app2. The virtual server has a rewrite profile for this.

Is it possible to set a connection limit for a single application?

The only way I can see it work is an irule, but i'm pretty new to irules, I haven't found anything on the internet about this.

Any help is appreciated. Thanks in advance!

  • Hi,

    You are looking after limiting L7 requests and not L4 connections which are not aware of the /app1 /app2... paths.

    This iRule is a good starting point :

    # 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
    }
     
    }

    Source: https://clouddocs.f5.com/api/irules/Limit-the-number-of-HTTP-requests-by-a-client-within-a-specified-time.html

    You can remove the class match part if not needed. And you can add the check of the exact path requested by the client using :

    if { [HTTP::uri] starts_with "/app1" } {
         ...
     }

    Let me know if that helps