ModSecurity, originally written as a web application firewall (WAF) for Apache servers, is the de facto standard for open-source WAF solutions. Recent work on the project has shifted focus toward providing a generic shared library that any web server can use to protect HTTP(S) requests. These instructions touch on building and configuring libmodsecurity for a DreamCompute instance running Ubuntu 14.04.
Building libmodsecurity
First, install the necessary packages and libraries used to build source projects, as well as libraries used specifically by libmodsecurity:
[root@server]# apt-get install automake gcc make pkg-config libtool g++ libfl-dev bison \
build-essential libbison-dev libyajl-dev liblmdb-dev libpcre3-dev \
libcurl4-openssl-dev libgeoip-dev libxml2-dev
Next, download and unpack the most recent source of libmodsecurity. This is available from the ModSecurity GitHub project, on the libmodsecurity branch:
[root@server]# git clone https://github.com/SpiderLabs/ModSecurity
Cloning into 'ModSecurity'...
remote: Counting objects: 20508, done.
remote: Compressing objects: 100% (72/72), done.
remote: Total 20508 (delta 16), reused 0 (delta 0), pack-reused 20435
Receiving objects: 100% (20508/20508), 33.93 MiB | 9.49 MiB/s, done.
Resolving deltas: 100% (14572/14572), done.
Checking connectivity... done.
[root@server]# cd ModSecurity/
[root@server]# git checkout -b origin/v3/master
Switched to a new branch 'origin/v3/master'
Initialize and update the git submodules that libmodsecurity requires:
[root@server]# git submodule init
[root@server]# git submodule update
Finally, configure, build, and install the libmodsecurity library:
[root@server]# ./build.sh && ./configure && make && make install
Building Nginx with libmodsecurity
Now that libmodsecurity has been installed and is available to be used by third-party programs, Nginx can be compiled with the ModSecurity-nginx connector to load libmodsecurity and process requests.
First, grab the source for the Nginx module wraps around libmodsecurity:
[root@server]# git clone https://github.com/SpiderLabs/ModSecurity-nginx.git
Next, grab the Nginx source and verify it:
[root@server]# wget http://nginx.org/download/nginx-1.10.1.tar.gz
It’s also important to grab the developer’s signing key and verify the contents of the download:
[root@server]# gpg --keyserver pgp.mit.edu --recv a1c052f8
gpg: requesting key A1C052F8 from hkp server pgp.mit.edu
gpg: key A1C052F8: public key "Maxim Dounin <mdounin@mdounin.ru>" imported
gpg: 3 marginal(s) needed, 1 complete(s) needed, PGP trust model
gpg: depth: 0 valid: 3 signed: 5 trust: 0-, 0q, 0n, 0m, 0f, 3u
gpg: depth: 1 valid: 5 signed: 0 trust: 4-, 0q, 0n, 0m, 1f, 0u
gpg: next trustdb check due at 2017-11-22
gpg: Total number processed: 1
gpg: imported: 1 (RSA: 1)
Next, grab the signature for this tarball:
[root@server]# wget http://nginx.org/download/nginx-1.10.1.tar.gz.asc
And finally, verify the signature:
[root@server]# gpg --verify nginx-1.10.1.tar.gz.asc nginx-1.10.1.tar.gz
gpg: Signature made Tue 31 May 2016 06:58:32 AM PDT using RSA key ID A1C052F8
gpg: Good signature from "Maxim Dounin <mdounin@mdounin.ru>"
Primary key fingerprint: B0F4 2533 73F8 F6F5 10D4 2178 520A 9993 A1C0 52F8
From here, configure Nginx with the –add-module= option, pointing to the ModSecurity-nginx module that was previously downloaded:
[root@server]# tar -zxf nginx-1.10.1.tar.gz
[root@server]# cd nginx-1.10.1/
[root@server]# ./configure --add-module=/root/ModSecurity-nginx
From here, simply build and install Nginx:
[root@server]# make && make install
Configuring libmodsecurity in Nginx
Adding libmodsecurity rules and configuration directives inside Nginx configs is straightforward. Add the following to the Nginx configuration:
modsecurity on;
modsecurity_rules '
SecRuleEngine On
SecDebugLog /tmp/modsec_debug.log
SecDebugLogLevel 9
SecRule ARGS "@streq test" "id:1,phase:1,deny,msg:\'test rule\'"
';
These directives can be added inside the http block, or one or more server or location blocks. Once this is added, reload Nginx. This rule can now be tested by sending a regular request to Nginx and examining the output:
[root@server]# curl -D - -s -o /dev/null localhost/
HTTP/1.1 200 OK
Server: nginx/1.10.1
Date: Wed, 13 Jul 2016 18:06:15 GMT
Content-Type: text/html
Content-Length: 612
Last-Modified: Wed, 13 Jul 2016 18:01:34 GMT
Connection: keep-alive
ETag: "578681fe-264"
Accept-Ranges: bytes
The single rule added via the modsecurity_rules directive will deny requests that have the word test inside a GET or POST argument. This can be seen by changing the curl test:
[root@server]# curl -D - -s -o /dev/null localhost/?a=test
HTTP/1.1 403 Forbidden
Server: nginx/1.10.1
Date: Wed, 13 Jul 2016 18:06:19 GMT
Content-Type: text/html
Content-Length: 169
Connection: keep-alive
A 403 response means that Nginx has blocked the request based on processing the request with libmodsecurity. From here, libmodsecurity can be customized using the available directives for ModSecurity (see the ModSecurity reference manual for more information).
Final Notes
It should be noted that libmodsecurity is still in active development, so certain functionality is subject to change. As with any actively developed open source project, be sure to check the source code for the most recent releases.