Installing the Naxsi Module in Nginx to Build a WAF (Web Application Firewall)

Since you're reading this, you're probably already familiar with Nginx, so I won't repeat its installation and configuration. We'll go straight to integrating Nginx with Naxsi. If Nginx is still new to you — you don't know where the config file is or how to compile — this article isn't for you yet; please get comfortable with Nginx installation, configuration, and compilation first.

Since you’re reading this, you’re probably already familiar with Nginx, so I won’t repeat its installation and configuration. We’ll go straight to integrating Nginx with Naxsi. If Nginx is still new to you — you don’t know where the config file is or how to compile — this article isn’t for you yet; please get comfortable with Nginx installation, configuration, and compilation first.

Why do I need a WAF? As the site stays online longer, scans and attacks keep growing. For some peace of mind I wanted a WAF to block most scan attacks. Hardware WAFs are great but expensive, and small companies or startups simply can’t afford such security gear. But Nginx + Naxsi can build a free software WAF, so I started using Naxsi to implement mine.

Before starting, here’s the environment you need to prepare (my demo runs on Linux):

1. Download and Install Dependencies and Packages

1. I use CentOS 7, so I install directly with yum:

yum -y install crontabs gcc gcc-c++ glibc libpcre3-dev make zlib autoconf openssl openssl-devel wget libxslt-devel gd gd-devel GeoIP GeoIP-devel pcre pcre-devel

2. Download Nginx:

wget -P /usr/local/src/ http://nginx.org/download/nginx-1.16.0.tar.gz

3. Download Naxsi:

wget -P /usr/local/src/ https://github.com/nbs-system/naxsi/archive/untagged-afabfc163946baa8036f.tar.gz

4. Extract Nginx and Naxsi:

tar vxf nginx-1.16.0.tar.gz
tar vxf untagged-afabfc163946baa8036f.tar.gz

Note: untagged-afabfc163946baa8036f.tar.gz is the downloaded Naxsi; after extraction it becomes the naxsi folder referenced below.

5. Create Nginx’s working directory:

mkdir /usr/local/nginx

6. Configure Nginx’s modules, adding the Naxsi module here. Note that ”../naxsi/” below is the extracted Naxsi folder:

cd nginx-1.16.0/
./configure \
    --prefix=/usr/local/nginx \
    --user=nginx \
    --group=nginx \
    --add-module=../naxsi/naxsi_src \
    --with-http_stub_status_module\
    --with-http_gzip_static_module\
    --with-http_realip_module\
    --with-http_ssl_module

7. Compile and install:

make modules
make
make install

8. Copy Naxsi’s core rules file to the target location:

cp ../naxsi/naxsi_config/naxsi_core.rules /etc/nginx/naxsi_core.rules

2. Configure Nginx’s nginx.conf

1. In the http block:

http {
	# context omitted

	include       /etc/nginx/naxsi_core.rules; # load the naxsi core rules file here

	# context omitted
}

2. In the server block:

server {
	# context omitted

	# enable the Naxsi module
	SecRulesEnabled;
	# enable learning mode: instead of denying access when a request is blocked, only write the rule-triggered request to the log
    #LearningMode; #enable learning mode
    LibInjectionSql; #enable libinjection support for SQLI
    LibInjectionXss; #enable libinjection support for XSS

	# page shown when access is denied
	DeniedUrl "/RequestDenied";

	# check rules
	CheckRule "$SQL >= 8" BLOCK;
	CheckRule "$RFI >= 8" BLOCK;
	CheckRule "$TRAVERSAL >= 4" BLOCK;
	CheckRule "$EVADE >= 4" BLOCK;
	CheckRule "$XSS >= 8" BLOCK;
	error_log  logs/naxsi.log;

	# the page shown when access is denied after blocking; here we simply return 403
    location /RequestDenied {
      return 403;
    }

	# context omitted
}

A note on LearningMode: if you uncomment it to enable learning mode, attacks won’t be blocked — the attack requests are only written to the error_log. To actually block attacks, keep it commented out.

3. Restart Nginx and Verify It Blocks Attack Requests

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

Verification is simple — issue a request like this:

http://localhost/?id=<>

If you get a 403 Forbidden, it worked!