Home   Profile   Fun
#147 Linux  07.01.2008

More security for Apache web servers with mod_security


This tutorial explains the installation and basic setup of mod_security on Gentoo.

ModSecurity is an Apache module which works as a web application firewall (WAF). It operates on the HTTP level and can be used to monitor traffic, detect intrusion attempts and block suspicious requests. Because ModSecurity is located in front of any web application it adds an additional security layer to the system. This layer is independent from all the web applications running behind it. It is ideal to dramatically enhance the security of a system which runs potential unsecure web software, e.g. PHP forums. It is not necessary to touch or have access to the underlying application.

Let's make an example: you run a forum and through a bug in the forum software or the script language an attacker could open a remote shell by using a specially prepared URL. Now, what mod_security does is to notice that the requested URL contains dangerous strings und blocks the request. The result is that the request of the attacker is refused and your server cannot be exploited by this bug.

ModSecurity is a rule-based system. For the above example to work it is necessary that a rule exists which matches this case. You can download a core rule set from ModSecurity which avoids the most common attacks.

The setup of mod_security is very easy and can be done within a few minutes. But the result is tremendous. The documentation of ModSecurity says that more than 70% of all attacks are carried out over the web application level. And this is the level where ModSecurity protects your system.

In general ModSecurity is very flexible and has a lot of features. If needed you can write your own rules or modify the existing rules. You can also whitelist requests by their IP address or URL so that they bypass mod_security completely or skip single rules.

It is obvious that such a system has an impact on the load and memory consumption of the system. At least at the beginning one must have an eye on these parameters.


Ok, here we go.

Make sure that libxml2 is installed. The Apache module mod_unique_id must be present as shared or static in /etc/apache2/apache2-builtin-mods. If it is shared there must be a LoadModule line in httpd.conf.

Install the Apache module mod_security
emerge mod_security 

This package comes with default rules. It is better to remove these rules and download the current core rule set. Check http://www.modsecurity.org/download/direct.html for the most actual download link.
rm /etc/apache2/modules.d/mod_security/*
cd /etc/apache2/modules.d/mod_security/
wget http://www.modsecurity.org/download/modsecurity-core-rules_[VERSION].tar.gz
tar xfvzp modsecurity-core-rules_[VERSION].tar.gz

Add "-D SECURITY" to the APACHE2_OPTS parameters. This will load the module as soon as Apache is started.
vi /etc/conf.d/apache2

The Apache module configuration file. Usually, there is nothing to change here.
vi /etc/apache2/modules.d/99_mod_security.conf

The configuration file of mod_security. This must be studied and adapted, see further below.
vi /etc/apache2/modules.d/mod_security/modsecurity_crs_10_config.conf

The actual rules which are applied reside in the same directory. (We will not touch the rules in this tutorial.)
/etc/apache2/modules.d/mod_security/


The installation is complete. It's time for some basic configuration. The following file should be studied carefully. For now we make just a few modifications.
vi /etc/apache2/modules.d/mod_security/modsecurity_crs_10_config.conf

For the testing phase make sure that mod_security is not yet blocking normal visitors! Change SecRuleEngine from "On" to "DetectionOnly". It is strongly recommended to do that at the beginning. There will be false positives for sure, don't skip this step!
SecRuleEngine DetectionOnly

Set the location of your log files.
SecDebugLog /var/log/apache2/modsec_debug.log
SecAuditLog /var/log/apache2/modsec_audit.log

If you have sites which are very long the following entry may block it:
SecResponseBodyLimit 524288
You can increase this value or you can completely disable the scanning of the HTTP reponse body. (This means that the outgoing content is not checked for data that should not be send to the client, like passwords etc.)
SecResponseBodyAccess Off


Let's start the whole thing
/etc/init.d/apache2 restart

As mod_security is just logging nothing should happen to your website, but I would recommend to check it anyway.


If a suspicious request hits the server you can see a detailed tracking of it in /var/log/apache2/modsec_audit.log. Generally, the log file has several sections per request. Each section starts with a code which has a capital letter at the end:

--ce603818-A--
...
--ce603818-F--
...
--ce603818-Z--

This means all logging data between --ce603818-A-- and --ce603818-Z-- belong to the same request.

For example a request to http://yourdomain/test.php?a=wget will be blocked due to the shell command wget in the URL. You can see which rule caused the blocking. Here the rule 950907 matched due to the wget string:
Message: Access denied with code 501 (phase 2). Pattern match "\\bwget\\b" at ARGS:input. [id "950907"] 
[msg "System Command Injection. Matched signature <wget>"] [severity "CRITICAL"]

It is also important to check the normal apache error log file for errors caused by mod_security. Example:
[Wed Nov 28 06:32:27 2007] [error] SecServerSignature: original signature too short. 
Please set ServerTokens to Full.
This can be fixed by adding "ServerTokens Full" to the httpd.conf file.

It is absolutely necessary to check every single URL of your site and make sure no rule matches these requests. If this is not the case the matching rules must be adapted. See the links at the bottom of this page for instructions. Another possibility is to just disable rules within an Apache context. For example to disable the rules 950910 and 950013 for the script /private/test.pl you can put the following lines into the Apache vhost configuration.
<LocationMatch "/private/test.pl">
  SecRuleRemoveById 950910 950013
</LocationMatch>


After a while you have tuned mod_security so that no errors occur and no normal visitor is blocked anymore. Then it's time to switch to production mode:
SecRuleEngine On
SecDebugLogLevel 0


In the end it's a matter of finetuning the rules. The initial installation is done within minutes but to setup a really robust system some time is needed depending on the running web applications.

ModSecurity is really a great piece of software! It's easy to use, fast to setup and the security dramatically increases.


Links:

ModSecurity FAQ
ModSecurity Documentation
Core rules project page
Handling False Positives and Creating Custom Rules
Open Web Application Security Project


Apache hardening
IDS/IPS systems with Snort
SELinux Training