Toggle menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

Setting Up Libmodsecurity3, Nginx Connector, & OWASP Ruleset on Nginx

From John's Wiki

Setting Up Libmodsecurity3, Nginx Connector, & OWASP Ruleset on Nginx

Logos
Logos

Background Info

Okay so tldr the modsecurity project recently back in January of 2024 switched hands from Trustwave SpiderLabs to the OWASP Foundation. More info here.

This transfer of stewardship means continued development of libmodsecurity3, is now under OWASP’s control. The new libmodsecurity3 is a complete rewrite, allowing them to make it platform independent (not dependant on Apache). Tldr, it is no longer just a module, it is its own library now, with the “Connectors” broken out into their own separate github repos.

Nginx ModSecurity Connector

Another thing, even though Nginx does have a connector and can use libmodsecurity3, the version of the package in apt its several years old already (default version in apt is v3.0.6 from 2021) and lack support for the newest features.

All of the guides I’ve found and even the official install docs say to just build the latest releases of the lib and connector from source. Trust me, its really not that hard.

Nginx ModSecurity

I’m installing this on a burner VM running Ubuntu 22.04 and Nginx 1.18.0, just to learn and document the process before trying to integrate this further into my own systems.

Fastfetch Img
Fastfetch Img

Overview

The server and Nginx are already setup stock with one Server Block (aka vhost) defined. I’m using the stock version of Nginx from apt.

What all needs setup?

As mentioned previously, we're going to be compiling the first two from source.

Mostly following their official docs. I know that’s for 22.10 but I they don’t have one for 22.04 yet so assuming those are mostly the same apt reqs. Except our version of nginx needs to use libpcre3.

Apt Requirements

There are some requirements to build these packages.

sudo apt-get install git g++ apt-utils autoconf automake build-essential libcurl4-openssl-dev libgeoip-dev liblmdb-dev libtool libxml2-dev libyajl-dev pkgconf zlib1g-dev libpcre3 libpcre3-dev

Building Libmodsecurity v3.0.12 from Source

Pretty straight forward, just clone the repo (master is v3.0.12) then update the git submodules and build with normal make cmds.

sudo su
cd /opt
git clone https://github.com/owasp-modsecurity/ModSecurity
cd ModSecurity/
git submodule init
git submodule update
sh build.sh
./configure --with-pcre
make
make install

Building Nginx Connector Module v1.0.3

After installing the library you can build the connector.

NOTE: The connector module has to be compiled against the source code version of Nginx you have installed.

Check Nginx version and build flags:

root@server:/opt# nginx -V
nginx version: nginx/1.18.0 (Ubuntu)
built with OpenSSL 3.0.2 15 Mar 2022
TLS SNI support enabled
configure arguments: --with-cc-opt='-g -O2 -ffile-prefix-map=/build/nginx-zctdR4/nginx-1.18.0=. -flto=auto -ffat-lto-objects -flto=auto -ffat-lto-objects -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -flto=auto -ffat-lto-objects -flto=auto -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-compat --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --add-dynamic-module=/build/nginx-zctdR4/nginx-1.18.0/debian/modules/http-geoip2 --with-http_addition_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_sub_module

To quote the guide I’m following.

We need to compile Nginx with ModSecurity module. We will not compile/install Nginx itself but compile the Nginx module only. For this, make sure that your Nginx package is compiled with “–with-compat” flag. The –with-compat flag will make the module binary-compatible with your existing Nginx binary.

First clone the source for the version of nginx you’re running. In our case, nginx/1.18.0.

sudo su
cd /opt
wget http://nginx.org/download/nginx-1.18.0.tar.gz
tar -xzf nginx-1.18.0.tar.gz

Then clone the latest connector module repo. After that build the modules for Nginx and copy the .so file into /usr/share/nginx/modules/.

git clone https://github.com/owasp-modsecurity/ModSecurity-nginx
cd nginx-1.18.0
./configure --add-dynamic-module=/opt/ModSecurity-nginx --with-compat
make modules
cp objs/ngx_http_modsecurity_module.so /usr/share/nginx/modules/

Configuring Nginx

Cool, so now we’ve got libmodsecurity3 built and installed, we’ve got the nginx connector module built and installed, and we just have to setup Nginx to work with them.

Installing OWASP CSR v4

First we’ll install core ruleset version 4. These instructions are basically exactly the same as for Apache, just pulling in the ruleset files really.

To install the core ruleset version v4.0.0 (latest stable) you can pull them from github.

sudo su
cd /opt
wget https://github.com/coreruleset/coreruleset/archive/refs/tags/v4.0.0.tar.gz
wget https://github.com/coreruleset/coreruleset/releases/download/v4.0.0/coreruleset-4.0.0.tar.gz.asc

Then you can add their pgp key and verify the signature with it.

# gpg --keyserver keys.openpgp.org --recv 0x38EEACA1AB8A6E72
gpg: /root/.gnupg/trustdb.gpg: trustdb created
gpg: key 38EEACA1AB8A6E72: public key "OWASP Core Rule Set <security@coreruleset.org>" imported
gpg: Total number processed: 1
gpg:               imported: 1

# gpg --verify coreruleset-4.0.0.tar.gz.asc v4.0.0.tar.gz
gpg: Signature made Wed 14 Feb 2024 05:48:48 PM UTC
gpg:                using RSA key 36006F0E0BA167832158821138EEACA1AB8A6E72
gpg:                issuer "security@coreruleset.org"
gpg: Good signature from "OWASP Core Rule Set <security@coreruleset.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 3600 6F0E 0BA1 6783 2158  8211 38EE ACA1 AB8A 6E72

Once you’ve verified the fingerprint is legit you’re all good to extract the ruleset.

mkdir /opt/crs4
tar -xzvf v4.0.0.tar.gz --strip-components 1 -C /opt/crs4

Lastly, copy the example crs-conf file into place.

cd /opt/crs4
mv crs-setup.conf.example crs-setup.conf

Setting Up Module & Nginx Conf

Add the load_module line to 50-mod-http-modsecurity.conf and then create a symlink to enable the module.

echo 'load_module modules/ngx_http_modsecurity_module.so;' > /usr/share/nginx/modules-available/mod-http-modsecurity.conf
ln -s /usr/share/nginx/modules-available/mod-http-modsecurity.conf /etc/nginx/modules-enabled/50-mod-http-modsecurity.conf

Then copy the recommended mod sec conf into place. There’s also a unicode.mapping that should be copied over too.

mkdir /etc/nginx/modsec/
cp /opt/ModSecurity-nginx/.github/nginx/modsecurity.conf /etc/nginx/modsec/
cp /opt/ModSecurity/unicode.mapping /etc/nginx/modsec

Now we can create our main ModSec conf: /etc/nginx/modsec/main.conf.

Add these lines:

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

Finally, in our main site’s server block we can enable mod security for our site.

vim /etc/nginx/sites-available/example.com

Add these contents to the server block.

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

Finally, restart Nginx and enjoy the protections of libmodsecurity3 + the OWASP ruleset!

systemctl restart nginx

You can test your new mod security setup is working correctly by visiting https://yourdomain.com/?test=/etc/passwd in a browser. If everything is setup correctly you should now be greeted with a 403 forbidden.

testing mod security
testing mod security

Sources