Stephen Reese

This entry describes settting up ModSecurity on a node in order to protect a few WordPress sites I host. There are a slew of guides out there describing ModSecurity builds but I wanted to leverage the latest ModSecurity and Apache MPM Event packages which typically are not included in most Linux distribution repositories. We use a proxy node that passes requests to the backend (origin) server hosting the web application. You may just as easily build ModSecurity on the same host that is serving your content verse using a reverse proxy, i.e. there are a number of ways to architect the setup. In the figure below, a request is first received by the proxy with ModSecurity enabled, and then passed to the origin host serving the actual content if ModSecurity does not intervene. We use Debian but other distributions should be similar.

ModSecurity Proxy

Install prerequisite packages:

$ sudo apt-get install gcc libpcre3-dev libxml2-dev libcurl4-gnutls-dev

Download, Build, and Install SSL (enable shared if on 64bit):

$ mkdir install
$ ./config shared --prefix=/root/openssl-1.0.2a/install/
$ make depend
$ make
$ make test
$ make install

Download latest Apache, APR, and APR Util packages. Extract APR and APR Util, copy both to Apache src directory, build and install Apache:

$ cp -R apr-util-1.5.4 httpd-2.4.12/srclib/apr-util/
$ cp -R apr-1.5.1 httpd-2.4.12/srclib/apr/
$ ./configure --with-included-apr --enable-ssl --enable-ssl-staticlib-deps --with-ssl=/root/openssl-1.0.2/install/ --enable-proxy --with-mpm=event
$ make
$ sudo make install

Download, Build and install ModSecurity (optionally install LUA if desired):

$ tar xzf modsecurity-2.9.0.tar.gz
$ cd modsecurity-2.9.0/
$ ./configure --with-apxs=/usr/local/apache2/bin/apxs --with-apr=/root/httpd-2.4.12/srclib/apr/ --with-apu=/root/httpd-2.4.12/srclib/apr-util/ --with-lua=/usr/lib/x86_64-linux-gnu/pkgconfig/
$ make
$ sudo make install

Grab a rule-set. You may also choose to use GIT to download.

$ wget
$ mv master master.tar.gz
$ cp -R SpiderLabs-owasp-modsecurity-crs-ebe8790/ /usr/local/apache2/conf/crs/
$ cd /usr/local/apache2/conf/crs/
$ mv modsecurity_crs_10_setup.conf.example modsecurity_crs_10_setup.conf
$ ln -s /usr/local/apache2/conf/crs/modsecurity_crs_10_setup.conf activated_rules/
$ for f in `ls base_rules/` ; do ln -s /usr/local/apache2/conf/crs/base_rules/$f activated_rules/$f ; done
$ for f in `ls optional_rules/` ; do ln -s /usr/local/apache2/conf/crs/optional_rules/$f activated_rules/$f ; done
$ mkdir /etc/modsec
$ cd
$ cp modsecurity-2.9.0/modsecurity.conf-recommended /etc/modsec/modsecurity.conf
$ cp modsecurity-2.9.0/unicode.mapping /etc/modsec/
$ vim /etc/modsec/whitelist.conf

Setup your Apache site, virtual host, or use proxy pass in order to fetch from a back-end origin node. Add ModSecurity directives to Apache conf file:

LoadModule unique_id_module modules/
LoadModule security2_module modules/
<IfModule security2_module>
Include /etc/modsec/modsecurity.conf
Include conf/crs/activated_rules/*.conf
Include /etc/modsec/whitelist.conf
SecRule ARGS "mod_security_test" "t:normalisePathWin,id:99999,severity:4,msg:'Drive Access'"

Start Apache and test to validate rules are logging and optionally being enforced. You should see a 403 forbidden response meaning that the malicious requests were blocked. Now you can move to tuning the ruleset to your web application:


If something is not clear, leave a comment below.


comments powered by Disqus