ModSecurity is a Web Application Firewall (WAF) that can block generic as well as specific threats. Off-the-shelf firewall appliances are becoming increasingly common. ModSecurity has the advantage over these, that you can write and customize firewall rules yourself. Combined with knowledge of your web application and insight into detailed audit logs, ModSecurity allows you to block attacks much more aggressively than a vendor appliance can. I will walk you through installing and configuring ModSecurity on FreeBSD.
Assuming you are using the new pkgng package manager, installing Apache is easy.
pkg install apache22 echo 'apache22_enable=YES' >> /etc/rc.conf service apache22 start
Install the ModSecurity package:
pkg install www/mod_security
Getting the Core Rule Set
ModSecurity requires firewall rule definitions. Most people use the OWASP ModSecurity Core Rule Set (CRS). The easiest way to track the OWASP CRS repository right now is to use Git. Let's make a directory for all our ModSecurity related stuff, and clone the CRS repository under it.
pkg install git mkdir -p /usr/local/etc/modsecurity cd /usr/local/etc/modsecurity git clone https://github.com/SpiderLabs/owasp-modsecurity-crs crs
Creating the ModSecurity configuration
Copy the default ModSecurity config file, and fetch a necessary file which is currently not included in the port:
cp /usr/local/etc/modsecurity.conf-example modsecurity.conf fetch https://raw.github.com/SpiderLabs/ModSecurity/master/unicode.mapping cp crs/modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
Now we create an Apache configuration snippet in Apache's
modules.d directory. It loads the ModSecurity module, and includes the configurations and CRS:
cat << EOF > /usr/local/etc/apache22/modules.d/000_modsecurity.conf # Load ModSecurity # Comment out the next line to temporarily disable ModSecurity: LoadModule security2_module libexec/apache22/mod_security2.so <IfModule security2_module> # Include ModSecurity configuration Include etc/modsecurity/modsecurity.conf # Include OWASP Core Rule Set (CRS) configuration and base rules Include etc/modsecurity/modsecurity_crs_10_setup.conf Include etc/modsecurity/crs/base_rules/*.conf # Add custom configuration and CRS exceptions here. Example: # SecRuleRemoveById 960015 </IfModule> EOF
When the configuration is all set, simply restart Apache, and confirm that ModSecurity is loaded by checking Apache's log file:
service apache22 restart tail /var/log/httpd-error.log
Hopefully, the log will show something like this:
ModSecurity for Apache/2.7.7 (http://www.modsecurity.org/) configured. ModSecurity: APR compiled version="1.4.8"; loaded version="1.4.8" ModSecurity: PCRE compiled version="8.34 "; loaded version="8.34 2013-12-15" ModSecurity: LIBXML compiled version="2.8.0"
Configuring blocking mode
Now that ModSecurity is active, try making a suspicious request to your web server, for instance browse to a URL http://www.example.com/?foo=/etc/passwd. The CRS has a rule against this type of request. After browsing to the URL, you should now see this request logged in
You'll notice that the request succeeds, and the response is sent to the browser normally. The reason is that ModSecurity runs in
DetectionOnly mode by default, in order to prevent downtime from misconfiguration or heavy-handed blocking. You can enable blocking mode simply by editing
modsecurity.conf and changing the following line:
Again, restart Apache. Now, make the same suspicious request to your web server. You should now see a "403 Forbidden" error!
In practice, it's probably best to keep
SecRuleEngine DetectionOnly for some time, while your users exercise the web applications. Meanwhile, you should keep an eye on
/var/log/modsec_audit.log to see what is being blocked. If there are any false positives, you need to mitigate this by writing custom exceptions.
An essential resource for working with ModSecurity is the ModSecurity Handbook by Ivan Ristić. ModSecurity exposes quite some internals, and it's good to scan this book before you start writing custom rules and exceptions.
You probably want to keep the CRS updated from time to time. You can do this with Git:
cd /usr/local/etc/modsecurity/crs git pull