How to Configure ModSecurity and mod_evasive for Apache on CentOS 7

Introduction

ModSecurity and mod_evasive are free Apache modules which protect your web server from various brute force or (D)DoS attacks, including SQL injection, cross-site scripting, session hijacking, and many others. These modules can be deployed and integrated into your infrastructure without having to modify your internal network.
In this tutorial I will explain how to install, configure and integrate ModSecurity and mod_evasive with Apache on CentOS 7.

Requirements

  • A server running CentOS v. 7 with Apache installed
  • A static IP Address for your server

Installing ModSecurity and mod_evasive

First you will need to install the EPEL yum repository on the server. Run the following command to install and enable the EPEL repository:
sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
Now you can install mod_security and mod_evasive by running the following command:
sudo yum --enablerepo=epel install mod_security mod_evasive
After installing these modules, you can verify them by running the following commands:
sudo httpd -M | grep evasive
If mod_evasive is enabled, you will see the following output:
evasive20_module (shared)
To test the mod_security module, run:
sudo httpd -M | grep security
If mod_security is enabled, you will see the following output:
security2_module (shared)

Configure ModSecurity

Now that the installation is complete and verified, you will need to install a Core Rule Set (CRS) in order to use mod_security. The CRS provides a web server with a set of rules on how to behave under certain conditions. You can download and install the latest OWASP CRS by running the following commands:
sudo mkdir /etc/httpd/crs
sudo cd /etc/httpd/crs
sudo wget https://github.com/SpiderLabs/owasp-modsecurity-crs/tarball/master
sudo tar -xvf master
sudo  mv SpiderLabs-owasp-modsecurity-crs-* owasp-modsecurity-crs
Now go to the installed OWASP CRS directory:
sudo cd  /etc/httpd/crs/owasp-modsecurity-crs/
In the OWASP CRS directory, you will find a sample file with rules modsecurity_crs_10_setup.conf.example. You need to copy its contents into a new file named modsecurity_crs_10_setup.conf.
sudo cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
Now you need to tell Apache to use this file along with the module. You can do this by editing Apache main configuration file:
sudo nano /etc/httpd/conf/httpd.conf
Add the following lines at the end of file:
<IfModule security2_module>
    Include /etc/httpd/crs/owasp-modsecurity-crs/modsecurity_crs_10_setup.conf
    Include /etc/httpd/crs/owasp-modsecurity-crs/base_rules/*.conf
</IfModule>
Save and close the file and restart Apache to reflect changes.
sudo apachectl restart
Last, it is a good idea to create your own configuration file within the modsecurity.d directory. You can do this by creating a file named mod_security.conf.
sudo nano /etc/httpd/modsecurity.d/mod_security.conf
Add the following lines:
<IfModule mod_security2.c>
    SecRuleEngine On
    SecRequestBodyAccess On
    SecResponseBodyAccess On 
    SecResponseBodyMimeType text/plain text/html text/xml application/octet-stream 
    SecDataDir /tmp
</IfModule>
Save and close the file and restart Apache to reflect the changes.
sudo apachectl restart

Configure mod_evasive

The mod_evasive module reads its configuration from /etc/httpd/conf.d/mod_evasive.conf which can be easily customized. You don't need to create a separate configuration file because there are no rules to update during a system upgrade.
The default mod_evasive.conf file has the following directives enabled:
<IfModule mod_evasive20.c>
    DOSHashTableSize    3097
    DOSPageCount        2
    DOSSiteCount        50
    DOSPageInterval     1
    DOSSiteInterval     1
    DOSBlockingPeriod   10
</IfModule>
You can change these values according to the amount and type of traffic that your web server needs to handle.
  • DOSHashTableSize: This directive specifies how mod_evasive keeps track of who's accessing what. Increasing this number will provide a faster lookup of the sites that the client has visited in the past.
  • DOSPageCount: This directive specifies how many identical requests to a specific URI a visitor can make over the DOSPageInterval interval.
  • DOSSiteCount: This is similar to DOSPageCount, but corresponds to how many requests overall a visitor can make to your site over the DOSSiteInterval interval.
  • DOSBlockingPeriod: If a visitor exceeds the limits set by DOSSPageCount or DOSSiteCount, their IP will be blocked during the DOSBlockingPeriod amount of time. During this interval, they will receive a 403 (Forbidden) error.
One of the most important configuration options you need to change is DOSEmailNotify. If this option is enabled, an email will be sent to the specified email address whenever an IP address is blacklisted.
You can do this by editing the mod_evasive.conf file:
sudo nano  /etc/httpd/conf.d/mod_evasive.conf
Uncomment the DOSEmailNotify line by removing the # in front of the line, and change the email address to your own:
DOSEmailNotify   jdoe@gmail.com
Save and close the file and restart Apache to reflect the changes.
sudo apachectl restart
Note: You need to have a functioning mail server on this server for this email alert to work.

Testing ModSecurity

To test mod_security you can use curl to send HTTP requests to the Apache server. One of the ModSecurity default rules is to reject requests that have a User Agent of "Nessus". This is intended to deny information to attackers who use automated scanners.
You can check mod_security by running the following command:
sudo curl -i http://192.168.1.42/ -A Nessus
You should see a 403 Forbidden response, as shown below on this page. ModSecurity has blocked the request, because the User Agent identifies it as a Nessus scan.
HTTP/1.1 403 Forbidden
Date: Tue, 27 Oct 2015 11:08:39 GMT
Server: Apache
X-Frame-Options: SAMEORIGIN
Last-Modified: Thu, 16 Oct 2014 13:20:58 GMT
Accept-Ranges: bytes
Content-Length: 4897
X-XSS-Protection: 1; mode=block
Content-Type: text/html; charset=UTF-8

Testing mod_evasive

Now it's time to test to make sure that the mod_evasive module is working. You can do this using the Perl scripttest.pl written by Mod_Evasive developers.
Before running this script, you need to make some changes:
sudo nano /usr/share/doc/mod_evasive-1.10.1/test.pl
Find the line for(0..100) { Replace 100 with 200. Find the line PeerAddr=> "127.0.0.1:80"); Replace 127.0.0.1 with yourserverip (192.168.1.42).
#!/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=> "192.168.1.42:80");
  if (! defined $SOCKET) { die $!; }
  print $SOCKET "GET /?$_ HTTP/1.0\n\n";
  $response = <$SOCKET>;
  print $response;
  close($SOCKET);
}`
Save and exit.
Now, run the script:
sudo  /usr/share/doc/mod_evasive-1.10.1/test.pl
You should see the following output:
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden</code></pre>
ModEvasive also logs to syslog when the IP address is blocked. You can check the log file using:
sudo tailf /var/log/messages
You should see the following output:
Oct 26 15:36:42 CentOS-7 mod_evasive[2732]: Blacklisting address 192.168.1.42: possible DoS attack.
Enjoy....