Limit Request Rate

The page rules dropdown menu offers multiple categorized action options. The “DoS Attack Actions” category contains actions for controlling request traffic.

Select the Limit Request Rate action:

Request rate-limiting works based on the Leaky Bucket Algorithm, and we can manage requests using the following three parameters:

  1. Key: By default, this is the client’s IP address, but it can be changed to URI, URI parameters, or Cookies via the dropdown menu. You can select one or multiple keys. If URI parameters or Cookies are selected, an additional Argument field must be specified;
  2. Regulating Threshold: Requests with a rate below this threshold are unaffected; requests with a rate between this threshold and the rejection threshold will be processed with a delay;
  3. Rejection Threshold: Requests exceeding this rate will be directly returned with HTTP status code 503, meaning the request is rejected.

These two threshold parameters default to requests per second but can also be set as requests per minute.

If both thresholds are set the same, requests exceeding that rate will be immediately rejected.

Requests will be rate-limited based on the set key. Possible keys include:

  • Client IP address, e.g., 1.1.1.1.
  • The request’s URI, for example, /openresty.
  • URI query parameters, such as the arg1 in /openresty?arg1=val1.
  • Request Cookie, like the key c1 in cookie: c1=v1.
  • The first IP address in the X-Forwarded-For request header, such as the 1.1.1.1 in X-Forwarded-For: 1.1.1.1, 1.1.1.2.
  • The last IP address in the X-Forwarded-For request header, such as the 1.1.1.2 in X-Forwarded-For: 1.1.1.1, 1.1.1.2.
  • Specific HTTP request headers, such as Host.
  • Encrypted Cookie: Rate limiting is based on the encrypted cookies generated by OpenResty Edge. When a client request does not carry an encrypted cookie, the rate-limiting will fall back to a configuration without encrypted cookies. Therefore, encrypted cookie must be used in conjunction with other keywords.

Upon reaching the rate limit condition, the system can perform the following preset actions, defaulting to Return Default Error Page:

  • Close request connection: Immediately terminate the connection with the client, no longer responding to the request.
  • Return error page, default status code 503: When rate limiting is in effect, display an error page with a 503 status code to the user, suggesting the server is temporarily unable to process the request.
  • Complete hCaptcha verification: Require the user to pass an hCaptcha challenge to differentiate between human and machine behavior.
  • Complete OpenResty Edge Captcha verification: Use OpenResty Edge’s captcha system to verify the user’s identity.
  • Redirect verification: Redirect the request to a verification page, which must be passed before continuing access.
  • JavaScript challenge: Require the user’s browser to execute JavaScript code to verify non-robotic operation.

By default, this action applies to all requests, and the rate is limited based on the client address. However, this rule might be too broad, so we can apply more fine-grained condition control in the following ways. Like action settings, conditions are organized by categories such as URI, request, response, and client information.

Example 1:

Here, we take Country from client information as an example, setting the action to be executed only for requests from Japan:

Enter Japan’s country code JP; codes for all continents, countries, provinces, and cities can be found in the Edge documentation: client-country.

After completing the action and condition settings, click the “Create” button in the lower right corner to apply the rule. The page will automatically redirect back to the rule list page.

Example 2:

Next, we demonstrate how to use Encrypted cookies. Encrypted cookies must be used with other keywords, as they fall back to rate limiting based on other keywords when the cookie is absent.

Encrypted Cookie

We have selected Client Address and Encrypted Cookie for keywords, allowing only one request per minute.

Create Action

We haven’t set up any proxy or other actions here, so the expected behavior is that normal requests return a 404 status, while requests that are rate-limited return a 503 status. Save the configuration.

Release Configuration

Release the configuration.

Then, send a test request: curl localhost -H 'Host: test.com' -I

HTTP/1.1 404 Not Found
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Set-Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw=; Path=/; Secure
Req-ID: 0000008000045ed343300002

At this point, Set-Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw=; Path=/; Secure is returned because there was no cookie initially, thus returning one. If we send another request without the cookie, it will be rate-limited based on Client Address.

Send the second test request with Encrypted Cookie: curl localhost -H 'Host: test.com' -I -H 'Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw='

HTTP/1.1 404 Not Found
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Req-ID: 0000008000045ed343300003

This is the first request with the encrypted cookie, so it is not rate-limited.

Send the third test request with Encrypted Cookie: curl localhost -H 'Host: test.com' -I -H 'Cookie: _oredge_rl=G63GyXMjH89ClH7dgJgSAo+f7FbPVTD5KAdkLbnkjhw='

HTTP/1.1 503 Service Temporarily Unavailable
Content-Type: text/html;charset=utf-8
Transfer-Encoding: chunked
Connection: keep-alive
Req-ID: 0000008000045ed343a80004

The request has been rate-limited.