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):
-
- On Linux I installed: 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
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:
If you get a 403 Forbidden, it worked!
