Denial of Service (DoS) and Distributed Denial of Service (DDoS) attacks overload a Apache server with abusive request patterns, exhausting worker capacity and pushing legitimate users into timeouts and errors. Application-layer flooding is often cheaper for an attacker than for a server to process, so early blocking of suspicious bursts can preserve availability. A tuned rate-limiting layer reduces performance collapse during traffic spikes caused by bots.
A practical first-line mitigation on Apache is mod_evasive, an access control module that tracks request rates per client IP and per requested URI. When request thresholds are exceeded within a short time window, mod_evasive temporarily blocks the client, typically resulting in 403 responses and log entries that show denials. The module can also write marker files to a dedicated log directory for later inspection.
Commands and paths below target Ubuntu and Debian (/etc/apache2/ layout). Thresholds must be tuned to match real traffic, especially for sites that legitimately fetch many assets or perform frequent background requests. When Apache is behind a reverse proxy or CDN, ensure the real client IP is visible to Apache before enforcing strict per-IP limits, or a shared proxy address can be blocked for everyone.
Related: How to block user agents in Apache
Related: How to log X-Forwarded-For IP in Apache
Related: How to analyze threats in Apache logs
Steps to configure mod_evasive for Apache:
- Install the mod_evasive module package.
$ sudo apt-get install --assume-yes libapache2-mod-evasive Reading package lists... Done Building dependency tree... Done Reading state information... Done The following NEW packages will be installed: libapache2-mod-evasive ##### snipped ##### Setting up libapache2-mod-evasive ...
CentOS and Red Hat typically use mod_evasive with a configuration under /etc/httpd/conf.d, and may require enabling an additional repository.
Related: How to install Raven repository on CentOS, Red Hat, Rocky Linux and AlmaLinux - Enable the evasive module in Apache.
$ sudo a2enmod evasive Enabling module evasive. To activate the new configuration, restart apache2.
- Create a writable directory for mod_evasive logs.
$ sudo install -d -o www-data -g www-data -m 0750 /var/log/mod_evasive
DOSLogDir must point to a directory writable by the Apache runtime user (www-data on Ubuntu and Debian).
- Edit /etc/apache2/mods-available/evasive.conf to set request thresholds.
<IfModule mod_evasive20.c> DOSHashTableSize 3097 DOSPageCount 2 DOSSiteCount 50 DOSPageInterval 1 DOSSiteInterval 1 DOSBlockingPeriod 10 DOSLogDir "/var/log/mod_evasive" #DOSEmailNotify admin@example.com #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 alerts. None DOSSystemCommand Command executed when an attack is detected. None DOSLogDir Directory used for mod_evasive log and marker files. None DOSWhitelist Client IP addresses excluded from blocking. None When traffic arrives via a reverse proxy or CDN, ensure Apache sees real client IP addresses before relying on per-IP limits, or a shared proxy address can be blocked for all users.
Overly strict thresholds can block legitimate clients and monitoring, and enabling DOSSystemCommand for firewall automation can cause lockouts if misconfigured.
- Validate the Apache configuration syntax.
$ sudo apache2ctl -t Syntax OK
- Restart the apache2 service to apply changes.
$ sudo systemctl restart apache2
- Confirm the evasive20_module entry appears in the loaded module list.
$ sudo apache2ctl -M 2>/dev/null | grep -E 'evasive|evasive20' evasive20_module (shared)
- Run a controlled request burst against a local endpoint to confirm blocking triggers.
$ ab -n 1000 -c 10 http://127.0.0.1/ This is ApacheBench, Version 2.3 <$Revision: 1903618 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd Licensed to The Apache Software Foundation, http://www.apache.org/ ##### snipped ##### Complete requests: 1000 Failed requests: 994 (Connect: 0, Receive: 0, Length: 994, Exceptions: 0) Non-2xx responses: 994
A high count of Non-2xx responses commonly indicates mod_evasive is returning 403 during the block window.
Load testing must be performed only against systems under authorized control, and only in a controlled manner that does not impact real users.
- Monitor /var/log/apache2/error.log for evasive20 block events.
$ sudo tail -f /var/log/apache2/error.log [Sat Dec 13 12:40:01.179679 2025] [evasive20:error] [pid 11185:tid 281472643232032] [client 127.0.0.1:40044] client denied by server configuration: /var/www/html/ [Sat Dec 13 12:40:01.179803 2025] [evasive20:error] [pid 11185:tid 281472643232032] [client 127.0.0.1:40048] client denied by server configuration: /var/www/html/
- Check /var/log/mod_evasive for per-client marker files created during blocking.
$ sudo ls -l /var/log/mod_evasive -rw-r--r-- 1 www-data www-data 0 Dec 13 12:40 dos-127.0.0.1
Blocks expire after DOSBlockingPeriod, and thresholds can be tuned to match real traffic patterns without sacrificing protection.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.
Comment anonymously. Login not required.
