How to Secure Nginx With NAXSI on Ubuntu 16.04
Learn how to build your web application firewall.
Join the DZone community and get the full member experience.
Join For FreeIntroduction
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:
- One Ubuntu 16.04 server set up by following the Ubuntu 16.04 initial server setup guide, including a sudo non-root user and a firewall.
- Basic knowledge of Nginx Server blocks How To Set Up Nginx Server Blocks (Virtual Hosts) on Ubuntu 16.04.
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.
Opinions expressed by DZone contributors are their own.
Comments