More actions
Setting Up Libmodsecurity3, Nginx Connector, & OWASP Ruleset on Nginx
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.
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.
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.