Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

How to Secure Nginx With NAXSI on Ubuntu 16.04

DZone's Guide to

How to Secure Nginx With NAXSI on Ubuntu 16.04

Learn how to build your web application firewall.

· Security Zone ·
Free Resource

Discover how to provide active runtime protection for your web applications from known and unknown vulnerabilities including Remote Code Execution Attacks.

Introduction

To start with the basics, Naxsi is a third-party Nginx module that provides web application firewall features. Its function is to provide additional security to your web server while also protecting you from various web attacks such as XSS and SQL injections. Naxsi acts like a DROP-by-default firewall, and for the target website to work properly, your sole task is to add required ACCEPT rules.

With Naxsi being incredibly adaptable and solid, one can use readily available rules for popular web applications such as WordPress. One can also create their own rules and adjust them by using Naxsi's learning mode at the same time

If you are already familiar with ModSecurity for Apache and/or seek similar functionality, then you can use Naxsi. However, you may not find all of ModSecurity's features in Naxsi.

This tutorial shows you how to install Naxsi, understand the rules, create a whitelist, and where to find rules already written for commonly-used web applications.

Prerequisites

To complete this tutorial, you will need:

Installing NAXSI

Most of the Nginx modules are not available through repositories and NAXSI is no exception, so we'll have to manually download and compile NAXSI with Nginx.

Download Nginx and NAXSI.

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


Now, let's extract both the archives.

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


You should have two folders naxsi-master and nginx-1.14.0 in your home directory. If not already created, let's create a separate user for running Nginx server.

useradd -r -s /bin/false www-data


Next, we should have a user called www-data for running the Nginx server. Let's compile the Nginx server with NAXSI we recently downloaded.

cd nginx-1.14.0
./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


After this, run:

make


And:

make install


Once this succeeds, we shall have a compiled version of Nginx with NAXSI.

Configuring NAXSI

Once the installation is done, we'll have to configure Nginx to have NAXSI core rules, follow the steps below to do that :-

First of all, we'll need to copy the NAXSI core rules to Nginx config directory.

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


Now, create a naxsi.rules file inside the Nginx directory:

nano /etc/nginx/naxsi.rules


Next, add these lines in the newly created naxsi.rules file.

SecRulesEnabled;  DeniedUrl "/error.html";  ## Check for all the rules CheckRule "$SQL >= 8" BLOCK;  CheckRule "$RFI >= 8" BLOCK;  CheckRule "$TRAVERSAL >= 4" BLOCK;  CheckRule "$EVADE >= 4" BLOCK;  CheckRule "$XSS >= 8" BLOCK;


Here, we have defined the DeniedUrl, which is the URL NAXSI will redirect to, in case the request is blocked. Now, we need to create an error.html file inside /usr/html directory, which is the home directory of our Nginx server.

Create error.html inside /usr/html directory using the following command.

sudo nano /usr/html/error.html


Next, in the nano editor, put in the following html code and save the file.

<html>
<head><title>Blocked By NAXSI</title></head>
<body bgcolor="white">
<center><h1>Malicious Request</h1></center>
<hr><center>This Request Has been Blocked By NAXSI</center>
</body>
</html>  


Now, include the naxsi_core.rules file in the nginx.conf file:

nano /etc/nginx/nginx.conf


And under the http section of the nginx.conf file, include the nginx_core.rules file.

include /etc/nginx/naxsi_core.rules;


So, Nginx should be configured with NAXSI rules.

As our Nginx was a manual installation, we'll have to create the startup script for Nginx.

sudo nano /etc/init.d/nginx
 #! /bin/sh 
     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


After saving the file, we'll have to make the file executable using the following command:

sudo chmod a+x /etc/init.d/nginx


If everything goes fine, we should be able to start the Nginx server, so let's start the server using the following command.

/etc/init.d/nginx start


Now, the Nginx server should be up and running.

Testing NAXSI

If everything went fine, Nginx server with NAXSI should be up, and to test the same, we will try hitting the server with malicious http requests and analyse the response.

To do so, copy the Public IP of the instance and use cURL to request the Nginx server.

curl 'http://<INSTACE_IP>/?q="><script>alert(0)</script>' http://35.188.90.226/


This URL supplies a malicious XSS script in the q parameter and should be rejected by the server, and if NAXSI rules are working the way we set them up, we should be redirected to the error.html on hitting the above URL.

<html><head><title>Blocked By NAXSI</title></head><body bgcolor="white"><center><h1>Malicious Request</h1></center><hr><center>This Request Has been Blocked By NAXSI</center></body></html>


This should be the response of the above command.

Now, let's verify the same using Nginx log by tailing the Nginx server log using the following command.

2018/09/05 16:02:04 [error] 15217#0: *6 NAXSI_FMT: ip=<CLIENT_IP>&server=<SERVER_IP>&uri=/&learning=0&vers=0.56&total_processed=4&total_blocked=3&block=1&cscore0=$SQL&score0=8&cscore1=$XSS&score1=8&zone0=ARGS&id0=1001&var_name0=q, client: <CLIENT_IP>, server: localhost, request: "GET /?q="><script>alert(0)</script> HTTP/1.1", host: "<SERVER_IP>"


In the log, you should see that XSS request from remote IP address getting blocked by NAXSI.

Let's try another URL with malicious SQL Injection query, which should get blocked too.

curl 'http://<INSTACE_IP>/?q=1" or "1"="1"'


It should also produce the same response in the terminal

<html>
<head><title>Blocked By NAXSI</title></head>
<body bgcolor="white">
<center><h1>Malicious Request</h1></center>
<hr><center>This Request Has been Blocked By NAXSI</center>
</body>
</html>


And in the log file, you should see the blocked entry for the SQL Injection attempt.

2018/09/05 16:02:04 [error] 15217#0: *6 NAXSI_FMT: ip=<CLIENT_IP>&server=<SERVER_IP>&uri=/&learning=0&vers=0.56&total_processed=4&total_blocked=3&block=1&cscore0=$SQL&score0=8&csc
ore1=$XSS&score1=8&zone0=ARGS&id0=1001&var_name0=q, client: <CLIENT_IP>, server: localhost, request: "GET /?q="><script>alert(0)</script> HTTP/1.1", host: "<SERVER_IP>"


Conclusion

Thus, it is incredibly simple to have a web application firewall with Nginx and Naxsi. This will give you a start in the flexible Naxsi module, and hopefully, you will be interested in learning more about it. After this tutorial, you can make your Nginx server not only fast, but also secure.

Find out how Waratek’s award-winning application security platform can improve the security of your new and legacy applications and platforms with no false positives, code changes or slowing your application.

Topics:
nginx ,firewall ,web application security ,web application firewall ,xss prevention ,sql attacks ,tutorial ,security

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}