Welcome to our guide on how to install and configure NAXSI Nginx WAF on Ubuntu 18.04 LTS.
NAXSI is an acronym for Nginx Anti XSS and SQL injection. It is an opensource, high performance and low rules maintenance web application firewall (WAF) module for NGINX. Unlike other WAFs that rely on signatures to detect and prevent web attacks such as SQLi, XSS etc, Naxsi relies on unexpected characters contained on the HTTP GET and POST requests. To achieve this, it uses simple rules that contains 99% of the known patterns involved in web vulnerabilities.
Installing NAXSI Nginx WAF on Ubuntu 18.04 LTS
Install Nginx-Naxsi on Ubuntu 18.04 LTS
Update and upgrade your system packages;
apt update
apt upgrade
Install the required dependencies.
apt install libpcre3-dev libssl-dev unzip build-essential daemon libxml2-dev libxslt1-dev libgd-dev libgeoip-dev
This guide assumes that this is a totally new Nginx deployment. Since Nginx-Naxsi package is not available on the default Ubuntu 18.04 repositories, you have to download and compile both Nginx and Naxsi from the source.
Download the latest sources of Nginx from here. You can simply obtain the link and pull it with wget
as shown below;
wget http://nginx.org/download/nginx-1.15.8.tar.gz
Unzip the source code;
tar xzf nginx-1.15.8.tar.gz
Download and unzip naxis.
wget https://github.com/nbs-system/naxsi/archive/master.zip
unzip master.zip
Configure Nginx for Naxsi support
Navigate to Nginx source directory and run the configure
script to prepare Nginx for compilation as shown below;
cd nginx-1.15.8
./configure \
--conf-path=/etc/nginx/nginx.conf \
--add-module=../naxsi-master/naxsi_src/ \
--error-log-path=/var/log/nginx/error.log \
--http-client-body-temp-path=/var/lib/nginx/body \
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi \
--http-log-path=/var/log/nginx/access.log \
--http-proxy-temp-path=/var/lib/nginx/proxy \
--lock-path=/var/lock/nginx.lock \
--pid-path=/var/run/nginx.pid \
--user=www-data \
--group=www-data \
--with-http_ssl_module \
--without-mail_pop3_module \
--without-mail_smtp_module \
--without-mail_imap_module \
--without-http_uwsgi_module \
--without-http_scgi_module \
--prefix=/usr
If all is well, you should be able to see the configuration summary;
...
creating objs/Makefile
Configuration summary
+ using system PCRE library
+ using system OpenSSL library
+ using system zlib library
nginx path prefix: "/usr"
nginx binary file: "/usr/sbin/nginx"
nginx modules path: "/usr/modules"
nginx configuration prefix: "/etc/nginx"
nginx configuration file: "/etc/nginx/nginx.conf"
nginx pid file: "/var/run/nginx.pid"
nginx error log file: "/var/log/nginx/error.log"
nginx http access log file: "/var/log/nginx/access.log"
nginx http client request body temporary files: "/var/lib/nginx/body"
nginx http proxy temporary files: "/var/lib/nginx/proxy"
nginx http fastcgi temporary files: "/var/lib/nginx/fastcgi"
The above command generates a Makefile
that can be used to compile Nginx. The compilation is done using the make
command.
make
Once the compilation is done, run the install script.
make install
Once the installation is complete, create Nginx dynamic data libraries directories.
mkdir -p /var/lib/nginx/{body,fastcgi}
Configuring Nginx NAXSI
To begin with, copy the Naxsi core rules, naxsi_core.rules
to Nginx configuration directory. The core rules are what makes the base of a WAF.
cp ~/naxsi-master/naxsi_config/naxsi_core.rules /etc/nginx/
Now that the rules are in place, you need to enable these rules to act on per location basis. You can also define different types of attacks that can be blocked by Naxsi.
vim /etc/nginx/naxsi.rules
SecRulesEnabled;
DeniedUrl "/RequestDenied";
## Check Naxsi rules
CheckRule "$SQL >= 8" BLOCK;
CheckRule "$RFI >= 8" BLOCK;
CheckRule "$TRAVERSAL >= 4" BLOCK;
CheckRule "$EVADE >= 4" BLOCK;
CheckRule "$XSS >= 8" BLOCK;
SecRulesEnabled
enables the Naxsi rules in a specific web location.SecRulesEnabled
directive disables this.- Note that you can set Naxsi in learning mode using the directive,
LearningMode
, where it automatically generates whitelisting rules based on website’s behavior. In this mode, Naxsi doesn’t block any attack. - The
DeniedUrl
defines where Naxsi will redirect blocked requests. - The
CheckRule
directive asks Naxsi to act on a specific request based on the score. The action ca either beALLOW, BLOCK, LOG, DROP
. The score level is between 0-9 and is set by the specific rules.
Next, configure Nginx server to include these rules such that it looks like the below without comments.
vim /etc/nginx/nginx.conf
user www-data;
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
include /etc/nginx/naxsi_core.rules;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
default_type application/octet-stream;
access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location / {
include /etc/nginx/naxsi.rules;
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
Save the file and verify that there is no syntactical errors.
nginx -t
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Create Nginx Startup Service
Since Nginx was installed from the source, you need to create its startup script. Hence create Nginx systemd unit file as shown below;
vim /lib/systemd/system/nginx.service
[Unit]
Description=A high performance web server and a reverse proxy server
Documentation=man:nginx(8)
After=syslog.target network.target remote-fs.target nss-lookup.target
[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t
ExecStart=/usr/sbin/nginx
ExecReload=/usr/sbin/nginx -s reload
ExecStop=/bin/kill -s QUIT $MAINPID
PrivateTmp=true
[Install]
WantedBy=multi-user.target
Reload Systemd Configurations
systemctl daemon-reload
Start Nginx
Run the command below to start nginx.
systemctl start nginx
You can check the status using the command below;
systemctl status nginx
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; disabled; vendor preset: enabled)
Active: active (running) since Wed 2019-01-23 19:57:22 UTC; 2min 54s ago
Docs: man:nginx(8)
Process: 28385 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
Process: 28384 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
Main PID: 28386 (nginx)
Tasks: 2 (limit: 2325)
CGroup: /system.slice/nginx.service
├─28386 nginx: master process /usr/sbin/nginx
└─28388 nginx: worker process
If you see a line, nginx.service: Failed to parse PID from file /run/nginx.pid: Invalid argument
, here is a workaround.
mkdir /etc/systemd/system/nginx.service.d
printf "[Service]\nExecStartPost=/bin/sleep 0.1\n" > /etc/systemd/system/nginx.service.d/override.conf
systemctl daemon-reload
Test Nginx-Naxsi WAF
Since Nginx-Naxsi is set up successfully, it is time to verify that Naxsi can actually block the attempted attacks. Let us begin by testing SQLi.
From a remote server, execute, curl 'http://192.168.43.46/?q=1" or "1"="1"'
while tailing error logs on the web server.
tail -f /var/log/nginx/error.log
2019/01/23 20:17:36 [error] 28470#0: *3 NAXSI_FMT: ip=192.168.43.149&server=192.168.43.46&uri=/&vers=0.56&total_processed=3&total_blocked=3&config=block&cscore0=$SQL&score0=40&cscore1=$XSS&score1=40&zone0=ARGS&id0=1001&var_name0=q, client: 192.168.43.149, server: localhost, request: "GET /?q=1" or "1"="1" HTTP/1.1", host: "192.168.43.46"
2019/01/23 20:17:36 [error] 28470#0: *3 open() "/usr/html/RequestDenied" failed (2: No such file or directory), client: 192.168.43.149, server: localhost, request: "GET /?q=1" or "1"="1" HTTP/1.1", host: "192.168.43.46"
As you can see, the SQLi is blocked. Next, run the command below to test Cross-Site Scripting (XSS) by executing the command; curl 'http://192.168.43.46/?q=<script>alert(0);</script>'
tail -f /var/log/nginx/error.log
2019/01/23 20:27:47 [error] 28470#0: *5 NAXSI_FMT: ip=192.168.43.149&server=192.168.43.46&uri=/&vers=0.56&total_processed=5&total_blocked=5&config=block&cscore0=$SQL&score0=4&cscore1=$XSS&score1=8&zone0=ARGS&id0=1008&var_name0=q, client: 192.168.43.149, server: localhost, request: "GET /?q=<script>alert(0);</script> HTTP/1.1", host: "192.168.43.46"
2019/01/23 20:27:47 [error] 28470#0: *5 open() "/usr/html/RequestDenied" failed (2: No such file or directory), client: 192.168.43.149, server: localhost, request: "GET /?q=<script>alert(0);</script> HTTP/1.1", host: "192.168.43.46"
Beautiful. Naxsi has successfull blocked attempted SQLi and XSS attacks on Nginx web server. Feel free to expore more about NASXI on their wiki page.
the best great
thank you man
Great tutorial. Thanks Amos!
Glad you found it useful Darin. Enjoy