DataScript: avi.vs.rate.limit

Function avi.vs.rate_limit( type, string_to_limit, [defer_action=False] )
Description Rate limits entities of various kinds.
Events HTTP_REQ
Parameter type is a string specifying the type of rate limiter. Currently type must be set to avi.RL_CUSTOM_STRING.

string_to_limit is a unique identifier of the entity that should be rate limited. This is a string, such as a JsessionID, a username or an IP address.

defer_action is an optional True/False flag. If True, the given_action (described below) is not taken when the rate limit has exceeded the threshold. If the rate limit action is set to discard the connection, the rule is not processed any further. The defer_action parameter could be used to prevent the connection from being dropped by the profile, allowing further DataScript logic to process before an action could be manually enacted later by the DataScript.
Returns The function returns two optional, purely informational variables:

count_exceeded is true when the count is exceeded.

given_action is the action the rate limit profile is configured to execute as long as the defer_action parameter is not set. The given_action is configured within the rate limit profile via the Avi CLI. This information may be used to manually recreate these actions within the DataScript. The possible options are:

avi.RL_ACTION_CLOSE_CONN – Closes the TCP connection. No further rule processing will occur.

avi.RL_ACTION_LOCAL_RSP – Returns a statically configured HTTP response page. No further rule processing will occur.

avi.RL_ACTION_REDIRECT – Redirects the request to another URL. No further rule processing will occur.

avi.RL_ACTION_NONE – Do nothing. A significant log for the request will be generated, but the request will be forwarded on to the chosen pool server.

Additional Configuration

DataScript must be configured to reference a rate limit profile, which is nested within a HTTP application profile, which is attached to one or more virtual services. This rate limit profile association is made via the CLI or API. The following CLI syntax shows how to modify the profile:


configure applicationprofile <application_profile_name>
dos_rl_profile
rl_profile
custom_requests_rate_limit
count <max_number_of_requests_allowed>
period <time_period_during_which_those_requests_should_be_allowed>
-- Rate limiter allows requests as long as count is not exceeded within period seconds
action type <action_type>
-- Default for action_type is avi.RL_ACTION_CLOSE_CONN
save
-- Repeat until you exit the application profile 

To configure the rate limit profile on the UI:

  1. On the Controller, navigate to Templates.
  2. Under the Application tab, select and edit your application profile (or create a new one).
  3. Select the DDoS tab.
  4. Under Add Rate Limit, select Rate Limit all HTTP requests that map to any custom string to all URLs of the virtual service.
  5. Enter the values for Threshold and Time Period. For this particular use-case select Action as Send HTTP Local Response and Status Code as 429. You do not need to upload a file.
  6. Click on Save.

Example 1

Basic rate limiting

  • Rate limit clients based upon a unique ID, in this case an HTTP header value
  • The number of requests per poeriod of time are defined within the rate limit profile
avi.vs.rate_limit(avi.RL_CUSTOM_STRING, avi.http.get_header("userID"))

Example 2

Rate limiting with a penalty timer

  • Extend the logic of rate limiting by adding a penalty box
  • Normally rate limit only allows X number of connections within
  • Y period of time. With the penalty box, when a user exceeds the limit,
  • They may not send any requests until the penalty timer expires.
userID = avi.http.get_header("userID")
penalty_time = 900
-- Check if the userID has been added to the table of blocked users
-- The table is used to create a "penalty box" of 900 seconds
-- If user is not in the list then given_action variable is nil
given_action, remaining_time = avi.vs.table_lookup(userID, 0)
if given_action then
   avi.http.close_conn()
else
-- if userID is not in the penalty box table
  count_exceeded, given_action = avi.vs.rate_limit(avi.RL_CUSTOM_STRING, userID, true)
  if count_exceeded then
-- user just crossed the threshold and is now added to the penalty box table
     avi.vs.table_insert(userID, given_action, penalty_time)
-- Since the optional defer_action flag from avi.vs.rate_limit() is set to true
-- The rate limit profile is not enforcing the limit, so it is enforced below
     avi.http.close_conn()
   end
 end

Note: This DataScript function is supported in Avi Vantage 17.2.13 and releases thereafter.