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.

Steps to configure mod_evasive for Apache:

  1. 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

  2. Enable the evasive module in Apache.
    $ sudo a2enmod evasive
    Enabling module evasive.
    To activate the new configuration, restart apache2.
  3. 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).

  4. 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.

  5. Validate the Apache configuration syntax.
    $ sudo apache2ctl -t
    Syntax OK
  6. Restart the apache2 service to apply changes.
    $ sudo systemctl restart apache2
  7. Confirm the evasive20_module entry appears in the loaded module list.
    $ sudo apache2ctl -M 2>/dev/null | grep -E 'evasive|evasive20'
     evasive20_module (shared)
  8. 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.

  9. 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/
  10. 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.

Discuss the article:

Comment anonymously. Login not required.