Installing ModSecurity & OWASP Core Rule Set on an Amazon EC2 Linux (CentOS) Instance

NOTE: This post has been updated to include the requirement of mod_unique_id.

As part of some investigations at work I have been playing around with ModSecurity, the open source web application firewall (WAF), and the standard set of rules provided by OWASP. All our infrastructure is hosted with Amazon AWS so I thought that it would be useful to drop down the steps I took to get this working on a bare bones Amazon Linux box.

Install ModSecurity

You can, of course, compile ModSecurity from the sources but it is easier to install via yum, however, it is part of the epel repo which isn’t enabled by default so you need to run as follows:

sudo yum install mod_security --enablerepo=epel

Now check that the ModeSecurity engine is on:

more /etc/httpd/conf.d/mod_security.conf

And look for the following line:

SecRuleEngine on

Download & configure the OWASP files

The Open Web Application Security Project (OWASP) has created a set of rules for ModSecurity – the OWASP ModSecurity Core Rule Set, whose “goal is to provide an easily “pluggable” set of generic attack detection rules that provide a base level of protection for any web application.”.

You can add these rules to ModSecurity as follows:

cd ~
 sudo wget
 sudo unzip -q master
 cd /etc/httpd
 sudo mv ~/SpiderLabs-owasp-modsecurity-crs-* modsecurity-crs
 cd modsecurity-crs
 sudo cp modsecurity_crs_10_setup.conf.example modsecurity_crs_10_config.conf

Next you need to ensure that the OWASP config files are included when ModSecurity loads. To do this edit mod_security.conf

 cd ../conf.d
 sudo nano mod_security.conf

And add the following lines in the section # ModSecurity Core Rules Set and Local configuration

 Include modsecurity-crs/local_rules/*.conf
 Include modsecurity-crs/modsecurity_crs_10_config.conf
 Include modsecurity-crs/base_rules/*.conf

The easiest way to do this is with the following SED command:

 sudo sed -i "s/Include modsecurity.d\/local_rules\/\*.conf/Include modsecurity.d\/local_rules\/\*.conf\n Include modsecurity-crs\/modsecurity_crs_10_config.conf\n Include modsecurity-crs\/base_rules\/\*.conf/" /etc/httpd/conf.d/mod_security.conf

Next you need to enable mod_unique_id Apache module which is required by mod_security:

sudo sed -i "s/#LoadModule unique_id_module modules\/ unique_id_module modules\/" /etc/httpd/conf/httpd.conf

Finally restart Apache:

sudo service httpd restart

If apache fails to start with a message similar to:

[alert] (EAI 2)Name or service not known: mod_unique_id: unable to find IPv4 address of “ip-x-x-x-x”

Add a line to your instance’s host file:

sudo nano /etc/hosts ip-x-x-x-x localhost

Testing that the rules are working

If you are lucky all this will work with your application without modification, although that isn’t guaranteed of course. The question is how do you safely test that the rules are working. One way is to try with this simple SQL injection attempt on the URL as follows:'%20or%20'1'%20=%20'1&password=1'%20or%20'1'%20=%20'1

If the rules are working then you should be shown a 403 error. You can also check the httpd error log (/var/log/httpd/error_log) to check any messages written there by ModSecurity.

Things to watch out for

During my tests with ModSecurity I discovered a couple of things that you should be aware of. Firstly you need to be testing using a domain name and not directly using the instances IP address. Secondly, ModSecurity and CloudFlare don’t play nicely together. ModSecurity seems to take exception to the cookies that are placed there by CloudFlare. There maybe a workaround for this but none was immediately obvious to me.


Protecting your web application should be a high priority for all and ModSecurity and the OWASP rules give you a good starting point. The issue is that you are relying on a set of rules written by someone else that you (probably) don’t understand and won’t be certain if they are going to conflict with your application. They are also no substitute for ensuring your application itself is as watertight as possible. However, if you have nothing else and cannot afford a commercial WAF then they are a great addition.