8.2.9 Installing ModSecurity WAF for Nginx

TheHost Banner WAF

WAF ModSecurity is an open-source Web Application Firewall that provides protection for websites and web applications against attacks and vulnerabilities. ModSecurity analyzes HTTP traffic, blocks malicious requests, prevents SQL injections, XSS, brute-force attacks, scanning, and other common threats. It works as a module for Apache, Nginx, and IIS, supports flexible rule configuration (including OWASP CRS policies), and maintains detailed security logs.

System Requirements

  • Virtual Server or Dedicated Server
  • Ubuntu 22.04 LTS or Ubuntu 24.04 LTS
  • CPU: minimum 2 cores;
  • RAM: minimum 1 GB;
  • SSD: at least 5 GB of free space;
  • root or sudo access.

Security

Before you start, make sure that UFW or iptables rules are enabled, SSH access is restricted to keys, and all security updates are installed.

Server Preparation

First, update the packages and install dependencies:

sudo apt update && sudo apt install -y \
  git build-essential autoconf automake libtool pkg-config \
  libpcre3 libpcre3-dev libpcre2-dev libxml2 libxml2-dev libyajl-dev \
  zlib1g zlib1g-dev curl wget
  • git – to clone ModSecurity and ModSecurity-nginx repositories;
  • build-essential, autoconf, automake, libtool, pkg-config – tools for building from source;
  • libpcre3, libpcre3-dev, libpcre2-dev – libraries for regular expression support (used by ModSecurity and Nginx);
  • libxml2, libxml2-dev – XML parser (required for ModSecurity);
  • libyajl-dev – JSON parser (ModSecurity);
  • zlib1g, zlib1g-dev – compression (ModSecurity, Nginx);
  • curl – tool for downloading files (needed in later steps).

Create a working directory:

sudo mkdir -p /usr/local/src && cd /usr/local/src

Clone the ModSecurity repository, initialize submodules, and build the library:

git clone --depth 1 -b v3/master https://github.com/SpiderLabs/ModSecurity
cd ModSecurity
git submodule update --init
./build.sh
./configure
make
sudo make install

Clone the connector for Nginx:

cd ..
git clone https://github.com/SpiderLabs/ModSecurity-nginx.git

Download Nginx source code and compile it with the connector:

wget http://nginx.org/download/nginx-1.24.0.tar.gz
 tar -xf nginx-1.24.0.tar.gz
cd nginx-1.24.0
./configure --add-module=../ModSecurity-nginx
make
sudo make install

<$>[note] By default, Nginx files will be installed into /usr/local/nginx. To use standard paths like /etc/nginx, /var/log/nginx, and /usr/sbin/nginx, add the --prefix option to the ./configure command and specify the paths manually. <$>

configurenginx

makeinstall

Configuration

Create the configuration directory:

sudo mkdir -p /etc/nginx/modsec
sudo cp /usr/local/src/ModSecurity/modsecurity.conf-recommended /etc/nginx/modsec/modsecurity.conf
sudo sed -i 's/SecRuleEngine DetectionOnly/SecRuleEngine On/' /etc/nginx/modsec/modsecurity.conf

Add OWASP CRS:

OWASP Core Rule Set (CRS) is a set of standard rules for ModSecurity that protect web applications against the most common attacks such as SQL injection, XSS, CSRF, Local File Inclusion (LFI), Remote File Inclusion (RFI), etc. It is an open-source project maintained by the OWASP community and regularly updated.

Install CRS and copy the rules:

sudo apt install modsecurity-crs -y
cd /etc/nginx/modsec
sudo git clone https://github.com/coreruleset/coreruleset.git
sudo cp coreruleset/crs-setup.conf.example crs-setup.conf
sudo cp -r coreruleset/rules .

sudo cp -r /usr/share/modsecurity-crs/rules /etc/nginx/modsec/

gitsubmoduleupdatefull

Connect the rules in nginx.conf

In the http section of nginx.conf, add the following directives, for example right after default_type application/octet-stream; or before the server { block:

/usr/local/src/nginx-1.24.0/conf/nginx.conf
modsecurity on;
modsecurity_rules_file /etc/nginx/modsec/main.conf;

nginxconf

Run the command to create the configuration file:

nano /etc/nginx/modsec/main.conf

And add the following content:

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

Attack Logging

Create a log directory and set permissions:

sudo mkdir /var/log/modsecurity
sudo chown www-data: /var/log/modsecurity

In modsecurity.conf, specify the audit log path:

/etc/nginx/modsec/modsecurity.conf
SecAuditLog /var/log/modsecurity/audit.log

Check the configuration and reload:

/usr/local/nginx/sbin/nginx -t && sudo /usr/local/nginx/sbin/nginx -s reload

WAF Testing

To test WAF, simulate an attack. The simplest way is to execute a SQL injection via URL directly in a web browser or using curl. WAF should detect the threat and return a 403 Forbidden error. Try:

http://your-domain.com/?id=1' OR '1'='1

The browser should return 403 Forbidden. Check the log with:

tail -f /var/log/modsecurity/audit.log
Common Issues and Solutions
Problem Solution
WAF does not block anything Ensure SecRuleEngine On and CRS rules are enabled
Logs are empty Check log file permissions and disk space
403 error on valid forms Enable DetectionOnly, find RuleID and add an exception
CRS 901001 error “CRS is deployed without configuration” — crs-setup.conf missing. Copy the file and restart service.
Nginx build error If ./configure doesn’t detect PCRE or Zlib, install libpcre2-dev and zlib1g-dev, then rebuild.

Official Documentation and Useful Links