Deploying Drupal on an Apache web server with mod_security or adding mod_security to an Apache server with Drupal running should be as easy as installing the relevant packages. Unfortunately, on Red Hat Enterprise Linux (RHEL) 5.4 and 5.5 servers it just isn't so. This is due to a combination of a bug and an outdated Core Rule Set (CRS) in the current mod_security package in the EPEL (Extra Packages for Enterprise Linux) repository. I've seen lots of posts online where people were struggling with this combination so I decided a how-to article was in order.
The problems are entirely in the mod_security package. I've written this from the perspective of having Apache and Drupal already running and adding mod_security, which is how I did it on four web servers recently. However, the order in which you install things really shouldn't matter. I am also assuming that most readers will have already added EPEL to their sources for yum or at least be aware of how to do that. These instructions will also work on other Linux distributions which are binary compatible with RHEL including CentOS and Scientific Linux.
The first step is to install the EPEL package in the repository for mod_security 2.5.12-1.
yum install mod_security
I did try the newer mod_security 2.5.12-3 package which, as I write this, is in EPEL testing and found that it had more serious problems than the current package. There are two problems in the current 2.5.12-1 package. First, the SecDataDir directive is left out of the configuration. Second, no directory for the security data is created. Without the SecDataDir directive pointing to a valid directory owned by the apache user mod_security will generate errors and simply will not run.
I chose to add SecDataDir to /etc/httpd/modsecurity.d/modsecurity_crs_10_config.conf It really doesn't matter where you add the directive in the file. I put it right near the bottom after SecDefaultAction entry. The syntax is:
Since the Apache error_log resides in /var/log/httpd by default I used /var/log/httpd/data but, once again, the location and name of the data directory is entirely up to you. You then need to create the directory, give ownership to the apache user, and enable read, write and execute permissions for apache on that directory as root:
cd /var/log/httpd mkdir data chown apache:apache data chmod 740 data
While the mod_security documentation I read only specified read and write privileges I learned through experience that if you fail to give execute privileges as well you will see multiple permissions errors in your Apache error_log.
At this point if you reload Apache mod_security will function. It will also prevent legitimate edits and content updates in Drupal. This is the result of an outdated, buggy 2.0.5 Core Rule Set in the EPEL package. Those of you who have configured Apache on other Linux distributions are probably familiar with the rules-updater.pl script normally included with mod_security. For some reason the good people at the Fedora Project / Red Hat decided not include that script or, indeed, any of the contents of the util directory in their package. Fortunately it is quite easy to drop in a new rule set without the script.
Download the latest Core Rule Set (2.0.8 as I write this) from the modsecurity.org website as a gzipped tarball and copy it directly into /etc/httpd. Then unzip and untar the file in place:
tar xvzf modsecurity-crs_2.0.8.tar.gz
This will create a directory called modsecurity-crs_2.0.8. If you look at the contents of the directory you will see that it is laid out exactly the same way as your existing modsecurity.d directory. You should copy any localrules.conf and/or modsecurity_crs_48_local_exceptions.conf files from your existing modsecurity.d directory into the new directory. Move your old modsecurity.d directory off somewhere for safe keeping in case you need to go back to it. Then rename modsecurity-crs_2.0.8 to modsecurity.d and reload apache:
mv modsecurity-crs_2.0.8 modsecurity.d apachectl graceful
You will then have mod_security running properly and it will not interfere with any Drupal functionality.