Layer 7 Custom Rules

Custom rules for Layer 7 services can be defined in the "Filtering" page for the Layer 7 (HTTP/HTTPS) port.

Add and check an HTTP rule

Open Services, choose Action → Ports, then choose Action → Filtering on the HTTP or HTTPS port. If you need a new HTTP port, add it with its public port number and backend and click Save first. The example uses HTTP port 8080 with backend 203.0.113.10.

Under Layer 7: Custom Rules, click Add Rules. To follow Example 3, enter RequestUri.Regex("^/api/") in Match expression, choose Drop Rate (Blacklist) in Target type, set Client (IP) limit / second to 1 and Global limit / second to 100, and choose 1 minute for Window. These example limits must be adjusted to the application's expected traffic.

API request rate rule with client and global limits
Review the expression, target, both rate limits and time window before saving.

Click Save rule, reload, and check that the saved row retains the expression and both limits. A syntax error is displayed beside Match expression; correct it and save again before relying on the rule.

Saved API rate-limit expression and target
The saved row confirms the expression and rate limits applied to this HTTP port.

Introduction

A rule is made up of multiple expressions, all expressions must match for the target action to be applied. A target action can be either an operation resulting in a whitelist (ACCEPT) or a blacklist (DROP) with or without a Ratelimit. Ratelimits consist of both a global (per rule) and a client (e.g per IP) component. Whitelisted search agents and other whitelisted clients may not be affected by user custom rules. An ACCEPT target (rate limit) runs early in the mitigation process while a DROP runs later.

Language rules:

The language supports expressions separated by && & || giving precedence to &&. Operators ==, !=,>=, >, <= and < are available. Language constants true and false are also available.

Functions:

NameTypeExampleNotes
HttpVersionStringHttpVersion() == "HTTP/1.0"
HttpHostStringHttpHost() != "google.com"
HttpHeader.GetStringHttpHeader.Get("content_type")Header name lower case, underscore not dash
HttpHeader.RegexBooleanHttpHeader.Regex("content_type","^text/")Header name lower case, underscore not dash. Will return false if header is missing.
HttpHeader.ExistsBooleanHttpHeader.Exists("connection")Header name lower case, underscore not dash
RequestLengthNumericRequestLength() > 3
RequestMethodStringRequestMethod() == "POST"
RequestUri[#]NumberRequestUri[#]() == 3
RequestUri.FullStringRequestUri.Full() == "/test"
RequestUri.RegexBooleanRequestUri.Regex("^/bad/[0-9]+")
RequestQueryString.RegexBooleanRequestQueryString.Regex("^[0-9]+$")
RequestQueryStringBooleanRequestQueryString("key","value")if equals value
RequestQueryStringBooleanRequestQueryString("key")if key exists
RequestQueryString[#]NumberRequestQueryString[#]() == 3
UserAgent.FullStringUserAgent.Full() == "bad actor"
UserAgent.RegexBooleanUserAgent.Regex("bots?")
Client.IpStringClient.Ip() == "1.1.1.1"
Client.Ip.RegexStringClient.Ip.Regex("^1\.1\.1.")All IPs starting with 1.1.1.
Client.ASNNumberClient.ASN() == 123
Client.CountryStringClient.Country() == "AU"
Connection.SuspectVPNBooleanConnection.SuspectVPN()Detects certain Layer4 VPN clients
Connection.MSSNumericConnection.MSS()Layer 4 TCP MSS

Targets

Targets control what happens when a rule is matched. Below the available targets are described.

Verify Traffic

Performs user verification as per the ports mitigation settings (Automated).

Drop All: Hard Disconnect

Rejects the request and disconnects the users connection.

Drop Rate (Blacklist)

Drops all traffic if the traffic to a client exceeds the user configured rate, or total hits on the rule exceeds the separate rate

Accept Rate (Whitelist)

Accepts all traffic (bypassing all reasonable mitigation) as long as the traffic is less than the configured rate from the client, and the separate rate for the rule itself.

Anti Spam Target Alpha

This target is available to enable our customers to target specific spammers and spam runs without software modification. This target injects a CAPTCHA page after the submission of the form, but before transmission of form data to the backend server.

Limitations:

  • Limited to POST requests
  • Limited to requests of less than 8MB in size
  • Limited to requests of type application/x-www-form-urlencoded, this means no file uploads or multipart submissions.

Example Usage: RequestMethod() == "POST" && RequestUri.Regex("^/post/new") -> Anti Spam

It is recommended that filtering be performed on either your backend or as additional custom rules to remove requests that do not meet these conditions.

Example rule: RequestMethod() != "POST" || RequestLength() >= 8388608 || HttpHeader.Get("content_type") != "application/x-www-form-urlencoded" -> Hard Drop

Examples

Example 1: Whitelist API requests with an Authorization header

Match: HttpHeader.Exists("authorization") && UserAgent.Regex("^ApiClient/v[0-9]+$") && RequestUri.Regex("^/api/")

The header and cookie examples below check supplied text, not identity. The backend must still validate credentials and sessions.

Target Type: Accept Rate (Whitelist)

Client (IP) Limit (per second): 10/s

Global Limit (per second): 100/s (10 clients simultaneously maxing limit)

Window: 1 minute

Example 2: Drop all traffic with HTTP header

Match: HttpHeader.Exists("authorization")

Target Type: Drop All: Hard Disconnect

Example 3: Limit traffic to API

Match: RequestUri.Regex("^/api/")

Target Type: Drop Rate (Blacklist)

Client (IP) Limit (per second): 1/s

Global Limit (per second): 100/s (global limit)

Window: 1 minute

Match: HttpHeader.Regex("cookie","(?:^|; ?)sessionid=[a-z0-9]{32}(?:;|$)")

Target Type: Accept Rate (Whitelist)

Client (IP) Limit (per second): 10/s

Global Limit (per second): 100/s (10 clients simultaneously maxing limit)

Window: 1 minute

Not Enough?

Not able to achieve a legitimate goal? An expression not meeting your needs? Then please do contact support. Please be sure to fully describe your use case and any ideas you have in resolving it.