mod_evasive is an Apache server module which provides action in the event of a Denial of Service attack. It is also can be configured to fail2ban, firewalls and routers. However, using with WordPress is not always easy. The module can lead dysfunction of certain plugins and backend administration.
mod_evasive is easier to configure and maintain/monitor than modsecurity. This person is the developer of mod_evasive:
1 2 | https://github.com/jzdziarski https://www.zdziarski.com/blog/?cat=14 |
I may cause too many false blocks. You need to make the settings quite liberal, check the log to make sure that your visitors or search engine bots are not getting blocked. It is particularly good when you are not closer to your computing device to SSH and check what is happening.
---
This module can cause performance penalties on an active server. Run webpagetest.org’s test to make sure that the site speed has not been too much slower.
Steps to Install mod_evasive on Ubuntu Server
Your server may run MPM Event and PHP-FPM or default MPM Prefork mod_php. Run these commands:
1 2 3 | apt-get update && apt-get upgrade -y apt-get install apache2-utils -y apt-get install libapache2-mod-evasive -y |
You will face a prompt asking you to configure a Postfix mail server for email notifications. You can select the option “Internet site” and continue the installation. mod_evasive uses /bin/mail
for sending email alerts and you need to have a mail server installed and working to receive email notifications. You can skip the mail server setup for now. It is better to configure it later rather than skip the email notification.
Now, if you run this command:
1 | apachectl -M | grep evasive |
You’ll get the output:
1 | evasive20_module (shared) |
Do not activate the module before reading the next sub-header.
The module’s name is evasive
, so these commands will work to activate and deactivate the module:
1 2 3 4 | ## apache2 enable module a2enmod evasive ## apache2 disable module a2dismod evasive |
Before enabling and disabling, always run:
1 | apachectl configtest |
…and reload settings in this way:
1 | /etc/init.d/apache2 reload |
These will avoid facing this kind of odd error – Config variable ${APACHE_RUN_DIR} is not defined.
For the common main modules of Apache (such as rewrite), you can restart or reload in any you want. The users of these modules are not as many as the common modules. They may have minor bugs.
How to Configure mod_evasive for WordPress
The configuration file of mod_evasive is located at /etc/apache2/mods-enabled/evasive.conf
. By default, there will be examples of too many restrictive settings and whitelisting will not be done. Open the file:
1 | nano /etc/apache2/mods-enabled/evasive.conf |
This is a liberal setting which you can try:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | <IfModule mod_evasive20.c> DOSWhiteList 127.0.0.1 DOSWhiteList 127.0.0.* # DOSWhiteList <your-server-ip> # DOSWhiteList <your-ip> DOSHashTableSize 32768 DOSPageCount 20 DOSSiteCount 50 DOSPageInterval 10 DOSSiteInterval 10 # kept lower value for your testing DOSBlockingPeriod 10 # DOSSystemCommand "su - someuser -c '/sbin/... %s ...'" DOSLogDir "/var/log/mod_evasive" </IfModule> |
DOSPageCount is the limit for the number of requests for the same page by an IP address, per second set by DOSSiteCount.
DOSPageCount below 10 catches false positives. 20 to 30 is an acceptable value.
DOSSiteCount requires to be 50 to 100.
DOSHashTableSize default value is 3097. Setting it to 32768 will make the server faster but will suck RAM. You should check the memory consumption.
If some plugins at WordPress admin disturb you, then increase the values.
Create the log directory. On Ubuntu, the default user for apache2 is www-data
(you can check it by running ps aux | grep apache
command):
1 2 3 4 5 | mkdir -p /var/log/mod_evasive ## Check the user name ps aux | grep apache # give permission to write chown www-data:www-data /var/log/mod_evasive |
Run:
1 | apachectl configtest |
…and reload settings:
1 | /etc/init.d/apache2 reload |
Test With a Script
There is a default test script here:
1 | /usr/share/doc/libapache2-mod-evasive/examples/test.pl |
But that requires adjustment, change the site address on this line PeerAddr=> "your-site.com:443"
from your-site.com
to your’s one. Also I have changed for(0..100)
to for(0..200)
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #!/usr/bin/perl # test.pl: small script to test mod_dosevasive's effectiveness use IO::Socket; use strict; for(0..200) { my($response); my($SOCKET) = new IO::Socket::INET( Proto => "tcp", PeerAddr=> "your-site.com:443"); if (! defined $SOCKET) { die $!; } print $SOCKET "GET /?$_ HTTP/1.0\n\n"; $response = <$SOCKET>; print $response; close($SOCKET); } |
I have kept these files in this GitHub repo. You can wget the script, open, edit, chmod and execute:
1 2 3 4 5 | cd ~ wget https://raw.githubusercontent.com/AbhishekGhosh/mod_evasive-settings-for-WordPress/main/test.pl nano test.pl chmod +x test.pl sudo perl test.pl |
It will give you either 403 error or 400 error. This is a test result on a test server:
400 error is coming out of other settings before mod_evasive can handle the request. Disable other such system and test.
Try to increase the values facing errors. It is better to keep this module active.