Installing ModSecurity with Nginx and OWASP CRS on Debian Stretch

First we have to install all dependencies including ModSecurity and Nginx.

It’s recommended to install Nginx from the stable branch of the official repositories, this way you can update nginx without compiling it everytime however we’ll need to compile the module for ModSecurity.

We’ll download the GPG key for the repositories and configure our sources to add Nginx’s.

wget -q -O - | apt-key add -
echo "deb stretch nginx
deb-src stretch nginx" > /etc/apt/sources.list.d/nginx.list

Then we just need to update and install.

apt update
apt install nginx

We can verify we have the latest version with:

nginx -v

Now we’ll install the dependencies, along with ModSecurity

apt install -y apt-utils autoconf automake build-essential git libcurl4-openssl-dev libgeoip-dev liblmdb-dev libpcre++-dev libtool libxml2-dev libyajl-dev pkgconf wget zlib1g-dev git
cd /opt/
git clone --depth 1 -b v3/master --single-branch
git submodule init 
git submodule update 
./Modsecurity/make install
wget -O - | tar xzvf -
cd nginx-1.13.10
./configure --with-compat --add-dynamic-module=../ModSecurity-nginx
make modules
cp objs/ /etc/nginx/modules

Once we have everything installed we need to activate the module, we have to put the next line on the upper part of nginx.conf

load_module modules/;

Now we need a configuration file for modsecurity

mkdir /etc/nginx/modsec
wget -O nginx/modsec/modsecurity.conf

The default behavior it’s detection only, so we need to change it in order to block malicious attacks

sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsec/modsecurity.conf

The final step it’s to download and load the rules.

wget -O - | tar xzf -
cp owasp-modsecurity-crs-3.0.0/crs-setup.conf.example /etc/nginx/modsec/crs-setup.conf
cp -r owasp-modsecurity-crs-3.0.0/rules /etc/nginx/modsec/
mv /etc/nginx/modsec/rules/REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf{.example,}
mv /etc/nginx/modsec/rules/RESPONSE-999-EXCLUSION-RULES-AFTER-CRS.conf{.example,}

Now we have to create a file to load all the rules and the configuration files

touch /etc/nginx/modsec/main.conf

Inside the file we put:

Include "/etc/nginx/modsec/modsecurity.conf"
Include "/etc/nginx/modsec/crs-setup.conf"
Include "/etc/nginx/modsec/rules/*.conf"

And finally we have to enable ModSecurity by putting the next 2 lines on the server block in the nginx configuration files.

modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;

Now we reload Nginx

nginx -s reload

To verify everything’s in order and working, once we reload nginx the nest line should appear on the logs:

ModSecurity-nginx v1.0.0

And to test we have a working WAF

curl -Iv'%20or%20'1'%20=%20'1&password=1'%20or%20'1'%20=%20'1

and it should return something like:

*   Trying
* Connected to ( port 80 (#0)
> HEAD /?username=1%20or%201%20=%201 HTTP/1.1
> Host:
> User-Agent: curl/7.52.1
> Accept: */*
< HTTP/1.1 403 Forbidden
HTTP/1.1 403 Forbidden
< Server: nginx
Server: nginx

and you can see the rule on the logs:

[warn] 5173#5173: *1109 [client] ModSecurity: Warning. Matched "Operator `Ge'
with parameter `5' against variable `TX:ANOMALY_SCORE' (Value: `8' )
[file "/etc/nginx/modsec/rules/REQUEST-949-BLOCKING-EVALUATION.conf"] [line "36"]
[id "949110"] [rev ""] [msg "Inbound Anomaly Score Exceeded (Total Score: 8)"]
[data ""] [severity "2"] [ver ""] [maturity "0"] [accuracy "0"]
 [hostname ""] [uri "/"] [unique_id "152277165429.072461"] 
[ref ""], client:, server:, 
request: "HEAD /?username=1%20or%201%20=%201 HTTP/1.1", host: ""
This entry was posted in Debian, Linux, ModSecurity, Nginx, Proxy, Security, Unix and tagged , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *