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)
sudo rpm -ivh http://dl.fedoraproject.org/pub/epel/7/x86_64/e/epel-release-7-5.noarch.rpm
mod_security
and mod_evasive
by running the following command:sudo yum --enablerepo=epel install mod_security mod_evasive
sudo httpd -M | grep evasive
mod_evasive
is enabled, you will see the following output:evasive20_module (shared)
mod_security
module, run:sudo httpd -M | grep security
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
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
sudo cd /etc/httpd/crs/owasp-modsecurity-crs/
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
sudo nano /etc/httpd/conf/httpd.conf
<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>
sudo apachectl restart
modsecurity.d
directory. You can do this by creating a file named mod_security.conf
.sudo nano /etc/httpd/modsecurity.d/mod_security.conf
<IfModule mod_security2.c>
SecRuleEngine On
SecRequestBodyAccess On
SecResponseBodyAccess On
SecResponseBodyMimeType text/plain text/html text/xml application/octet-stream
SecDataDir /tmp
</IfModule>
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.
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.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>
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.
DOSEmailNotify
. If this option is enabled, an email will be sent to the specified email address whenever an IP address is blacklisted.mod_evasive.conf
file:sudo nano /etc/httpd/conf.d/mod_evasive.conf
DOSEmailNotify
line by removing the #
in front of the line, and change the email address to your own:DOSEmailNotify jdoe@gmail.com
sudo apachectl restart
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
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.mod_security
by running the following command:sudo curl -i http://192.168.1.42/ -A Nessus
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....
mod_evasive
module is working. You can do this using the Perl scripttest.pl
written by Mod_Evasive developers.sudo nano /usr/share/doc/mod_evasive-1.10.1/test.pl
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);
}`
sudo /usr/share/doc/mod_evasive-1.10.1/test.pl
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>
sudo tailf /var/log/messages
Oct 26 15:36:42 CentOS-7 mod_evasive[2732]: Blacklisting address 192.168.1.42: possible DoS attack.