mod_traffic_guard
Observe or throttle rapid content retrieval without trusting browser user agents.
Enable mod_traffic_guard in Modules. The default mode is observe, which allows
all requests and reports when a configured budget would reject one. enforce
returns HTTP 429 with Retry-After and no-cache headers. off bypasses checks.
Scope and configuration
The guard covers GET/HEAD requests to page, template, HTTP model API and agent
interface controllers. Static assets, POST requests and MQTT messages are excluded.
Custom controllers classified as pages by analytics ({analytics, page}) are also
covered, even without analytics enabled. Dispatch option {traffic_guard, true}
opts another controller in; false opts a
route out. Configuration is under mod_traffic_guard in System Configuration.
| Key | Default | Meaning |
|---|---|---|
| mode | observe | off, observe, enforce |
| period | 60 | Rate period, in seconds |
| request_limit | 120 | Requests replenished per period |
| request_burst | 30 | Maximum request credits |
| max_clients | 5000 | Retained client budgets per site/node |
Budgets are shared by all covered routes for a client IP. Cookies and user agents cannot reset them. There are no automatic admin or claimed-bot exemptions. Shared networks share budgets: calibrate in observe mode before enforcing. Invalid values fall back to defaults. Configuration changes reset transient budgets on the next check. Off mode performs no detection or analytics emission.
IP exceptions
Use System → Traffic guard to edit exact IPv4 and IPv6 allow/block lists (up to
256 addresses per list). Allow takes precedence and bypasses rate limits. Block
entries follow the mode: observe reports would_throttle, enforce returns 429, off
bypasses checks. Lists cover only guarded routes and methods. Saves require a
writable administrator and invalidate the in-memory copy. Invalid entries reject
the whole save. IPv4-mapped IPv6 addresses match IPv4 entries. CIDR networks and
hostnames are not supported. Entries are stored in traffic_guard_ip, with a required note and optional UTC
expiry. Expired rules stop applying immediately; hourly cleanup deletes them.
The admin page shows currently rate-limited IPs on this node and offers timed
blocks with automatically generated notes. Global traffic_guard_allow and
traffic_guard_block lists in zotonic.config are merged on settings load and
shown read-only. See m_traffic_guard for model APIs.
Analytics
With mod_analytics enabled, the default Page requests chart includes Would
throttle and Throttled lines for other and unknown page attempts. A separate
companion recording reserves 10,734 rows within the site budget, preserving the
existing page-view history. Additional breakdowns can use mod_traffic_guard:request.
Each checked request emits one decision, including early rejections. Dimensions
are crawl_behavior (normal, excessive, unknown), guard_action (allow,
would_throttle, throttle), guard_reason (none, request_rate,
state_capacity, unavailable, ip_allow, ip_block), traffic, and type (page, api, other).
Existing request events also receive the three guard dimensions. Unknown means
no reliable guard assessment was available, not a suspected crawler.
Analytics consent and admin exclusions still apply; enforcement never depends on
analytics availability or recording configuration. Guard events and ordinary
request events overlap and should not be added together as a request total.
Limits and privacy
State is transient and bounded: only client IPs and request-rate budgets are tracked, with no paths, query strings or cookies. Every covered request consumes the same budget, including repeated reloads of one page. Idle clients expire and a restart resets all budgets. Limits are node-local, not shared across a cluster.
Unavailable or busy workers and exhausted client capacity fail open with an unknown assessment. This is origin protection, not a DDoS firewall. Use trusted proxy configuration for the client IP and proxy-level protection for distributed attacks. This version does not implement fingerprinting, challenges, account budgets, concurrency limits, or bot verification. See the module README for setup and validation examples.