Nginx with libmodsecurity (ModSecurity 3.x) and OWASP ModSecurity Core Rule Set (CRS) on Ubuntu 16.04

Please note: This guide is deprecated and it has been replaced by our Aegis WAF project for Ubuntu 18.04. Aegis WAF provides easy installation script for your existing Ubuntu 18.04 machine, latest version of Nginx, Modsecurity 3.x.x, OWASP Modsecurity Core Rule Set and Certbot (Let's Encrypt Certificates) support. More information can be found on our Aegis WAF Github page.

This guide assumes you already have a brand new updated instance of Ubuntu 16.04 64-bit. We are going to be installing and compiling the latest version of Nginx with libmodsecurity a.k.a Modsecurity 3.x which is NOT to be confused with ModSecurity 2.x. Additionally, we are going to be integrating OWASP ModSecurity Core Rule Set (CRS).

Install pre-requisites

apt-get install \
apache2-dev \
autoconf \
automake \
build-essential \
bzip2 \
checkinstall \
devscripts \
flex \
g++ \
gcc \
git \
graphicsmagick-imagemagick-compat \
graphicsmagick-libmagick-dev-compat \
libaio-dev \
libaio1 \
libass-dev \
libatomic-ops-dev \
libavcodec-dev \
libavdevice-dev \
libavfilter-dev \
libavformat-dev \
libavutil-dev \
libbz2-dev \
libcdio-cdda1 \
libcdio-paranoia1 \
libcdio13 \
libcurl4-openssl-dev \
libfaac-dev \
libfreetype6-dev \
libgd-dev \
libgeoip-dev \
libgeoip1 \
libgif-dev \
libgpac-dev \
libgsm1-dev \
libjack-jackd2-dev \
libjpeg-dev \
libjpeg-progs \
libjpeg8-dev \
liblmdb-dev \
libmp3lame-dev \
libncurses5-dev \
libopencore-amrnb-dev \
libopencore-amrwb-dev \
libpam0g-dev \
libpcre3 \
libpcre3-dev \
libperl-dev \
libpng12-dev \
libpng12-0 \
libpng12-dev \
libreadline-dev \
librtmp-dev \
libsdl1.2-dev \
libssl-dev \
libssl1.0.0 \
libswscale-dev \
libtheora-dev \
libtiff5-dev \
libtool \
libva-dev \
libvdpau-dev \
libvorbis-dev \
libxml2-dev \
libxslt-dev \
libxslt1-dev \
libxslt1.1 \
libxvidcore-dev \
libxvidcore4 \
libyajl-dev \
make \
openssl \
perl \
pkg-config \
tar \
texi2html \
unzip \
zip \


Git clone Modsecurity, checkout and build libmodsecurity

cd /opt/
git clone
cd ModSecurity
git checkout -b v3/master origin/v3/master
git submodule init
git submodule update
make install


Git clone the Modsecurity-nginx connector

cd /opt/
git clone

You should now have the following directory which contains the Modsecurity-nginx connector



Download latest Nginx stable source

Goto and get the link to the latest stable version of Nginx. As of this writing, the latest stable version was nginx-1.12.0.tar.gz. Adjust instructions below for your specific version. Download and extract

tar -zxf nginx-1.12.0.tar.gz


Download the headers-more-nginx-module

This module allows you to add, set, or clear any output or input header that you specify. This is an enhanced version of the standard headers module because it provides more utilities like resetting or clearing "builtin headers" like Content-Type, Content-Length, and Server. The headers-more-nginx-module can be downloaded from

Technically, the headers-more-nginx-module is not required for Modsecurity, however it's nice to have installed in your nginx environment. If you prefer, you can completely skip downloading and extracting this module. If you decide to skip this module, ensure that you you do not include the --add-module=/opt/headers-more-nginx-module-master in the ./configure command under the Configure Nginx section below.



Configure Nginx with the headers-more-nginx-module and the Modsecurity-nginx connector and install

cd nginx-1.12.0
./configure --user=www-data --group=www-data --with-pcre-jit --with-debug --with-http_ssl_module --with-http_realip_module --add-module=/opt/headers-more-nginx-module-master --add-module=/opt/ModSecurity-nginx
make install

The ModSecurity source code that we downloaded earlier includes a sample modsecurity.conf file with some recommended settings. Copy this file to the folder with the Nginx configuration files

cp /opt/ModSecurity/modsecurity.conf-recommended /usr/local/nginx/conf/modsecurity.conf

Create a symlink from /usr/local/nginx/sbin/nginx to /bin/nginx

ln -s /usr/local/nginx/sbin/nginx /bin/nginx

Create the following directories:

mkdir /usr/local/nginx/conf/sites-available
mkdir /usr/local/nginx/conf/sites-enabled
mkdir /usr/local/nginx/conf/ssl

Create the following symlinks:

ln -s /usr/local/nginx/ /etc/nginx
ln -s /usr/local/nginx/conf/ssl /etc/nginx/ssl
ln -s /usr/local/nginx/conf/mime.types /etc/nginx/mime.types
ln -s /usr/local/nginx/conf/nginx.conf /etc/nginx/nginx.conf

Make a backup copy of the conf/nginx.conf file

cp /usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/nginx.bak

Configure the /usr/local/nginx/conf/nginx.conf file

vi /usr/local/nginx/conf/nginx.conf

Locate and remove all the entries starting with "server {" and ending with the second to the last closing curly brace "}". In other words, leave the last curly brace intact.

Right above the last curly brace, insert the following. This will instruct Nginx to look for our site configs in the "/usr/local/nginx/conf/sites-enabled" directory

include /usr/local/nginx/conf/sites-enabled/*;

So the end of the file should look like below:

include /usr/local/nginx/conf/sites-enabled/*;

Enable the "user" directive by removing the "#" prefix if disabled and ensure it's set to user "www-data" instead of the default "nobody" so it looks like below:

user www-data;

Change the "pid" drective by removing the "#prefix" if disabled and setting it to "/var/run/" so it looks like below:

pid /var/run/;

Save the file


Download Jason Giedymin's Nginx init script for managing nginx service and configure it as a service

wget -O /etc/init.d/nginx
chmod +x /etc/init.d/nginx
update-rc.d nginx defaults

This script provides the following options for managing the Nginx service:

# service nginx start|stop|restart|force-reload|reload|


Git clone and copy the current version of the OWASP ruleset and config to Nginx

cd /opt/
git clone
cd owasp-modsecurity-crs/
cp -R rules/ /usr/local/nginx/conf/
cp /opt/owasp-modsecurity-crs/crs-setup.conf.example /usr/local/nginx/conf/crs-setup.conf


Configure Nginx with OWASP ModSecuirty Core Rule Set

Edit /usr/local/nginx/conf/modsecurity.conf

vi /usr/local/nginx/conf/modsecurity.conf

At the end of the file, paste the following:

#Load OWASP Config
Include crs-setup.conf
#Load all other Rules
Include rules/*.conf
#Disable rule by ID from error message
#SecRuleRemoveById 920350

In your Nginx modsecurity.conf file or your individual server conf files enter the following in either the server or location blocks. The example below, shows a combination of adding the entries in both the server and the location blocks:

server {
modsecurity on;
location / {
modsecurity_rules_file /usr/local/nginx/conf/modsecurity.conf;

Test your Nginx config

service nginx configtest

If not errors, reload or restart your Nginx

service nginx reload

You can now view the /var/log/modsec_audit.log for any ModSecurity events

tail -f /var/log/modsec_audit.log

If you are satisfied, edit the /usr/local/nginx/conf/modsecurity.conf file and set "SecRuleEngine" from "DetectionOnly" to "On" like below

SecRuleEngine On