On this page

Security: firewall, WAF, rate limiting and bot protection

Every request to a proxied hostname passes through these layers at the edge, in this order. A layer that blocks or challenges stops the request.

  1. IP access rules — block or allow an IP, range or ASN.
  2. Firewall rules — your expression rules.
  3. Honeypot and blocked networks.
  4. Page rules (redirects and rewrites; see Proxy and SSL).
  5. Rate limiting.
  6. Cache — a cache hit is served here.
  7. Bot protection.
  8. Custom WAF rules, then the managed WAF.
  9. Your origin.

Rules apply to the domain and every hostname below it. Changes reach the edge within about 15 seconds. Every block, challenge and log action is recorded as a security event.

IP access rules

Block or allow traffic by IP address, CIDR range or AS number, for one domain or for every domain in your account. In the panel, every security event has Block and Allow buttons that pick the target (the IP, its /24 or /64, or its network's ASN) and the scope (this domain, or all your domains); each domain lists its rules under Bot protection → Access rules.

API: GET/POST /api/v1/domains/{domainId}/network-policy, GET/POST /api/v1/account/network-policy, and DELETE .../{ruleId}.

json
{"value": "AS64500", "action": "block", "note": "scraper network"}
{"value": "203.0.113.0/24", "action": "allow", "note": "office"}
ActionEffect
block403 for every matching request.
allowThe request passes: no later layer scores, limits or blocks it.

Which rule wins, highest first:

  1. a rule on the domain;
  2. the domain's exemption of an account-wide rule (PUT/DELETE /api/v1/domains/{domainId}/network-policy/account/{ruleId}/exemption; GET /api/v1/domains/{domainId}/network-policy/account lists the account rules with exempt for that domain; these three routes show or switch account-wide rules, so an API token limited to some domains gets 403 on them and an unrestricted token is needed);
  3. an account-wide rule.

Within one level the most specific match wins, and on a tie block beats allow. Account-wide ranges must be /8 (IPv4) or /32 (IPv6) or narrower. Private and loopback addresses and GreenProxy's own servers are never blocked: a rule that would cover a platform address is refused with 400.

Firewall rules

Expression rules modelled on the Cloudflare rules language, per domain or account-wide. API: GET/POST /api/v1/domains/{domainId}/firewall-rules, GET/POST /api/v1/account/firewall-rules, PUT/DELETE /api/v1/firewall-rules/{id}. Check an expression before saving it with POST /api/v1/firewall-rules/validate.

json
{
  "name": "Protect admin",
  "expression": "http.request.uri.path starts_with \"/wp-admin\" and not ip.src in {203.0.113.0/24}",
  "action": "block",
  "priority": 10
}
Fields
Clientip.src, ip.geoip.country, ip.geoip.asnum, ip.category (residential, hosting, vpn, tor, unknown)
Requesthttp.host, http.request.uri, http.request.uri.path, http.request.uri.query, http.request.method, http.user_agent, http.referer, http.request.headers["name"], ssl
Botbot.score (0 = certainly automated, 100 = human)

Operators: == != < <= > >= (or eq ne lt le gt ge), contains, starts_with, ends_with, matches (RE2), wildcard, in {…}, not in {…}; combine with and, or, not; lower(field) for case-insensitive comparisons.

Actions are block, challenge (proof-of-work), allow (the request bypasses every later layer: rate limiting, bot protection and the WAF) and log. Firewall rules run whether or not bot protection is enabled. Lower priority runs first. Each rule reports hits, the security events it produced in the last 7 days.

Managed WAF

Every domain is protected by the OWASP Core Rule Set, maintained by the platform and evaluated after your own WAF rules.

LevelCoverage
standard (default)CRS paranoia level 1. The minimum for every domain.
strictAdds paranoia level 2: broader detection, more false positives.

GET/PUT /api/v1/domains/{domainId}/managed-waf. The response reports the CRS version and how many rules each level evaluates. Blocks are recorded with source managed_waf and the CRS rule id.

Request arguments are inspected wherever the application reads them: the query string, application/x-www-form-urlencoded forms, JSON bodies (application/json and any +json type, and JSON-shaped bodies sent with another type), where each value is named by its path such as user.name or items[0].id, and multipart/form-data text fields. Uploaded file names are inspected as FILES; file contents are not. The first 64 KiB of a body and at most 1000 arguments are inspected. At strict, a request is also refused when some of its arguments lie beyond that window (rule 200007) or its body does not parse as the declared type (rule 200002); a file upload larger than the window is not refused for that reason.

Custom WAF rules

A single regular expression matched against one part of the request, for cases the firewall language does not cover (for example the request body).

GET/POST /api/v1/domains/{domainId}/waf-rules, PUT/DELETE /api/v1/waf-rules/{id}.

FieldValues
targetpath, header (with header_name), ip, method, user_agent, body (first 8 KiB)
patternRE2 regular expression; prefix (?i) for case-insensitive
actionblock, challenge, log (continue evaluating), allow (skip remaining rules)
priorityHigher runs first
json
{"target": "user_agent", "pattern": "(?i)sqlmap|nikto", "action": "block", "priority": 0, "enabled": true}

Rate limiting

Every proxied hostname is rate limited. Without a rule of your own the default is 20 requests per second per client IP, burst 40, with a challenge when exceeded.

GET/POST /api/v1/domains/{domainId}/ratelimit-rules, PUT/DELETE /api/v1/ratelimit-rules/{id}.

json
{
  "name": "Login",
  "path_pattern": "/login*",
  "methods": ["POST"],
  "requests_per": 5,
  "per_seconds": 60,
  "count_by": "ip",
  "action": "block",
  "response_status": 429,
  "retry_after": 60,
  "mitigation_seconds": 600,
  "enabled": true
}
FieldMeaning
requests_per / per_seconds / burstToken bucket: refills at requests_per / per_seconds per second, holds up to burst (default derived from requests_per).
count_byip, ip_path, session, header, cookie (name in count_key), asn or country.
path_pattern, methods, expressionWhich requests count: a path wildcard, HTTP methods, and an optional firewall expression.
actionblock (status 429, 403 or 503, optional custom body and Retry-After), challenge (proof-of-work page), tarpit (serve an endless maze of decoy pages) or log.
mitigation_secondsKeep the key limited this long after it first exceeds the rate.
rate_headersSend X-RateLimit-Limit and X-RateLimit-Remaining.
priorityLower runs first.

Bot protection

Bot protection scores each request from 0 (automated) to 100 (human) and allows, challenges or blocks it. It is off until you enable it on the domain's Bot protection tab (GET/PUT /api/v1/domains/{domainId}/antibot-settings; PUT replaces the whole object, so send back what GET returned with your changes).

The score combines request shape, TLS and HTTP/2 fingerprints, request rate, session behaviour over time (page timing, crawl patterns, asset loading, URL enumeration) and the network the client connects from. Every event lists the signals that contributed.

SensitivityBlock belowChallenge below
low1025
medium (default)2550
high4070
SettingDefaultEffect
under_attackoffChallenge every visitor without a clearance.
under_attack_interactiveoffIn Under attack mode, require the interactive check from everyone.
js_challengeonAllow the invisible JavaScript check.
tls_fingerprinting, rate_behaviour, behaviour_analysisonSignal groups.
verify_search_botsonConfirm Googlebot, Bingbot, Applebot, DuckDuckBot and Yandex by reverse DNS; verified crawlers are always allowed.
hosting_policy / vpn_policy / tor_policychallenge / challenge / blockallow, challenge or block traffic from datacenter, commercial VPN and Tor networks.
ipv6_subnet_blockoffWhen a scored block hits an IPv6 address, block its /48 for ipv6_subnet_block_minutes (default 30).

The challenge. Visitors in the challenge band see a short interstitial. Most browsers pass an invisible check and continue automatically; the rest, and Tor or VPN visitors, get an interactive check with a proof-of-work. A clearance lasts 30 minutes and is bound to the visitor's address and browser.

Honeypot. Each domain has a trap path (honeypot_path). Add the Disallow: line shown in the panel to your robots.txt; any client that requests the path anyway is blocked on the domain for 10 minutes.

Check an address. GET /api/v1/ip-lookup?ip=203.0.113.5 returns its network, AS number, organisation, country and category.

Security events

Every block, challenge and log action is recorded with the client address and its network, the request line, User-Agent, the rule or score and the reasons.

API
GET /api/v1/domains/{domainId}/security-eventsOne domain; filter by source and action, page with offset or the before/before_id cursor.
GET /api/v1/domains/{domainId}/security-events/summary24-hour totals, hourly series and top addresses.
GET /api/v1/security-events, .../summaryThe same across every domain in the account.

Sources: antibot, honeypot, waf, managed_waf, ratelimit, firewall, ip_rule, blocked_network. Allowed requests are not recorded.

Events are kept for your account's log retention period (GET/PUT /api/v1/account/log-retention). To keep them longer or analyse them in your SIEM, stream them to S3, Splunk, Datadog or any HTTPS endpoint (Alerts and webhooks → Log export).

Limits

  • Rate-limit and behaviour state is kept per edge node.
  • Residential proxy networks cannot be identified by network alone; the behaviour, fingerprint and challenge signals apply to them.
  • TLS and HTTP/2 fingerprint signals require HTTPS.