Nginx module that bans clients by their 404/403 error rate, in-worker

dvershinin1 pts0 comments

NGINX Abuse Guard Module: Auto-Ban Scanners and Bots

Skip to main content

Email Us

Message us

Cart<br>Search

Search for:

NGINX / Security / Server Setup

Home

Blog

NGINX Abuse Guard Module: Auto-Ban Scanners and...

NGINX Abuse Guard Module: Auto-Ban Scanners and Bots

by Danila Vershinin, June 26, 2026

We have by far the largest RPM repository with NGINX module packages and VMODs for Varnish. If you want to install NGINX, Varnish, and lots of useful performance/security software with smooth yum upgrades for production use, this is the repository for you.

Active subscription is required.

Open your NGINX error log on any public server and you will see the same thing: a steady drip of 404s probing for /wp-login.php, /.env, /phpmyadmin, and a thousand other paths that do not exist on your site. A vulnerability scanner walking your tree is a wall of 404s. A bot rattling locked admin endpoints is a wall of 403s. A credential-stuffing run is a wall of failed logins. Legitimate visitors almost never generate a burst of errors, but abusers generate little else. That asymmetry is the entire signal the NGINX abuse guard module acts on, and most servers throw it away.

The usual tools do not act on it cleanly. A rate limiter such as limit_req shapes load by request volume, so it slows everyone during a flood and lets the offender back in the instant the rate eases. Tools like fail2ban read the error pattern correctly, but they live outside NGINX: they tail a log file, parse it on a delay, and shell out to the firewall, so the ban lands seconds or minutes after the damage. What you actually want is to read the status codes your server is already returning and evict the clients whose traffic is mostly failure, immediately, inside the worker.<br>🛠️ Related Tools<br>✓ NGINX Config Validator⚡ Website Speed Test📦 NGINX Extras Repository

That is exactly what the NGINX abuse guard module does. It watches the final response status of every request, keeps a small per-client score in shared memory, and the moment a client crosses a threshold of errors it earns a timed ban enforced at the NGINX preaccess phase, before any handler, file lookup, or upstream runs. There is no sidecar, no log shipper, and no scripting layer. The decision happens in compiled C in a few microseconds. This guide shows you how it works, how to install and configure it, and how to roll it out safely against live traffic.

How the NGINX Abuse Guard Module Works

The module reduces abuse detection to three moving parts, all of which live inside the NGINX worker. Understanding them makes every configuration choice below obvious.

A leaky, decaying score per client

Every client identity carries a single small number in a shared-memory zone. Each matching error response adds to that score, and the score continuously bleeds away at a rate of threshold Ă· interval per second. A short, sharp burst of errors pushes the score over the line and trips a ban; a slow trickle of the occasional 404 spread across hours never accumulates. Crucially, that score is one fixed-size record no matter how high you set the threshold, so a single modest zone comfortably tracks the tens of thousands of distinct source addresses a botnet throws at you.

Counting at the header filter, deciding at preaccess

The module hooks two points in the request lifecycle. A header filter inspects the final response status of each request and updates the offending client’s score. Separately, the preaccess phase checks whether the current client is already banned. Because preaccess runs before routing, static-file handling, and upstream proxying, a banned client is turned away at the cheapest possible point: NGINX never spends a cycle serving the request it is about to reject.

A privacy-correct refusal

When a banned client returns, it receives 429 Too Many Requests by default (you choose the code). The response carries a Retry-After header telling honest clients when to come back, and a Cache-Control: private, no-store header so that no shared cache or CDN can ever store one client’s ban page and serve it to another. Identities are folded into a fixed-size digest before they are stored, so keying on something large like $request_uri or a header costs exactly as much memory as keying on a plain IP address.

Installation

Abuse Guard ships as a precompiled, signed dynamic module from the GetPageSpeed repository, so there is no build toolchain to install.

RHEL, CentOS, AlmaLinux, Rocky Linux, Amazon Linux

Install the NGINX abuse guard module from the GetPageSpeed RPM repository:

sudo dnf install https://extras.getpagespeed.com/release-latest.rpm<br>sudo dnf install nginx-module-abuse-guard<br>Then load the module by adding this line at the top of /etc/nginx/nginx.conf, in the main context before any http {} block:

load_module modules/ngx_http_abuse_guard_module.so;<br>Debian and Ubuntu

First, set up the GetPageSpeed APT repository, then install from the APT module page:

sudo apt-get update<br>sudo...

nginx module abuse guard client install

Related Articles