Showing posts with label Firewall. Show all posts
Showing posts with label Firewall. Show all posts

Tuesday, November 13, 2012

Howto : Fail2ban, Secure your Network services with Fail2ban and ban malicious hosts





Last Update: 11/13/2012


The Goal: 

Fail2Ban is a very flexible and powerful tool to help you improving your security by temporarily banishing hosts IPs trying to have malicious activity against your services. (brute force attack...)

Easy to install and configure, Fail2Ban will permanently read your files logs and look for suspicious connection attempts or activity, based on provided / custom rules.

Depending on your configuration, Fail2Ban will ban the remote IP using Netfilter rules (iptables) and then unban it depending on your settings.

This a very great tool you MUST have in your server if you opened any service like ssh, http/https with basic authentication, smtp...and much more.


Major sources: 

Official Fail2ban Wiki:
http://www.fail2ban.org/wiki/index.php/Main_Page

Various articles:
http://www.fanatips.org/Apache_%2F%2F_Nginx_tips/Secure_Nginx_with_fail2ban
http://snippets.aktagon.com/snippets/554-How-to-Secure-an-nginx-Server-with-Fail2Ban



Summary of steps: 

Step 1: Requirements
Step 2: Installation and base configuration
Step 3: Enabling services
Step 4: Test your configuration
Step 5: Adding new customized services, example with Nginx Web Server

FAQ & Issues



Step 1: Requirements

Fail2ban is quite easy to install and setup, still depending on your needs you have some requirements:

Iptables:

Fail2ban will require iptables to banish suspicious hosts, it is not a requirement to setup your iptables Firewall configuration (even if recommended).

Fail2ban will insert a drop line, whenever you are using iptables or not.

It is probably installed by defaut (use the command "iptables" to check), if not:
$ sudo apt-get install iptables

MTA configuration for mail alerting:

If you want Fail2ban to able to send you alerting mails in case of action done (banish, unbanish...), then you need to setup your MTA.

Your system probably only be a client of a mail central hub (eg. your ISP), if this is the case i recommend to install "ssmtp" wich is very light and simple to setup, but you may prefer to use sendmail, postfix or anything else.

If your system is a mail server itself, i guess you already know how to configure it :-)

Installation: 
$ sudo apt-get install ssmtp

Configuration (real simple!): 

Edit "/etc/ssmtp/ssmtp.conf" and set:

- mailhub: Define here the smtp server of your local ISP (eg. myisp.smtp.com)
- rewriteDomain: if you want the sender domain to be rewritten with the value of your choice

For most of cases, this will be the only modifications required, in case of need see ssmtp configuration pages. (ask Google ^^)

Quick send test:
$ echo "Testing" | mail -s Subject dest@domain.com

If you receive the mail then you're done. (check /var/log/mail* if required)


Step 2: Installation and base configuration

Installation:

Very simple, For Debian/Ubuntu based systems:
$ sudo apt-get install fail2ban

Initial Configuration:

Edit main Fail2Ban configuration file: "/etc/fail2ban/jail.conf" and define:

1. Local hosts to ignore:

If you want to ignore some local hosts, add them to your configuration, example with 192.168.0.0/24 local network:
# "ignoreip" can be an IP address, a CIDR mask or a DNS host
ignoreip = 127.0.0.1/8 192.168.0.0/24
bantime  = 600
maxretry = 3

2. Mail alert recipient:

If you want to send alter when an action has been done, set the recipient
# Destination email address used solely for the interpolations in
# jail.{conf,local} configuration files.
destemail = admin@mydomain.com

3. MTA:

Sendmail is defined as default command called for sending mails, both should work but i prefer to call standard "mail" command:
# email action. Since 0.8.1 upstream fail2ban uses sendmail
# MTA for the mailing. Change mta configuration parameter to mail
# if you want to revert to conventional 'mail'.
mta = mail

4. Default action when a host has banished

In default configuration, when a host has been banned, the information is just logged and no mail report will be sent.

If you want a report to be sent by mail (associated with a whois request report for the concerned IP), set:
action = %(action_mw)s

If you want a report to be sent by mail with a log extract (associated with a whois request report for the concerned IP), set:
action = %(action_mwl)s



Step 3: Enabling services

SSH example:

The next step will be to define which Network services you will want to supervise, in default configuration Fail2Ban will only monitor SSH for both login failed and DDOS attacks, extract:
[ssh]

enabled  = true
port     = ssh
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 6

The import thing here will be the enabled value set to "true" (^^) but also the port, in case of host banishing the iptables rules will be created using this port.

Fail2ban will create multiport iptables rules, so you can add as many ports as you require.

Example if your SSH is running on several port (example 22 for internal and OTHER for external purposes) then you can set:
[ssh]

enabled  = true
port     = ssh,OTHER
filter   = sshd
logpath  = /var/log/auth.log
maxretry = 6


Other services important vars values:

In each service section, you can overwrite default vars values or set specific ones for your needs.
Here are some you may need to set.

1. Protocol type:

The default protocol if not set will be tcp, you can set it to "udp" or "all" if you need to block bother tcp/udp ports.
protocol = all

2. Ban time:

You may want to overwrite the default bantime, then you just need to it in the service concerned section, time is set in seconds, example for 10 minutes banishment:
bantime = 600 # 10 minutes

3. Ports:

As seen before with the SSH example, you can set as many ports as you required in the port section.
You can call them by names if they are present in /etc/services or by the port number.

Each port must be separated by a coma.

4. Action:

Defaults actions in response of matched events are defined in jail.conf, but you can overwrite values for each specific network service.

In the following example, let's say our default configuration sends emails alert with log extract ("action = %(action_mwl)s") but for a specific Network service we just it to be banned without any altering.

Then you will overwrite the action value in your service section:
action_ = %(banaction)s[name=%(__name__)s, port="%(port)s", protocol="%(protocol)s", chain="%(chain)s


Enable your services:

Depending on your configuration, you need to enable Network services as you require.
Follow each section to enable if required.

If you need to create your own service, follow the example of Nginx as above.



Step 4: Testing your configuration


Testing your configuration is very simple :-)

Just test accessing your SSH host outside of your local network (using your Smartphone or whatever you want!) and put false credentials.

Upon the max retry failures, your host should have been banished, you will see in fail2ban logs:

/var/log/fail2ban.log
2012-11-13 10:41:43,487 fail2ban.actions: WARNING [ss] Ban xxx.xxx.xxx.xxx

Locally, a new iptables rule has been created inside the jail dedicated iptables section (automatically created by fail2ban at boot time):
Chain fail2ban-ssh (1 references)
target     prot opt source               destination         
DROP       all  --  37.160.52.0          anywhere            
RETURN     all  --  anywhere             anywhere            


And you should (if you set it) have received a mail with all required information.

Depending on your configuration, XX minutes/days or whatever after having been ban, the host will be unban and the iptables drop rule will be removed.


Powerful, simple, beautiful :-)



Step 5: Adding new customized services, example with nginx Web Server


One of very great things with Fail2ban is that you can easily add any customized service you would require, you just add to define regex expression that will be used to match patterns and define Network section.

Here comes a full example for Nginx Web Server, we will monitor basic authentication failures, badbots, prevent script execution... and off course this can be easily customized to your needs.

Nginx Web Server Fail2Ban integration:

1. Create Nginx filters

Create each required file with its content:

/etc/fail2ban/filter.d/nginx-auth.conf
#
# Auth filter /etc/fail2ban/filter.d/nginx-auth.conf:
#
# Blocks IPs that fail to authenticate using basic authentication
#
[INCLUDES]                                                                                                                    
                                                                                                                              
# Read common prefixes. If any customizations available -- read them from                                                     
# common.local                                                                                                                
before = common.conf 

[Definition]
 
failregex = no user/password was provided for basic authentication.*client: <HOST>
            user .* was not found in.*client: <HOST>
            user .* password mismatch.*client: <HOST>
  
ignoreregex =

/etc/fail2ban/filter.d/nginx-login.conf
#
# Login filter /etc/fail2ban/filter.d/nginx-login.conf:
#
# Blocks IPs that fail to authenticate using web application's log in page
#
# Scan access log for HTTP 200 + POST /sessions => failed log in
[INCLUDES]                                                                                                                    
                                                                                                                              
# Read common prefixes. If any customizations available -- read them from                                                     
# common.local                                                                                                                
before = common.conf 

[Definition]
failregex = ^<HOST> -.*POST /sessions HTTP/1\.." 200
ignoreregex =

/etc/fail2ban/filter.d/nginx-noscript.conf
# Noscript filter /etc/fail2ban/filter.d/nginx-noscript.conf:
#
# Block IPs trying to execute scripts such as .php, .pl, .exe and other funny scripts.
#
# Matches e.g.
# 192.168.1.1 - - "GET /something.php
#
[INCLUDES]                                                                                                                    
                                                                                                                              
# Read common prefixes. If any customizations available -- read them from                                                     
# common.local                                                                                                                
before = common.conf 

[Definition]
failregex = ^<HOST> -.*GET.*(\.php|\.asp|\.exe|\.pl|\.cgi|\scgi)
ignoreregex =

/etc/fail2ban/filter.d/nginx-proxy.conf
# Proxy filter /etc/fail2ban/filter.d/nginx-proxy.conf:
#
# Block IPs trying to use server as proxy.
#
# Matches e.g.
# 192.168.1.1 - - "GET http://www.something.com/
#
[INCLUDES]                                                                                                                    
                                                                                                                              
# Read common prefixes. If any customizations available -- read them from                                                     
# common.local                                                                                                                
before = common.conf 

[Definition]
failregex = ^<HOST> -.*GET http.*
ignoreregex =


2. Create Nginx configuration

Edit Fail2Ban configuration  "/etc/fail2ban/jail.conf" and add:

Note: 

If Nginx is listening to non standard http/https port, think to adapt to your configuration
Also, nginx-noscript will prevent any script execution on your sites, if this is not what you need just comment out this section.

/etc/fail2ban/jail.conf
[nginx-auth]
enabled = true
filter = nginx-auth
port = http,https
logpath = /var/log/nginx*/*error*.log
bantime = 600 # 10 minutes
maxretry = 6
 
[nginx-login]
enabled = true
filter = nginx-login
port = http,https
logpath = /var/log/nginx*/*access*.log
bantime = 600 # 10 minutes
maxretry = 6
  
[nginx-badbots]
enabled  = true
filter = apache-badbots
port = http,https
logpath = /var/log/nginx*/*access*.log
bantime = 86400 # 1 day
maxretry = 1
  
[nginx-noscript]
enabled = true
port = http,https
filter = nginx-noscript
logpath = /var/log/nginx*/*access*.log
axretry = 6
bantime  = 86400 # 1 day
  
[nginx-proxy]
enabled = true
port = http,https
filter = nginx-proxy
logpath = /var/log/nginx*/*access*.log
maxretry = 0
bantime  = 86400 # 1 day



Finally, restart fail2ban and you're done! (sudo service fail2ban restart)

To test your configuration, just try to access to your basic authentification protected Web Site with bad credentials, as for the SSH example your host will be ban and you'll get the report :-)



FAQ & Issues


  • How to prevent Fail2ban from sending alerts mails when stopped/started

When email alerting is configured, fail2ban will send you one mail per jail configured (one per Network service) for each action (stop/start).

This can be as usefull as boring :-)

If you want to disable this behavior:

- Go in "/etc/fail2ban/actions.d/"

- You will find 6 configurations files related to sendmail & mail, depending on what you set (sendmail vs mail) you just have to comment out actionstart and actionstop:

"action_": comment "actionstart" & "actionstop" in action.d/sendmail.conf
"action_mw": comment "actionstart" & "actionstop" in action.d/sendmail-whois.conf
"action_mwl": comment "actionstart" & "actionstop" in action.d/sendmail-whois-lines.conf

"action_": comment "actionstart" & "actionstop" in action.d/mail.conf
"action_mw": comment "actionstart" & "actionstop" in action.d/mail-whois.conf
"action_mwl": comment "actionstart" & "actionstop" in action.d/mail-whois-lines.conf

- Restart fail2ban, you're done!













Saturday, November 10, 2012

Howto - Apache2 ModSecurity - Enhance your Web Server and Applications security with an Opensource Web Application Firewall (WAF)






*** Updated March 9, 2013  ***

03/09/2013: Various typo corrections


The Goal: 

ModSecurity is an OpenSource Web Application Firewall, today stable when used with Apache Web server, it will allow to drastically increase your Web security by analyzing in real time any kind of traffic and applying various analysis rules.

This tutorial is based on Ubuntu and Debian based system, bu can be easily adapted to any Unix / Linux based OS.

Major sources: 

Official ModSecurity site:
http://www.modsecurity.org/

ModSecurity Rules:
http://spiderlabs.github.com/owasp-modsecurity-crs/

Various interesting sources:
http://www.thefanclub.co.za/how-to/how-install-apache2-modsecurity-and-modevasive-ubuntu-1204-lts-server
http://www.ebelair.fr/2011/06/07/installer-et-configurer-modsecurity/



Summary of steps: 

Step 1: Prepare your systemStep 2: Download components - ModSecurity Sources and Rules
Step 3: Compile and install ModSecurity Module
Step 4: Configure ModSecurity module and rules
Step 5: Main ModSecurity Configuration
Step 6: Test your configuration, Simulate a generic attack and malicious code upload
Step 7: Whitelist configuration, test your Web sites and add whitelist exceptions if required
Step 8: Advanced vulnerabilities and attack tools
FAQ & issues


I will assume you already have a running OS and Apache installation.

To implement ModSecurity for Apache on Debian / Ubuntu based systems, you can use official OS Repositories or download, compile and configure latest official versions of ModSecurity sources and rules.

This tutorial is based on the second solution because we wan't to take benefit of very last versions.


Step 1: Prepare your system

Install various dependencies:
$ sudo apt-get install g++ make autoconf automake libtool flex bison gcc apache2-threaded-dev libxml2-dev libcurl4-gnutls-dev libapr1 libapr1-dev libpcre3 libpcre3-dev libxml2 libxml2-dev

ModSecurity can be combined with an Antivirus if you want to scan for malicious code any incoming file, this can be a great idea to secure your Web Server.
Clamav is an Opensource Antivirus and will be used to achieve this.

Install Clamav:
$ sudo apt-get install clamav clamav-base clamav-freshclam

An Apache module called "unique_id" is required to use ModSecurity.
This module should be installed by default.
$ sudo a2enmod unique_id


Step 2: Download components - ModSecurity Sources and Rules

I would advise to download and keep files into "/usr/local/src/modsecurity" but this is up to you to change it.


Download required components:
  • ModSecurity sources:
Go to http://www.modsecurity.org/download/ and download last version  "modsecurity*apache*.tar.gz"
  • ModSecurity Core Rules:
Go to http://spiderlabs.github.com/owasp-modsecurity-crs/ and download last modsecurity*apache*.tar.gz


Step 3: Compile and install ModSecurity Module

Extract Modsecurity Sources:
$ tar -xvzf <replace with Modsecurity Sources archive version name>
$ cd <extracted directory>

Configure, compile and install:
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install

The module core will be installed by default in "/usr/local/modsecurity/lib".


Step 4: Configure ModSecurity module and rules

Create module loading file in Apache:

Create a new file "/etc/apache2/mods-available/security2_module.load" and add:
LoadFile libxml2.so
LoadFile liblua5.1.so
LoadModule security2_module /usr/local/modsecurity/lib/mod_security2.so

Extract Modsecurity Core Rules:
$ tar -xvzf <replace with Modsecurity Core Rules archive version name>
$ sudo mv <extracted directory> /usr/local/src/modsecurity-crs

Prepare your Apache configuration: 
$ sudo mv <extracted directory> /usr/local/src/modsecurity-crs
$ sudo mkdir -p /etc/apache2/modsecurity/conf
$ sudo mkdir -p /etc/apache2/modsecurity/activated_rules
$ sudo cp /usr/local/src/modsecurity-crs/*.conf.example /usr/local/src/modsecurity-crs/modsecurity.conf
$ sudo ln -s /usr/local/src/modsecurity-crs/modsecurity.conf /etc/apache2/modsecurity/conf/modsecurity.conf

Activate recommended rules by creating symlinks:
$ for f in `ls base_rules/`; do sudo ln -s /usr/local/src/modsecurity-crs/base_rules/$f /etc/apache2/modsecurity/activated_rules/$f; done
$ for f in `ls optional_rules/ | grep comment_spam`; do sudo ln -s /usr/local/src/modsecurity-crs/optional_rules/$f /etc/apache2/modsecurity/activated_rules/$f; done

Add symlink to "util" directory:
$ sudo ln -s /usr/local/src/modsecurity-crs/util /etc/apache2/modsecurity/util

Add module launch configuration file:

Create a new file "/etc/apache2/conf.d/modsecurity.conf" and add:
<IfModule security2_module>
 Include /etc/apache2/modsecurity/conf/*.conf
 Include /etc/apache2/modsecurity/activated_rules/*.conf
<IfModule>

Activate modsecurity module:
$ sudo a2enmod security2_module


Step 5: Main ModSecurity Configuration


Now, let's create the module configuration file, based on recommended version by modsecurity:
https://github.com/SpiderLabs/ModSecurity/wiki/Reference-Manual

Create the main Modsecurity configuration file:

/etc/apache2/mods-available/security2_module.conf :

Modifications i recommend:

# Line 7: Change "SecRuleEngine DetectionOnly" to "SecRuleEngine On" if you want active response from the module.
In detection mode only, no actions but logging will be done by modsecurity module.

# Line 167: Comment out and change debug log file, change "#SecDebugLog /opt/modsecurity/var/log/debug.log" to "SecDebugLog /var/log/apache2/modsec_debug.log"

# Line 187: Change main modsec log from"SecAuditLog /var/log/modsec_audit.log" to "SecAuditLog /var/log/apache2/modsec_audit.log"

# Line 147: Change "#SecUploadDir /opt/modsecurity/var/upload/" to "/var/cache/www-upload" (will be created later)

# Line 32/33: Depending on your needs, you have set the maximum allowed file size for uploads in your sites, there is an hard limit 1GB, if you want this, then set:
SecRequestBodyLimit 1073741824
SecRequestBodyNoFilesLimit 1073741824

If you want to use Clamav to scan uploaded files:


#Line 160: add the following line:
SecRule FILES_TMPNAMES "@inspectFile /etc/apache2/modsecurity/util/runav.pl" "id:159,phase:2,t:none,log,deny,msg:'Malicious Code Detected, access denied'"


/etc/apache2/mods-available/security2_module.conf :
# -- Rule engine initialization ----------------------------------------------

# Enable ModSecurity, attaching it to every transaction. Use detection
# only to start with, because that minimises the chances of post-installation
# disruption.
#
SecRuleEngine On


# -- Request body handling ---------------------------------------------------

# Allow ModSecurity to access request bodies. If you don't, ModSecurity
# won't be able to see any POST parameters, which opens a large security
# hole for attackers to exploit.
#
SecRequestBodyAccess On


# Enable XML request body parser.
# Initiate XML Processor in case of xml content-type
#
SecRule REQUEST_HEADERS:Content-Type "text/xml" \
     "id:'200000',phase:1,t:none,t:lowercase,pass,nolog,ctl:requestBodyProcessor=XML"


# Maximum request body size we will accept for buffering. If you support
# file uploads then the value given on the first line has to be as large
# as the largest file you are willing to accept. The second value refers
# to the size of data, with files excluded. You want to keep that value as
# low as practical.
#
SecRequestBodyLimit 1073741824
SecRequestBodyNoFilesLimit 1073741824

# Store up to 128 KB of request body data in memory. When the multipart
# parser reachers this limit, it will start using your hard disk for
# storage. That is slow, but unavoidable.
#
SecRequestBodyInMemoryLimit 131072

# What to do if the request body size is above our configured limit.
# Keep in mind that this setting will automatically be set to ProcessPartial
# when SecRuleEngine is set to DetectionOnly mode in order to minimize
# disruptions when initially deploying ModSecurity.
#
SecRequestBodyLimitAction Reject

# Verify that we've correctly processed the request body.
# As a rule of thumb, when failing to process a request body
# you should reject the request (when deployed in blocking mode)
# or log a high-severity alert (when deployed in detection-only mode).
#
SecRule REQBODY_ERROR "!@eq 0" "id:'200001', phase:2,t:none,log,deny, \
  status:400,msg:'Failed to parse request body.',logdata:'%{reqbody_error_msg}',severity:2"

# By default be strict with what we accept in the multipart/form-data
# request body. If the rule below proves to be too strict for your
# environment consider changing it to detection-only. You are encouraged
# _not_ to remove it altogether.
#
SecRule MULTIPART_STRICT_ERROR "!@eq 0" \
  "id:'200002',phase:2,t:none,log,deny,status:400, \
  msg:'Multipart request body failed strict validation: \
  PE %{REQBODY_PROCESSOR_ERROR}, \
  BQ %{MULTIPART_BOUNDARY_QUOTED}, \
  BW %{MULTIPART_BOUNDARY_WHITESPACE}, \
  DB %{MULTIPART_DATA_BEFORE}, \
  DA %{MULTIPART_DATA_AFTER}, \
  HF %{MULTIPART_HEADER_FOLDING}, \
  LF %{MULTIPART_LF_LINE}, \
  SM %{MULTIPART_MISSING_SEMICOLON}, \
  IQ %{MULTIPART_INVALID_QUOTING}, \
  IP %{MULTIPART_INVALID_PART}, \
  IH %{MULTIPART_INVALID_HEADER_FOLDING}, \
  FL %{MULTIPART_FILE_LIMIT_EXCEEDED}'"

# Did we see anything that might be a boundary?
#
SecRule MULTIPART_UNMATCHED_BOUNDARY "!@eq 0" "id:'200003',phase:2,t:none,log,deny, \
  status:400,msg:'Multipart parser detected a possible unmatched boundary.'"

# PCRE Tuning
# We want to avoid a potential RegEx DoS condition
#
SecPcreMatchLimit 1000
SecPcreMatchLimitRecursion 1000

# Some internal errors will set flags in TX and we will need to look for these.
# All of these are prefixed with "MSC_".  The following flags currently exist:
#
# MSC_PCRE_LIMITS_EXCEEDED: PCRE match limits were exceeded.
#
SecRule TX:/^MSC_/ "!@streq 0" \
        "id:'200004',phase:2,t:none,deny,msg:'ModSecurity internal error flagged: %{MATCHED_VAR_NAME}'"


# -- Response body handling --------------------------------------------------

# Allow ModSecurity to access response bodies. 
# You should have this directive enabled in order to identify errors
# and data leakage issues.
# 
# Do keep in mind that enabling this directive does increases both
# memory consumption and response latency.
#
SecResponseBodyAccess On

# Which response MIME types do you want to inspect? You should adjust the
# configuration below to catch documents but avoid static files
# (e.g., images and archives).
#
SecResponseBodyMimeType text/plain text/html text/xml

# Buffer response bodies of up to 512 KB in length.
SecResponseBodyLimit 524288

# What happens when we encounter a response body larger than the configured
# limit? By default, we process what we have and let the rest through.
# That's somewhat less secure, but does not break any legitimate pages.
#
SecResponseBodyLimitAction ProcessPartial


# -- Filesystem configuration ------------------------------------------------

# The location where ModSecurity stores temporary files (for example, when
# it needs to handle a file upload that is larger than the configured limit).
# 
# This default setting is chosen due to all systems have /tmp available however, 
# this is less than ideal. It is recommended that you specify a location that's private.
#
SecTmpDir /tmp/

# The location where ModSecurity will keep its persistent data.  This default setting 
# is chosen due to all systems have /tmp available however, it
# too should be updated to a place that other users can't access.
#
SecDataDir /tmp/


# -- File uploads handling configuration -------------------------------------

# The location where ModSecurity stores intercepted uploaded files. This
# location must be private to ModSecurity. You don't want other users on
# the server to access the files, do you?
#
SecUploadDir /var/cache/www-upload

# By default, only keep the files that were determined to be unusual
# in some way (by an external inspection script). For this to work you
# will also need at least one file inspection rule.
#
#SecUploadKeepFiles RelevantOnly

# Uploaded files are by default created with permissions that do not allow
# any other user to access them. You may need to relax that if you want to
# interface ModSecurity to an external program (e.g., an anti-virus).
#
#SecUploadFileMode 0600
SecRule FILES_TMPNAMES "@inspectFile /etc/apache2/modsecurity/util/runav.pl" "id:159,phase:2,t:none,log,deny,msg:'Malicious Code Detected, access denied'"

# -- Debug log configuration -------------------------------------------------

# The default debug log configuration is to duplicate the error, warning
# and notice messages from the error log.
#
SecDebugLog /var/log/apache2/modsec_debug.log
#SecDebugLogLevel 3


# -- Audit log configuration -------------------------------------------------

# Log the transactions that are marked by a rule, as well as those that
# trigger a server error (determined by a 5xx or 4xx, excluding 404,  
# level response status codes).
#
SecAuditEngine RelevantOnly
SecAuditLogRelevantStatus "^(?:5|4(?!04))"

# Log everything we know about a transaction.
SecAuditLogParts ABIJDEFHZ

# Use a single file for logging. This is much easier to look at, but
# assumes that you will use the audit log only occasionally.
#
SecAuditLogType Serial
SecAuditLog /var/log/apache2/modsec_audit.log

# Use concurrent logging
#SecAuditLogType Concurrent
#SecAuditLog "|/opt/modsecurity/bin/mlogc /opt/modsecurity/etc/mlogc.conf"

# Specify the path for concurrent audit logging.
#SecAuditLogStorageDir /opt/modsecurity/var/audit/


# -- Miscellaneous -----------------------------------------------------------

# Use the most commonly used application/x-www-form-urlencoded parameter
# separator. There's probably only one application somewhere that uses
# something else so don't expect to change this value.
#
SecArgumentSeparator &

# Settle on version 0 (zero) cookies, as that is what most applications
# use. Using an incorrect cookie version may open your installation to
# evasion attacks (against the rules that examine named cookies).
#
SecCookieFormat 0

# Specify your Unicode Code Point.
# This mapping is used by the t:urlDecodeUni transformation function
# to properly map encoded data to your language. Properly setting
# these directives helps to reduce false positives and negatives.
#
#SecUnicodeCodePage 20127
#SecUnicodeMapFile unicode.mapping

Create upload dir cache:
$ sudo mkdir /var/cache/www-upload
$ sudo chown www-data:wwwdata /var/cache/www-upload

Create whitelist file (blank for now):
$ sudo touch /etc/apache2/modsecurity/conf/whitelist.conf

Were're done with configuration, restart Apache2:
$ sudo service apache2 restart


Step 6: Test your configuration, Simulate a generic attack and malicious code upload


Test your configuration:

1. Main log file

Upon Apache2 start-up, you should see a new file "/var/log/apache2/modsec_audit.log", to see its content in real time:
$ tail -f /var/log/apache2/modsec_audit.log

2. Simulate a simple attack

Open your Web Browser and simulate a generic attack (adapt to your configuration, name and port):
http://localhost/test.php?secret_file=/etc/passwd

If you have activated SecRuleEngine to On, then your get an refused error from Apache.
Otherwise, an attack should have been logged in main audit log.

If ok:

Forbidden

You don't have permission to access / on this server.

In log you should see something like this:

Message: Access denied with code 403 (phase 2). Pattern match "(?:\\b(?:\\.(?:ht(?:access|passwd|group)|www_?acl)|global\\.asa|httpd\\.conf|boot\\.ini)\\b|\\/etc\\/)" at ARGS:secret_file. [file "/etc/apache2/modsecurity/activated_rules/modsecurity_crs_40_generic_attacks.conf"] [line "205"] [id "950005"] [rev "2"] [msg "Remote File Access Attempt"] [data "Matched Data: /etc/ found within ARGS:secret_file: /etc/passwd"] [severity "CRITICAL"] [ver "OWASP_CRS/2.2.6"] [maturity "9"] [accuracy "9"] [tag "OWASP_CRS/WEB_ATTACK/FILE_INJECTION"] [tag "WASCTC/WASC-33"] [tag "OWASP_TOP_10/A4"] [tag "PCI/6.5.4"]
Action: Intercepted (phase 2)
Apache-Handler: application/x-httpd-php
Stopwatch: 1352556406954555 3620 (- - -)
Stopwatch2: 1352556406954555 3620; combined=2104, p1=546, p2=1462, p3=0, p4=0, p5=95, sr=121, sw=1, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.7.0 (http://www.modsecurity.org/); OWASP_CRS/2.2.6.
Server: Apache
Engine-Mode: "ENABLED"


3. Try to upload a malicious test file

Create locally a file "testeicar.txt" with following content and try to upload it to your Web Server:
X5O!P%@AP[4\PZX54(P^)7CC)7}$EICAR-STANDARD-ANTIVIRUS-TEST-FILE!$H+H*

Upload should fail and you should see this kind of message in modsec log:
Message: Access denied with code 403 (phase 2). File "/tmp//20121110-143758-UJ5Ytn8AAQEAAFjiESIAAAAI-file-pCUZqH" rejected by the approver script "/etc/apache2/modsecurity/util/runav.pl": 0 clamscan: Eicar-Test-Signature [file "/etc/apache2/mods-enabled/security2_module.conf"] [line "160"] [id "159"] [msg "Malicious Code Detected, access denied"]
Action: Intercepted (phase 2)
Apache-Handler: application/x-httpd-php
Stopwatch: 1352554678179590 9450540 (- - -)
Stopwatch2: 1352554678179590 9450540; combined=9447023, p1=562, p2=9446396, p3=0, p4=0, p5=64, sr=117, sw=1, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.7.0 (http://www.modsecurity.org/); OWASP_CRS/2.2.6.
Server: Apache
Engine-Mode: "ENABLED"


Step 7: Whitelist configuration, test your Web sites and add whitelist exceptions if required


You could probably encounter actions refused based on rules policies with your Web Sites and Applications, so it is recommended to test and add exceptions when required.

As far en example, in my case using Ajaxplorer and uploading files won't possible in default configuration because some rules policies will reject it.

The way to deal with that is almost simple, keep a terminal view on modsec log and test normal user action, each rejected action will be associated to a unique id, we will add exceptions to these ids to allow normal users actions.

Example with ajaxplorer and file upload:

Without whitelist exception, upload fails with following message log: 
Message: Access denied with code 400 (phase 2). Match of "eq 0" against "MULTIPART_UNMATCHED_BOUNDARY" required. [file "/etc/apache2/mods-enabled/security2_module.conf"] [line "80"] [id "200003"] [msg "Multipart parser detected a possible unmatched boundary."]
Action: Intercepted (phase 2)
Apache-Handler: application/x-httpd-php
Stopwatch: 1352555512125594 4755100 (- - -)
Stopwatch2: 1352555512125594 4755100; combined=1441, p1=1276, p2=65, p3=0, p4=0, p5=99, sr=336, sw=1, l=0, gc=0
Response-Body-Transformed: Dechunked
Producer: ModSecurity for Apache/2.7.0 (http://www.modsecurity.org/); OWASP_CRS/2.2.6.
Server: Apache
Engine-Mode: "ENABLED"


This is the first policy blocking our normal user action, so we will had an exception associated with this id:

Edit "/etc/apache2/modsecurity/conf/whitelist.conf" and add:
<LocationMatch "/ajaxplorer/">
SecRuleRemoveById 200003
</LocationMatch>


Then reload or restart Apache2 (sudo service apache2 reload) and restart your normal user action, if it still fails then re-check your modsec log, note the id and add it to exception.

Finally, for Ajaxplorer/owncloud example, i had to deal with these exceptions:
<LocationMatch "/ajaxplorer/">
SecRuleRemoveById 200003 960024 960915
</LocationMatch>

Proceed the same way with all your sites and applications, and you will be done!

Note:

If you have any problem with whitelist by location like exception not been working, try to apply your exceptions directly in the Apache configuration file.

Behind the directive DocumentRoot, append your exceptions like this:

SecRuleRemoveById 200003 960024 960915


 And restart/reload Apache.


Step 8: Advanced vulnerabilities and attack tools

Now that your Apache installation has been secured, you should think about testing your site with advanced vulnerabilities tools.

Here are some tools i recommend:

1. Nessus

Nessus is a well known security scan tool, you can get for a free a personal user key and use the software to scan your sites or hosts.

See:
http://www.tenable.com/


Installation is really simple, then simply launch a Web Application scan and wait for the report, you should see many output in log showing ModSecurity activity.

2. Nikto

Also very powerful and simple to use, Nikto will carefully scan and launch various attacks/exploit against your Web Server.

The result will instantly visible in ModSecurity main log with thousands of events logs, i would recommend to to launch 2 scan, a first scan with ModSecurity activated and second with ModSecurity deactivated and just compare results ^^

See:
http://cirt.net/

Example of use:

Launching a scan in http:
perl nikto.pl -h HOST -p PORT

Launching a scan in https:
perl nikto.pl -h HOST -p PORT -ssl


3. Web-sorrow

Another tool, under hard tests :-)

http://code.google.com/p/web-sorrow/





FAQ & Issues

  • How to activate / deactivate ModSecurity Module
Nothing more simple:

Activating:
$ sudo a2enmod security2_module
$ sudo service apache2 restart

Deactivating:
$ sudo a2dismod security2_module
$ sudo service apache2 restart


  • How to partially deactivate ModSecurity for a location
You may want to partially deactivate ModSecurity for a specific location, to do this add a such section into your whitelist:
<LocationMatch "/application/">
SecRuleEngine Off
</LocationMatch>

And restart / reload Apache to apply.


  • How to deactivate ModSecurity for a full Apache instance
You may also want to deactivate ModSecurity by instance, to do so edit the instance Apache configuration file and this behind the DocumentRoot line:
SecRuleEngine Off

And restart / reload Apache to apply.


  • How to update ModSecurity Rules
An auto update tool is provided with ModSecurity but the provided repository does not seem to be as up to date as the spiderlabs link... at this writing time the modsecurity contains v2.2.5 where spiderlabs provides 2.2.6 ^^

The update tool "rules-updater.pl" is located in "util" directory. 

You can also simply update rules by extracting and overwriting content in /usr/local/src/modsecurity-crs