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.

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.

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:
| Name | Type | Example | Notes |
|---|---|---|---|
| HttpVersion | String | HttpVersion() == "HTTP/1.0" | |
| HttpHost | String | HttpHost() != "google.com" | |
| HttpHeader.Get | String | HttpHeader.Get("content_type") | Header name lower case, underscore not dash |
| HttpHeader.Regex | Boolean | HttpHeader.Regex("content_type","^text/") | Header name lower case, underscore not dash. Will return false if header is missing. |
| HttpHeader.Exists | Boolean | HttpHeader.Exists("connection") | Header name lower case, underscore not dash |
| RequestLength | Numeric | RequestLength() > 3 | |
| RequestMethod | String | RequestMethod() == "POST" | |
| RequestUri[#] | Number | RequestUri[#]() == 3 | |
| RequestUri.Full | String | RequestUri.Full() == "/test" | |
| RequestUri.Regex | Boolean | RequestUri.Regex("^/bad/[0-9]+") | |
| RequestQueryString.Regex | Boolean | RequestQueryString.Regex("^[0-9]+$") | |
| RequestQueryString | Boolean | RequestQueryString("key","value") | if equals value |
| RequestQueryString | Boolean | RequestQueryString("key") | if key exists |
| RequestQueryString[#] | Number | RequestQueryString[#]() == 3 | |
| UserAgent.Full | String | UserAgent.Full() == "bad actor" | |
| UserAgent.Regex | Boolean | UserAgent.Regex("bots?") | |
| Client.Ip | String | Client.Ip() == "1.1.1.1" | |
| Client.Ip.Regex | String | Client.Ip.Regex("^1\.1\.1.") | All IPs starting with 1.1.1. |
| Client.ASN | Number | Client.ASN() == 123 | |
| Client.Country | String | Client.Country() == "AU" | |
| Connection.SuspectVPN | Boolean | Connection.SuspectVPN() | Detects certain Layer4 VPN clients |
| Connection.MSS | Numeric | Connection.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
Example 4: Whitelist traffic with a specific Cookie set
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.
