Apache mod_security on CentOS 5 x86_64
In the journey of rebuilding my dedicated server to create a secured cloud server, I was trying to find out what are the potential issues, besides network intrusion through various ports, and services on my server. I found numbers ranging from 70% to 85% of all intrusions actually occur by way of applications. Specifically, I am running many php and a couple Perl applications. Not to mention, I was allowing MySql to be accessed external to my machine in the past.
As I googled various options to secure Apache, I found mod_security module (http://www.modsecurity.org/).
So I started off by trying several different tutorials (listed below). So it all seemed fairly straight forward from the examples.
- Install the plugin: yum, rpm or compile
- Load module in mod_security.conf: or directly into httpd.conf
- Load Rules: define them manually, and/or load them from additional configuration files
I spent several very long days trying to get this to work.
The first time I tried to get this to work, I just got the plugin from the CentOS yum repository. Then I configured the plugin, no errors where thrown, and Apache seemed to be working fine. I wanted to try to understand how to test or verify what I have done.
I first used a simple example from http://blog.bodhizazen.net/linux/how-to-mod_security-ubuntu-904/ that has you create simple php file on your server
//bad.php <? $secret_file = $_GET['secret_file']; include ( $secret_file); ?>
then try to access that page with a rogue command:
http://www.yourdomain.com/bad.php?secret_file=/etc/passwd
At first I kept getting a blank page, then I added some html that would print <h2>bad.php</h2> just to ensure the page was loaded. The page was succeeding, and not giving a 403 error as expected. I then tried to use the curl command that was given on the example
user1@home# curl -i "http://www.yourdomain.com/bad.php?secret_file=/etc/passwd"
HTTP/1.1 200 OK
Date: Tue, 28 Apr 2009 22:24:11 GMT
Server: Apache/2.2
Vary: Accept-Encoding
Content-Length: 860
Content-Type: text/html
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/bin/sh
bin:x:2:2:bin:/bin:/bin/sh
sys:x:3:3:sys:/dev:/bin/sh
sync:x:4:65534:sync:/bin:/bin/sync
games:x:5:60:games:/usr/games:/bin/sh
man:x:6:12:man:/var/cache/man:/bin/sh
lp:x:7:7:lp:/var/spool/lpd:/bin/sh
mail:x:8:8:mail:/var/mail:/bin/sh
news:x:9:9:news:/var/spool/news:/bin/sh
uucp:x:10:10:uucp:/var/spool/uucp:/bin/sh
proxy:x:13:13:proxy:/bin:/bin/sh
www-data:x:33:33:www-data:/var/www:/bin/sh
backup:x:34:34:backup:/var/backups:/bin/sh
list:x:38:38:Mailing List Manager:/var/list:/bin/sh
irc:x:39:39:ircd:/var/run/ircd:/bin/sh
gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/sh
nobody:x:65534:65534:nobody:/nonexistent:/bin/sh
libuuid:x:100:101::/var/lib/libuuid:/bin/sh
sshd:x:101:65534::/var/run/sshd:/usr/sbin/nologin
postfix:x:104:107::/var/spool/postfix:/bin/false
Well, what I did not see will hurt me… Well, It has already!
Ok, so I setup mod_security what’s going on then?
Well, the example I ended up did not Load any libraries as documented in the modsecurity.org install guide. I thought, these examples (several of them), all professed to work, why does mine not work?
The answer has not been easy, and unfortunately, not 100% clear either. I will list through the 3 main items I had trouble with and the solution I found to finally get this to work
1. Correctly loading x86_64 libraries.
As I described an issue with several different libraries in the blog http://baselogic.com/blog/archives/294 This was effecting many items in my server configuration. I also found that my libxml2 was having issues while I was hacking different configurations to get something to either work, or to throw some errors. Once this issue was solved, I go to thinking about my second issue:
2. Get correct mod_security module for x86_64.
As with my libxml2 and other libraries, I started tracking down what version of mod_security I was actually running. I was running a version I got through some means in one of these tutorials. Then I found an updated module from Jason Litka (http://www.jasonlitka.com/2007/08/24/mod-security-packages-now-available/). The install went fine, and even came with a new configuration file and rules. But then I kept getting errors trying run a configcheck on Apache:
Starting httpd: httpd: Syntax error on line 210 of /etc/httpd/conf/httpd.conf: Syntax error on line 5 of /etc/httpd/conf.d/mod_security.conf: Cannot load /etc/httpd/modules/mod_security2.so into server: /etc/httpd/modules/mod_security2.so: undefined symbol: ap_get_server_banner
I was not the only person that was having this issue.
The solution alluded to trying to rebuild apache and other modules, and I was not interested in compiling Apache to get this to work. I wanted to use yum as much as possible. So I kept researching, and quickly realized that the latest version I could find via any yum repository, was 2.5.0, yet on modsecurity.org, the latest available version was 2.5.9 ion source version, as I did not see x86_64 CentOS listed for the update version.
Well, I downloaded this package and installed this manually because I had no other choice. But it was very easy. Now even though at the time I did not know it, this issue was resolved.
3. Find the Configuration that properly works.
After installing x86_64 version of mod_security, I still was unable to get even a simple test to work, thus my module was not working.
After several really long days hacking at various options over and over again. I was quite frustrated that, what I thought to be a simple configuration and module was such an issue to resolve. This is the part of the solution that is not 100% clear to me. I believe I had tried this configuration before, but somehow on m=one of my hacks, this configuration worked:
LoadFile /usr/lib64/libxml2.so LoadFile /usr/lib64/liblua.so.5.0 #Load mod_unique_id and mod_security 2 LoadModule unique_id_module modules/mod_unique_id.so LoadModule security2_module modules/mod_security2.so <IfModule mod_security2.c> Include modsecurity.d/*asl*.conf #Enable mod_security SecRuleEngine On SecDefaultAction log,auditlog,deny,status:403,phase:2,t:lowercase,t:replaceNulls,t:compressWhitespace #Log Configuration SecAuditEngine RelevantOnly SecAuditLogParts ABCFHZ SecAuditLogType Serial SecAuditLog logs/mod_security2.log #SecAuditLogStorageDir logs/audit SecAuditLogRelevantStatus ^(?:5|4\d[^4]) #General Settings #SecTmpDir /temp #SecUploadDir /temp/uploads #SecUploadKeepFiles RelevantOnly #Rules </IfModule>
Now finally, I was able to get the desired result:
user1@home# curl -i "http://www.yourdomain.com/bad.php?secret_file=/etc/passwd"
HTTP/1.1 403 Forbidden
Date: Thu, 30 Apr 2009 17:20:03 GMT
Server: Apache
Content-Length: 283
Content-Type: text/html; charset=iso-8859-1
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /bad.php
on this server.</p>
<hr>
<address>Apache Server at yourdomain.com Port 80</address>
</body></html>
…
Conclusion:
Although x86_64 seems to not be widely used and supported with many tutorials, I can say that once I was able to get this plugin working, I was able to quickly and easily see the benefits from various web application intrusions. I also gained a better insight as to how to identify OS issues and how to notice them next time.
References:
- ModSecurity: http://www.modsecurity.org
- How-To Forge: http://www.howtoforge.com/apache_mod_security
- Jason Litka: http://www.jasonlitka.com/2007/08/24/mod-security-packages-now-available/
- My Whiteboard: http://www.my-whiteboard.com/linux-admin/protect-your-web-server-from-security-attacks-using-modsecurity.html
- Atomic: http://www.atomicorp.com/wiki/index.php/Atomic_ModSecurity_Rules
the end…
RSS Feed