Synopsis

Naxsi also known as Nginx Anti XSS & SQL Injection is an open-source web application firewall module for Nginx web server and reverse-proxy. Naxsi is used to protect Nginx web server against attacks like SQL Injections, Cross Site Scripting, Cross Site Request Forgery, Local & Remote file inclusions. Naxsi does not rely upon signatures to detect and block attacks, but it detects unexpected characters in the HTTP requests. Naxsi is flexible and powerful Nginx module and is very similar to ModSecurity for Apache. Naxsi requires minimal memory, minimal runtime processing and no need for updates of any “attack” signatures.

Here, we will explain how to install Naxsi with Nginx and test it against XSS and SQL injection attacks.

System Requirements

  • Ubuntu 16.04 server installed to your server.
  • Static IP address 192.168.15.189 setup on your server.

Update the System

Before starting, it is recommended to update your system with the latest version.

You can update your system with the following command:

apt-get update -y
apt-get upgrade -y

After updating your system, restart your system.

Install Required Dependencies

First, you will need to install some dependencies required by Nginx-Naxsi. You can install them with the following command:

apt-get install build-essential bzip2 unzip libpcre3-dev libssl-dev mysql-server daemon libgeoip-dev wget -y

Once all the packages are installed, you can proceed to the next step.

Install and Configure Nginx-Naxsi

By default, Nginx-Naxsi is not available in Ubuntu 16.04 repository. So you will need to download and compile Nginx and Naxsi first.

You can download Nginx and Naxsi source code with the following command:

wget http://nginx.org/download/nginx-1.13.1.tar.gz
wget https://github.com/nbs-system/naxsi/archive/master.zip

Once the download is completed, extract both file with the following command:

tar -xvzf nginx-1.13.1.tar.gz
unzip master.zip

Before compiling both packages, create user and group www-data:

adduser --system --no-create-home --disabled-login --disabled-password --group www-data

Next, compile Nginx with Naxsi support with the following command:

cd nginx-1.13.1
 ./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 \ 
 --with-http_geoip_module \ 
 --without-mail_pop3_module \ 
 --without-mail_smtp_module \ 
 --without-mail_imap_module \ 
 --without-http_uwsgi_module \ 
 --without-http_scgi_module \ 
 --prefix=/usr

Next, run the following command:

make
make install

Once Nginx is installed, you will need to copy Naxsi core rule set from Naxsi source to the Nginx config directory:

cp /root/naxsi-master/naxsi_config/naxsi_core.rules /etc/nginx/

Next, create a naxsi.rules file inside /etc/nginx/ directory:

nano /etc/nginx/naxsi.rules

Add the following lines:

 SecRulesEnabled; 
 DeniedUrl "/RequestDenied";
 
 ## check rules 
 CheckRule "$SQL >= 8" BLOCK; 
 CheckRule "$RFI >= 8" BLOCK; 
 CheckRule "$TRAVERSAL >= 4" BLOCK; 
 CheckRule "$EVADE >= 4" BLOCK; 
 CheckRule "$XSS >= 8" BLOCK;

Save and close the file when you are finished.

Next, you will need to modify nginx.conf file:

nano /etc/nginx/nginx.conf

Make the following changes:

 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; 
     tcp_nodelay on; 
     gzip on; 
     gzip_disable "MSIE [1-6].(?!.*SV1)";
 
     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 and close the file when you are finished.

Create Nginx Upstart Script

Once Nginx is installed and configured, you will need to create an upstart script for Nginx. You can do this by with the following command:

nano /etc/init.d/nginx

Add the following lines:

 #! /bin/sh PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 
 DAEMON=/usr/sbin/nginx 
 NAME=nginx 
 DESC=nginx
 
 test -x $DAEMON || exit 0 
 # Include nginx defaults if available 
 if [ -f /etc/nginx ] ; then 
         . /etc/nginx 
 fi
 
 set -e
 
 case "$1" in 
     start)
         echo -n "Starting $DESC: " 
         start-stop-daemon --start --quiet --pidfile /var/run/nginx.pid \ 
             --exec $DAEMON -- $DAEMON_OPTS 
         echo "$NAME." 
         ;; 
     stop) 
         echo -n "Stopping $DESC: " 
         start-stop-daemon --stop --quiet --pidfile /var/run/nginx.pid \ 
             --exec $DAEMON 
         echo "$NAME." 
         ;; 
     restart|force-reload) 
         echo -n "Restarting $DESC: " 
         start-stop-daemon --stop --quiet --pidfile \ 
             /var/run/nginx.pid --exec $DAEMON 
         sleep 1 start-stop-daemon --start --quiet --pidfile \ 
             /var/run/nginx.pid --exec $DAEMON -- $DAEMON_OPTS 
         echo "$NAME." 
         ;; 
     reload) 
         echo -n "Reloading $DESC configuration: " 
         start-stop-daemon --stop --signal HUP --quiet --pidfile /var/run/nginx.pid \ 
             --exec $DAEMON 
         echo "$NAME." 
         ;; 
     *) 
         N=/etc/init.d/$NAME 
         echo "Usage: $N {start|stop|restart|force-reload}" >&2 
         exit 1 
         ;; 
 esac
 
 exit 0

Save and close the file when you are finished.

Next, test Nginx for any configuration error with the following command:

nginx -t

When all is well, start Nginx service with the folling command:

/etc/init.d/nginx start

Test Nginx-Naxsi

Nginx is now up and running, it’s time to test Naxsi whether it is working or not.

First, we will test how Naxsi protects Nginx web server from XSS attack.

On the remote machine, run the following command to test Naxsi against XSS attack:

curl 'http://192.168.15.189/?q="><script>alert(1)</script>'

On the Nginx server, check the Nginx log file:

tail -f /var/log/nginx/error.log

You should see that XSS request from remote machine IP address 192.168.15.196 is blocked by Naxsi:

 2017/06/11 21:49:21 [error] 1652#0: *4 NAXSI_FMT: ip=192.168.15.196&server=192.168.15.189&uri=/&learning=0&vers=0.55.3&total_processed=4&total_blocked=4&block=1&cscore0=$SQL&score0=8&cscore1=$XSS&score1=8&zone0=ARGS&id0=1001&var_name0=q, client: 192.168.15.196, server: localhost, request: "GET /?q="><script>alert(1)</script> HTTP/1.1", host: "192.168.15.189"

Next, run the following command on the remote machine to test Naxsi against SQL Injection attack:

curl "http://192.168.15.189/?q='1 OR 1=1"

On the Nginx server, check the Nginx log file:

tail -f /var/log/nginx/error.log

You should see that SQL query from remote machine IP address 192.168.15.196 is blocked by Naxsi:

 2017/06/11 21:52:15 [error] 1652#0: *5 NAXSI_FMT: ip=192.168.15.196&server=192.168.15.189&uri=/&learning=0&vers=0.55.3&total_processed=5&total_blocked=5&block=1&cscore0=$SQL&score0=6&cscore1=$XSS&score1=8&zone0=ARGS&id0=1009&var_name0=q&zone1=ARGS&id1=1013&var_name1=q, client: 192.168.15.196, server: localhost, request: "GET /?q='1 OR 1=1 HTTP/1.1", host: "192.168.15.189"

References