Denial of Service (DoS) request floods can exhaust Apache worker capacity and turn a reachable site into slow responses, timeouts, or repeated 403 and 503 errors long before the host fully runs out of CPU or bandwidth. Blocking abusive request bursts close to the web server reduces wasted application work and helps normal traffic keep moving during scans, brute-force attempts, and short-layer HTTP floods.
On Ubuntu and Debian, mod_evasive is a practical first-line module for per-client request-rate blocking. It tracks repeated requests by client address and by requested URI, then temporarily denies further requests once a configured threshold is crossed, with the block decisions visible in the Apache error log and in marker files under DOSLogDir.
Thresholds that are too strict can block asset-heavy pages, health checks, or busy API clients, so tune them against normal traffic before using aggressive values in production. If Apache sits behind a load balancer, reverse proxy, or CDN, make sure it sees the real client address through a trusted mod_remoteip configuration, or the shared proxy address can be blocked instead of the offending client.
$ sudo apt-get update && sudo apt-get install --assume-yes libapache2-mod-evasive apache2-utils ##### snipped ##### Setting up libapache2-mod-evasive (1.10.1-6build1) ... apache2_invoke: Enable module evasive
apache2-utils provides ab for the verification step, and the package install usually enables evasive automatically on current Ubuntu and Debian builds.
$ sudo a2query -m evasive evasive (enabled by maintainer script)
If the query reports disabled, run a2enmod evasive before continuing.
$ sudo install -d -o www-data -g www-data -m 0750 /var/log/mod_evasive
Use a directory that is writable by the Apache runtime user but not by unprivileged shell users.
<IfModule mod_evasive20.c> DOSHashTableSize 3097 DOSPageCount 2 DOSSiteCount 50 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 DOSLogDir "/var/log/mod_evasive" #DOSEmailNotify admin@host.example.net #DOSSystemCommand "su - someuser -c '/sbin/... %s ...'" #DOSWhitelist 127.0.0.1 </IfModule>
| Parameter | Description | Default |
|---|---|---|
| DOSHashTableSize | Hash table size used for tracking clients and requests. | 3097 |
| DOSPageCount | Requests to the same page or URI within the page interval. | 2 |
| DOSSiteCount | Total requests for any object from the same client IP within the site interval. | 50 |
| DOSPageInterval | Interval for the page count threshold. | 1 second |
| DOSSiteInterval | Interval for the site count threshold. | 1 second |
| DOSBlockingPeriod | Block duration in seconds after a threshold is exceeded. | 10 seconds |
| DOSEmailNotify | Email address to receive blacklist alerts. | None |
| DOSSystemCommand | Command executed when a client is blacklisted. | None |
| DOSLogDir | Directory used for lock and marker files. | None |
| DOSWhitelist | Client IP addresses excluded from blocking. | None |
DOSWhitelist can be repeated for multiple trusted sources, and the upstream module also accepts trailing-octet wildcards when needed.
When traffic arrives through a reverse proxy or CDN, configure mod_remoteip with trusted proxy settings first so the rate limits apply to the real client address.
Overly strict thresholds can block legitimate traffic, and DOSSystemCommand firewall automation can lock out users or monitoring if it is misconfigured.
$ sudo apache2ctl -t Syntax OK
Related: How to test Apache configuration
$ sudo systemctl restart apache2
$ sudo apache2ctl -M 2>/dev/null | grep evasive20 evasive20_module (shared)
$ ab -n 200 -c 10 http://127.0.0.1/ This is ApacheBench, Version 2.3 <$Revision: 1903618 $> ##### snipped ##### Complete requests: 200 Failed requests: 194 (Connect: 0, Receive: 0, Length: 194, Exceptions: 0) Non-2xx responses: 194
A high count of Non-2xx responses usually means mod_evasive is returning 403 during the block window.
Only run load tests against systems you control and only at a level that does not disrupt real users.
$ sudo grep -E "evasive20|client denied" /var/log/apache2/error.log | tail -n 3 [Wed Apr 08 04:43:59.011209 2026] [evasive20:error] [pid 3903:tid 281473216717088] [client 127.0.0.1:50136] client denied by server configuration: /var/www/html/ [Wed Apr 08 04:43:59.011231 2026] [evasive20:error] [pid 3903:tid 281473191354656] [client 127.0.0.1:50142] client denied by server configuration: /var/www/html/ [Wed Apr 08 04:43:59.011257 2026] [evasive20:error] [pid 3903:tid 281473216717088] [client 127.0.0.1:50152] client denied by server configuration: /var/www/html/
$ sudo ls -l /var/log/mod_evasive total 4 -rw-r--r-- 1 www-data www-data 5 Apr 8 04:43 dos-127.0.0.1
Blocks expire after DOSBlockingPeriod, so raise the thresholds or whitelist only trusted automation if legitimate traffic is being denied.