How to Configure mod_security With Apache on Debian/Ubuntu or CentOS

Configure Mod_security Apache

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


$ 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


$ 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)


$ 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. Incase you need to install git (if you haven’t installed it before) run the following:

Read Also  Grapefruit, the Large, Semi-sweet and Delicious Citrus Fruit

$ sudo apt install git

Download the OWASP ModSecurity CRS:

$ git clone

From the downloaded location move the relevant files as shown below:

$ cd 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

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 [email protected]
    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'"

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:

Read Also  Here's the Difference Between Simulation vs Emulation

$ 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 is 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 of POSTed data should be kept in the memory (RAM). Additional data will be placed in the hard disk like 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

Inside the VirtualHost section.

For a particular directory:

<Directory "/var/www/website/document_root/wp-admin">
    <IfModule security2_module>
        SecRuleEngine Off

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

Next we will show you how to set up mod_evasive in addition to this mod_security configuration to help safeguard against DDOS attacks.