mod_security is a free Web Application Firewall (WAF) that comes with Apache, Nginx, and IIS web servers. It is designed to monitor HTTP traffic in real-time in order to detect and mitigate attacks.
ModSecurity which acts as an intrusion detection tool, allows server administrators to react to suspicious activity and is able to prevent SQL Injection, Cross-site Scripting, Malware, Trojans, Bad user agents, Session hijacking, and a lot of other exploits.
ModSecurity comes with a default configuration however there is an OWASP ModSecurity Core Rule Set (CRS) that provides a set of generic attack detection rules that provide a base level of protection for any web application from a wide range of attacks with minimal false alerts.
This tutorial will assume you have already installed the LAMP stack on your server.
Step 1: Install mod_security
Debian
$ sudo apt install libapache2-modsecurity
Restart Apache:
$ sudo systemctl restart apache2
Verify that the version of ModSecurity is 2.8.0 or higher:
$ apt-cache show libapache2-modsecurity
Ubuntu
$ sudo apt-get install libapache2-mod-security2
Restart Apache:
$ sudo systemctl restart apache2
Verify that the version of ModSecurity is 2.8.0 or higher:
$ apt-cache show libapache2-mod-security2
If you use apachectl -M to list all mods, ModSecurity will be listed under the name security2_module. or you could filter the result by using:
$ apachectl -M | grep --color security
The output will be:
security2_module (shared)
CentOS
$ yum install mod_security
Restart Apache by entering the following command:
$ /etc/init.d/httpd restart
Verify that the version of ModSecurity is 2.8.0 or higher:
$ yum info mod_security
Step 2: Enable the OWASP ModSecurity Core Rule Set
Start by renaming the default ModSecurity file (the path below is for Ubuntu/Debian based distros):
$ mv /etc/modsecurity/modsecurity.conf-recommended modsecurity.conf
We then need to download the OWASP ModSecurity CRS from Github. In case you need to install git (if you haven’t installed it before) run the following:
$ sudo apt install git
Download the OWASP ModSecurity CRS:
$ git clone https://github.com/SpiderLabs/owasp-modsecurity-crs.git
From the downloaded location move the relevant files as shown below:
$ owasp-modsecurity-crs
$ mv crs-setup.conf.example /etc/modsecurity/crs-setup.conf
$ mv rules/ /etc/modsecurity/
Open this configuration file:
$ sudo nano /etc/apache2/mods-available/security2.conf
Add the IncludeOptional directive and the Include directive as shown below:
<IfModule security2_module>
# Default Debian dir for modsecurity's persistent data
SecDataDir /var/cache/modsecurity
# Include all the *.conf files in /etc/modsecurity.
# Keeping your local configuration in that directory
# will allow for an easy upgrade of THIS file and
# make your life easier
IncludeOptional /etc/modsecurity/*.conf
Include /etc/modsecurity/rules/*.conf
</IfModule>
Restart Apache for changes to take effect:
$ sudo systemctl restart apache2
Step 3: Test ModSecurity
Open the default Apache configuration and add two additional directives, using the default configuration as an example:
$ sudo nano /etc/apache2/sites-available/000-default.conf
Add the SecRuleEngine and SecRule directives as shown below:
<VirtualHost *:80>
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
ErrorLog ${APACHE_LOG_DIR}/error.log
CustomLog ${APACHE_LOG_DIR}/access.log combined
SecRuleEngine On
SecRule ARGS:testparam "@contains test" "id:1234,deny,status:403,msg:'Our test rule has triggered'"
</VirtualHost>
Restart Apache for changes to take effect:
$ sudo systemctl restart apache2
Curl the index page to intentionally trigger the alarms using the following:
$ curl localhost/index.html?testparam=test
You should expect to get a 403 response code and see the response from the logs.
$ sudo tail -f /var/log/apache2/error.log
Step 4: Review the ModSecurity Configuration Settings
The default configuration file is set to DetectionOnly which logs requests according to rule matches and doesn’t block anything besides what the OWASP CRS provides. This can be changed by editing the file below:
$ sudo nano /etc/modsecurity/modsecurity.conf
Find this line
SecRuleEngine DetectionOnly
and change it to:
SecRuleEngine On
In production, be sure to change this directive only after testing all your rules.
You might also want to change SecResponseBodyAccess. This configures whether response bodies are buffered. This is only necessary if data leakage detection and protection are required. Leaving it On will use up droplet resources and also increase the log file size.
Find this
SecResponseBodyAccess On
and change it to:
SecResponseBodyAccess Off
limit the maximum data that can be posted to your web application using these two directives configure these:
The value mentioned in the configuration file is 12MB:
SecRequestBodyLimit 13107200
The SecRequestBodyNoFilesLimit directive limits the size of POST data minus file uploads. This value should be as low as practical.
The default value in the configuration file is 128KB.
SecRequestBodyNoFilesLimit 131072
The SecRequestBodyInMemoryLimit can also be reviewed as it affects server performance too. This directive specifies how much POSTed data should be kept in the memory (RAM). Additional data will be placed in the hard disk like a swap. if you have plenty of RAM then you can be generous with this value. The default value in the configuration file is 128KB.
SecRequestBodyInMemoryLimit 131072
Step 5: Exclude Hosts and Directories
ModSecurity can block genuine traffic for various reasons so you need to be able to exclude certain directories or entire hosts. Examples are phpMyAdmin where SQL queries will be blocked or CMS application backends like WordPress admin.
To disable mod_security for a complete Virtual Host place the following
<IfModule security2_module>
SecRuleEngine Off
</IfModule>
Inside the VirtualHost section.
For a particular directory:
<Directory "/var/www/website/document_root/wp-admin">
<IfModule security2_module>
SecRuleEngine Off
</IfModule>
</Directory>
You may not want to completely disable ModSecurity. Therefore use the SecRuleRemoveById directive to remove a particular rule or rule chain by specifying its ID.
<LocationMatch "/wp-admin/update.php">
<IfModule security2_module>
SecRuleRemoveById 981173
</IfModule>
</LocationMatch>
Next, we will show you how to set up mod_evasive in addition to this mod_security configuration to help safeguard against DDOS attacks.
Found this article interesting? Follow Brightwhiz on Facebook, Twitter, and YouTube to read and watch more content we post.