loop-detect: CDN-Loop header support for request loop prevention
Debian/Ubuntu installation
These docs apply to the APT package nginx-module-loop-detect provided by the GetPageSpeed Extras repository.
- Configure the APT repository as described in APT repository setup.
- Install the module:
sudo apt-get update
sudo apt-get install nginx-module-loop-detect
Show suites and architectures
| Distro | Suite | Component | Architectures |
|----------|-------------------|-------------|-----------------|
| debian | bookworm | main | amd64, arm64 |
| debian | bookworm-mainline | main | amd64, arm64 |
| debian | trixie | main | amd64, arm64 |
| debian | trixie-mainline | main | amd64, arm64 |
| ubuntu | focal | main | amd64, arm64 |
| ubuntu | focal-mainline | main | amd64, arm64 |
| ubuntu | jammy | main | amd64, arm64 |
| ubuntu | jammy-mainline | main | amd64, arm64 |
| ubuntu | noble | main | amd64, arm64 |
| ubuntu | noble-mainline | main | amd64, arm64 |
ngx_http_loop_detect_module allows NGINX to use the CDN-Loop header to prevent request loops.
Table of Content
- Name
- Table of Content
- Status
- Synopsis
- Installation
- Directives
- loop_detect
- loop_detect_cdn_id
- loop_detect_status
- loop_detect_max_allow_loops
- Variables
- $loop_detect_current_loops
- $loop_detect_proxy_add_cdn_loop
- How It Works
- Author
- License
Status
This Nginx module is currently considered experimental. Issues and PRs are welcome if you encounter any problems.
Synopsis
http {
# Enable the module in a location block
loop_detect on;
loop_detect_cdn_id my_cdn_id;
loop_detect_status 508;
loop_detect_max_allow_loops 10;
server {
listen 80;
server_name example.com;
location / {
proxy_set_header CDN-Loop $loop_detect_proxy_add_cdn_loop;
proxy_pass http://example.upstream.com;
}
}
}
Directives
loop_detect
Syntax: loop_detect on | off;
Default: loop_detect off;
Context: http, server, location
Enables or disables the loop detection for the current scope. When enabled, the module checks the CDN-Loop header to track the number of hops and blocks requests exceeding the allowed limit.
loop_detect_cdn_id
Syntax: loop_detect_cdn_id string;
Default: loop_detect_cdn_id openresty;
Context: http, server, location
Sets the unique identifier for your clusters. This identifier is used to parse and track loops in the CDN-Loop header.
loop_detect_status
Syntax: loop_detect_status code;
Default: loop_detect_status 508;
Context: http, server, location
Sets the HTTP status code returned when a request exceeds the allowed loop limit. The code must be between 400 and 599 (client or server errors).
loop_detect_max_allow_loops
Syntax: loop_detect_max_allow_loops number;
Default: loop_detect_max_allow_loops 10;
Context: http, server, location
Sets the maximum number of allowed loops before blocking the request. The number must be greater than 0.
Variables
$loop_detect_current_loops
Returns the current detected loop count extracted from the CDN-Loop header. This value represents the number of hops your request has already passed through CDN nodes.
$loop_detect_proxy_add_cdn_loop
Constructs the new CDN-Loop header value to be sent to downstream proxies. This value includes:
- The current CDN node's identifier and incremented loop count (e.g.,
my_cdn; loops=2). - Remaining other entries from the original
CDN-Loopheader (if any).
Example Usage:
location / {
proxy_set_header CDN-Loop $loop_detect_proxy_add_cdn_loop;
proxy_pass http://backend;
}
How It Works
-
Detection: The module parses the
CDN-Loopheader to identify the number of hops. Each hop is formatted as: Format:Cdn-Loop: <cdn_id>; loops=<count>, ...Example:Cdn-Loop: my_cdn; loops=2, another_cdn; loops=1. -
Tracking: The current hop count (current_loops) is extracted from the header. The module increments the count and constructs a new
CDN-Loopvalue for downstream proxies. -
Blocking: If the detected loop count exceeds
loop_detect_max_allow_loops, NGINX returns the configuredloop_detect_status(e.g., 508).