Update : This how-to is reported to work in Ubuntu 8.04 as well.
What is mod_security you ask ?
Mod Security can significantly increase the security of your Apache installation.
What Is ModSecurity?
ModSecurity is a web application firewall that can work either embedded or as a reverse proxy. It provides protection from a range of attacks against web applications and allows for HTTP traffic monitoring, logging and real-time analysis.
It is also an open source project that aims to make the web application firewall technology available to everyone.
Do not think you need this ? Follow along with the examples and decide for yourself (This tutorial assumes you already have Apache and php5 installed).
First, let us look at the default Apache behavior. I will use “ubuntuVPS” as the server of interest.
“Insecure” Example 1 – curl
Use curl to obtain information on the server (bodhi@home is a remote machine connecting to “ubutnuVPS”. You can test all this with any browser if you wish, simply use your server’s home page).
bodhi@home# curl -i ubuntuVPS
HTTP/1.1 200 OK
Date: Tue, 28 Apr 2009 22:06:21 GMT
Server: Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.1 with Suhosin-Patch
Last-Modified: Tue, 28 Apr 2009 21:39:54 GMT
ETag: "50d4a-2d-468a44dadbe80"
Accept-Ranges: bytes
Content-Length: 45
Vary: Accept-Encoding
Content-Type: text/html
< html>< body>< h1>It works!< /h1>< /body>< /html>
Looks like this in your browser (the famous It works! page)
It works!
See how with a single command we already know the server is Ubuntu running Apache 2.2.11 and PHP 5.2.6 ?
“Insecure” Example 2 – bad .php
For this I will ask you to create a file “/var/www/insecure.php”
Put the following code in the file :
< ? $secret_file = $_GET['secret_file'];
include ( $secret_file); ?>
Note: I had to put a space at the front of the php tag “< ?”, remove it.
Now what ? Open a browser and enter http://ubuntuVPS/insecure.php?secret_file=/etc/passwd
I shall use curl in this example:
bodhi@home# curl -i "http://ubuntuVPS/insecure.php?secret_file=/etc/passwd"
HTTP/1.1 200 OK
Date: Tue, 28 Apr 2009 22:24:11 GMT
Server: Apache/2.2.11 (Ubuntu) PHP/5.2.6-3ubuntu4.1 with Suhosin-Patch
X-Powered-By: PHP/5.2.6-3ubuntu4.1
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
YIKES !!!
Install and configure mod_secure
There was a time when installing mod_security was a bit difficult, now it is as easy as :
sudo apt-get -y install libapache-mod-security
The “hard part” is that we need to configure mod_security and obtain a few rules.
Configure mod_security
Using any editor, make a file “/etc/apache2/conf.d/modsecurity2.conf” and put the following contents in the file.
< ifmodule mod_security2.c>
Include conf.d/modsecurity/*.conf
< /ifmodule>
Note: I had to add a space at the front of the tag “< ifmodule mod_security2.c>” and “< /ifmodule>”, remove them.
By default, mod_security logs to /etc/apache2/logs, the following commands will put the log in /var/log/apache2/mod_security and create a symbolic link back to /etc/apache2/logs
sudo mkdir /var/log/apache2/mod_security
sudo ln -s /var/log/apache2/mod_security/ /etc/apache2/logs
Download and install rules
Download rules from here
As of this writing, the rule set was “modsecurity-core-rules_2.5-1.6.1.tar.gz”, you may need to adjust accordingly as new rules are released.
sudo mkdir /etc/apache2/conf.d/modsecurity
cd /etc/apache2/conf.d/modsecurity
sudo wget http://www.modsecurity.org/download/modsecurity-core-rules_2.5-1.6.1.tar.gz
sudo tar xzvf modsecurity-core-rules_2.5-1.6.1.tar.gz
sudo rm CHANGELOG LICENSE README modsecurity-core-rules_2.5-1.6.1.tar.gz
Enable mod_security:
sudo a2enmod mod-security
Now restart Apache
sudo /etc/init.d/apache2 restart
That’s it :)
Testing mod_security
“Secure” Example 1 – curl
bodhi@home# curl -i http://ubuntuVPS
HTTP/1.1 200 OK
Date: Tue, 28 Apr 2009 22:44:42 GMT
Server: Apache/2.2.0 (Fedora)
Last-Modified: Tue, 28 Apr 2009 21:39:54 GMT
ETag: "50d4a-2d-468a44dadbe80"
Accept-Ranges: bytes
Content-Length: 45
Vary: Accept-Encoding
Content-Type: text/html
< html>< body>< h1>It works!< /h1>< /body>< /html>
Look no more server or php information (Fedora apache 2.2.0 , LOL !!! )
“Secure” Example 2 – bad .php
bodhi@home# curl -i "http://ubuntuVPS/insecure.php?secret_file=/etc/passwd"
HTTP/1.1 501 Method Not Implemented
Date: Tue, 28 Apr 2009 22:47:38 GMT
Server: Apache/2.2.0 (Fedora)
Allow: TRACE
Vary: Accept-Encoding
Content-Length: 291
Connection: close
Content-Type: text/html; charset=iso-8859-1
< !DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
< html>< head>
< title>501 Method Not Implemented< /title>
< /head>< body>
< h1>Method Not Implemented< /h1>
< p>GET to /insecure.php not supported.< br />
< /p>
< hr>
< address>Apache/2.2.0 (Fedora) Server at ubuntuvps Port 80< /address>
< /body>< /html>
Looks like this in your browser:
501 Method Not Implemented
Method Not Implemented
GET to /insecure.php not supported.
Apache/2.2.0 (Fedora) Server at ubuntuvps Port 80
Ah 501 Error looks much better then the contents of /etc/passwd :)
Where to go from here ?
1. Monitor your logs :
tail /var/log/apache2/mod_security/modsec_audit.log
2. Learn / edit your mod_security rules : ModSecurity Reference Manual
3. Delete bad.php, LOL
sudo rm -rf /var/www/insecure.php
I hope you enjoyed and learned from this tutorial :)
Another great article. Thanks.
By the way, are there any web/ or other interfaces to modify, change modsecurity rules, rather than manipulating the rules using text editor.
Thanks.
@Mohan
They have been working on a few interfaces for mod_security.
See: http://www.modsecurity.org/projects/modprofiler/
I followed your instructions to the letter and downloaded the CRS from the modsecurity website (link to sourceforge). I had to make one slight modification to apache2.conf, the line that had to say: include conf.d/*.conf, otherwise apache would not restart.
Yet I am still getting the ability to list the passwd file, despite the ruleset being there.
Can someone help?
Aron
you saved me!
Gold star … thanks!
Unterschaetzt bei weitem nicht die technischen Errungenschaften des menschlichen Geistes! Darueber hinaus zensiert flink weiter.
Aron S, thank you for this tip! I was struggling with this for 3 days, now it works!
@Aaron
try running something like-
#here’s my config file Ubuntu 10.04
# /etc/apache2/conf.d/modsec.conf (no need to put in apache.conf, keep it separate)
SecRuleEngine On
SecRule ARGS “@validateUtf8Encoding”
SecRule ARGS “@validateByteRange 10, 13, 15, 32-126″
SecServerSignature “Microsoft-IIS/5.0″
SecAuditEngine RelevantOnly
SecAuditLog /var/log/mod-security/modsec_audit_log
Include mod-security-rules/base_rules/*.conf
#Note: the critical part is:
SecRuleEngine On
#Nothing happens without that…
#The server sig part requires
ServerTokens Full
#to work (needs the allocated memory space of the Full setting)
Excellent article. Can anyone tell me how to block access to apache accessing through hostname. I mean the machine which has apache, I am able to block access through ip but unable to block it through hostname. Thanks
I’ve tried it in ubuntu 9.10, on localhost running smoothly. but the access from other computers, no web page that can appear and give this response.
Bad Request
Your browser sent a request that this server could not understand.
Apache/2.2.0 (Fedora) Server at 192.168.0.6 Port 80.
anyone can help me ????
@Ivan – you need to access your web browser by FQDN, not ip address.