Getting Started With ModSecurity

by Mike on May 18, 2009 · 2 comments

in Web Server

Using ModSecurity is not easy.  The complexity of your site, your use of PHP, MySQL and other scripting languages will make it more difficult to configure correctly.   Basically, the more complex your site, the more time  you will need to work out issues with rules.  This tutorial will provide you with several important tips to get started with ModSecurity.

Tip #1: Develop A Basic Understanding of ModSecurity
Go to the website, download and read the documentation.  Once that is done you need to know how to find a policy number.

1. Locate a Policy
The rules will be located in the directory you create, probably named modsecurity, and in that directory will be a list of  rules.  These Core Rules provide generic protection from many unknown vulnerabilities.  You will not want to modify the Core Rules, except to turn them on,  as when you update you will erase your settings.  There are two files that have been created to create custom rules.  The first is the modsecurity_crs_15_customrules.conf which lists rules that have been tested for your site and are working effectively.  The second is a bailout ruleset, in other words, if you cannot get something to work you can place it in the modsecurity_crs_65_temporary.conf  until you can get it fixed.  For example, if you need to run ModSecurity but cannot get a specific rule to work you can disable it in this file until you can get it working.

You can see that the file represent different kinds of rules.  The 10_config provides the basic configuration and this is the file that you will use to turn on ModSecurity rules.  The collection of rules provide protection for your web server, detects and protects against bots, crawlers,scanners, it detects and protects against trojans and limits error messages that will provide too much information to attackers.


2. Locate Your Logs
The logs for ModSecurity will be located in /var/log/httpd and you will have two of them, modsec_audit.log and modsec_debug.log.

3. Locate Rule Numbers in Logs
You will need to be able to find the rule numbers so you can work with problems that may develop.  Here you can see the rule number highlighted after the letters “id”.

[Sun May 17 06:11:34 2009] [error] [client] ModSecurity: Access denied with code 501 (phase 2). Pattern match “(?:\\b(?:\\.(?:ht(?:access|passwd|group)|www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\\/etc\\/)” at ARGS:content. [file "/etc/httpd/conf.d/modsecurity/modsecurity_crs_40_generic_attacks.conf"] [line "114"] [id "950005"] [msg "Remote File Access Attempt"] [data "/etc/"] [severity "CRITICAL"] [tag "WEB_ATTACK/FILE_INJECTION"] [hostname ""] [uri "/blog/wp-admin/post.php"] [unique_id "lC3YnH8AAAEAAFoKCK0AAAAL"]

4.  Locate IP Address of a Client in the Logs
You can see the IP Address of the client highlighted.

[Sun May 17 06:11:34 2009] [error] [client] ModSecurity: Access denied with code 501 (phase 2). Pattern match “(?:\\b(?:\\.(?:ht(?:access|passwd|group)|www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\\/etc\\/)” at ARGS:content. [file "/etc/httpd/conf.d/modsecurity/modsecurity_crs_40_generic_attacks.conf"] [line "114"] [id "950005"] [msg "Remote File Access Attempt"] [data "/etc/"] [severity "CRITICAL"] [tag "WEB_ATTACK/FILE_INJECTION"] [hostname ""] [uri "/blog/wp-admin/post.php"] [unique_id "lC3YnH8AAAEAAFoKCK0AAAAL"]

5. Locate Rule File and Line
You will need to know what rule file that is causing you problems and the line number.  These are highlighted.

[Sun May 17 06:11:34 2009] [error] [client] ModSecurity: Access denied with code 501 (phase 2). Pattern match “(?:\\b(?:\\.(?:ht(?:access|passwd|group)|www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\\/etc\\/)” at ARGS:content. [file "/etc/httpd/conf.d/modsecurity/modsecurity_crs_40_generic_attacks.conf"] [line "114"] [id "950005"] [msg "Remote File Access Attempt"] [data "/etc/"] [severity "CRITICAL"] [tag "WEB_ATTACK/FILE_INJECTION"] [hostname ""] [uri "/blog/wp-admin/post.php"] [unique_id "lC3YnH8AAAEAAFoKCK0AAAAL"]

After running the default rules on a web site using PHP, Apache 2 and MySQL database with about 1300 visitors a day I received these violations to the ModSecurity rules.   That is 1636 violations which you will have to determine are they legitimate or false positives.  In other words, to get ModSecurity to work like you want for your site you have to expect to make some custom changes and verify that things are working correctly.

960903 – 55
960015 – 1271
970903 – 84
970902 – 56
960017 – 170

The more you know about ModSecurity the easier it will be but be prepared this is not something to add to your site and walk away, you must keep up with your logs.

Tip #2: Be Prepared to Disable Problem Rules
As much as you will want to install ModSecurity and be done with it, you will probably have issues with several rules that are troubling to solve.  What I did was create the file, modsecurity_crs_65_temporary.conf  and in the file I listed rules to disable until I could resolve the problems.  This should only be a temporary situation but I did this instead of disabling all of ModSecurity.  This strategy allows you to protect most elements of your site without shutting the whole thing down.  Yes, it is a great idea to set up a test server before you go ahead with ModeSecurity but in reality nothing will prepare you for going live, there are just too many variables in terms of how your site is accessed.

Disable rules
If you need to disable a rule you can do that based on the rule number.

SecRuleRemoveById 960015

Whenever you will disable a rule you need to place it after the actual rule so you will want to put the rules that you will disable in a special list at the end of your configuration that is why the file has the number 65.  add them one line at a time.

Tip #3: Create a Custom Rule Set
Regardless of your site you will probably want to create some custom rules. Create your custom rules and place them in modsecurity_crs_15_customrules.conf.  Here are some examples of custom rules that you may consider.

Secure Administration Logins
You certainly will want to secure your login areas for your administrators.  Here is an example of a WordPress login (wp-login.php) that does not allow anyone to access accept the two IP Addresses listed.  They are chained together so you do not need to rewite the rule several times.  The first two lines have the chain option so that it is included with the last line.

SecRule SCRIPT_BASENAME “^wp-login.php$” chain,t:none
SecRule REMOTE_ADDR “!^192\.168\.3\.119$” chain,t:none
SecRule REMOTE_ADDR “!^192\.168\.3\.57$”

You can also add a LocationMatch for a specific rule or rules so that it only applies to a specific directory or file.   This example removes the three rules for this directory so that it will work for WordPress.

<LocationMatch “/wp-includes/”>
SecRuleRemoveById 960010
SecRuleRemoveById 960012
SecRuleRemoveById 950006

Tip #4: Increase SecResponseBodyLimit

If you are using WordPress one of the first modifications that you will want to make is to the SecResponseBodyLimit.  This is the maximum response body size that will be accepted for buffering.  When you go over this limit you will see a 500 Internal Server error.  The default is 512 KB but should be increased.  Here is the setting that will likely work for most WordPress sites.

Edit modsecurity_crs_10_config.conf    and find the line for SecResponseBodyLimit and make changes.

SecResponseBodyLimit 1572864

Without this update you will see some errors with your plugins.

Tip #5: Modify PHP Memory Limit
When you use output buffering ModSecurity keeps the whole page output in memory and as a result you may run out of memory and get errors with php.  Edit your /etc/php.ini and double the memory that you were using in order to allow ModSecurity to keep those pages in memory.

memory_limit = 32M      ; Maximum amount of memory a script may consume

Tip #6: Create Whitelists
You may want some IP Addresses to be whitelisted so that those IP Addresses can work without having any restrictions.

SecRule REMOTE_ADDR “!^192\.168\.3\.119$” “nolog,phase:1,allow”

Previous post:

Next post: