Install question ...
On Ubuntu 24.04 running Apache 2.4.58 (running MPM_PREFORK), I've done the following:
% apt-get update && apt-get install apache2-dev build-essential wget
% cd /usr/local/src
% sudo wget https://github.com/jvdmr/mod_evasive/archive/refs/tags/2.4.0.tar.gz -O mod_evasive-2.4.0.tar.gz
% sudo tar xzf mod_evasive-2.4.0.tar.gz
% cd mod_evasive-2.4.0
% mv mod_evasive24.c mod_evasive.c
% apxs2 -i -a -c mod_evasive.c
% cp /usr/local/src/mod_evasive-2.4.0/mod_evasive.conf /etc/apache2/mods-available/evasive.conf
% vim /etc/apache2/mods-available/evasive.conf
(Replace `<IfModule mod_evasive.c>` with `<IfModule evasive_module>`)
% apache2ctl configtest
% a2enmod evasive
% systemctl restart apache2
% apache2ctl -M |grep evasive
It installs great, with two minor warnings, one fixed (according to AI assistants) like so:
line 544:
- fprintf(file, "%ld\n", getpid());
+ fprintf(file, "%d\n", (int)getpid());
Config tests are happy, it's enabled, and my loaded modules show:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
evasive_module (shared)
expires_module (shared)
filter_module (shared)
headers_module (shared)
mime_module (shared)
mpm_prefork_module (shared)
negotiation_module (shared)
php_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
socache_shmcb_module (shared)
ssl_module (shared)
status_module (shared)
I'm uncertain whether evasive_module needs to load below mpm_prefork_module, will test that next and report any delta.
I'm testing it via shell script from another server like so ...
for i in {1..10}; do
curl -s -H 'Cache-Control: no-cache' \
-H 'Pragma: no-cache' \
-o /dev/null -w "%{http_code}\n" \
https://myneatowebsite.com/index.html
done
... but all I get are 200s. Not a 301 in sight. If I enable the log file, it stays empty. I've changed the log files permissions, that fixes nothing.
EDIT: I've added this Apache log line right at the beginning of the access_checker() function:
line 447:
ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, "[mod_evasive] access_checker hook fired for URI: %s from IP: %s", r->uri, r->useragent_ip);
... then recompiled, reinstalled, and restarted Apache. The log DOES show the hook is firing. So the module is running. The problem lies within its logic (maybe how it calculates hashes, checks tables, or interacts with the DOSLogDir despite permissions seeming okay).
Any advice on what I can do to get this working?
EDIT: Further error logging reveals that the problem is per-process memory with Prefork MPM. My server uses mpm_prefork, this was coded for mpm_event. This version of mod_evasive uses an in-memory structure (stored in cfg->hit_list) to keep track of hit counts. The hit count state is not shared between the different Apache processes. So the count for a specific IP+URI combination rarely increments beyond 1 before a different process handles the next request and starts over.
EDIT 2:
Turns out this code will simply never work with mpm_prefork. Prefork spins up independent Apache child processes, each with its own in-memory rate counter, so mod_evasive never accumulates enough hits in any single process to hit its blocking threshold. Without a shared-memory or central datastore for counters, each child resets its count on its own, preventing global per-IP rate limiting under the prefork MPM. So without drastic recoding, this mod will never work under mpm_prefork.
But removing mpm_prefork in favor of mpm_event + PHP-FPM, even though FPM takes a bit of configuring, gives MUCH better performance, and now mod_evasive works.
I very much recommend a big "DOES NOT WORK WITH mpm_prefork" warning in the readme.
I agree that the Readme is a bit brief in talking about the drawbacks when using the module with mpm_prefork. The limits set are much less effective and has more randomness in blocking requests. Worse is that it's more likely for legitimate users to get blocked since they keep their connection open and so hit the same process while attackers who open a fresh connection each requests are hitting a different processes most of the time.