Install and Configure NAXSI Nginx WAF on Ubuntu 18.04 LTS

|
Last Updated:
|
|

Welcome to our guide on how to install and configure NAXSI Nginx WAF on Ubuntu 18.04 LTS.

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 be ALLOW, 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.

Other Tutorials

Install Modsecurity with Nginx on Rocky Linux 8

Install ModSecurity 3 with Apache in a Docker Container

SUPPORT US VIA A VIRTUAL CUP OF COFFEE

We're passionate about sharing our knowledge and experiences with you through our blog. If you appreciate our efforts, consider buying us a virtual coffee. Your support keeps us motivated and enables us to continually improve, ensuring that we can provide you with the best content possible. Thank you for being a coffee-fueled champion of our work!

Photo of author
koromicha
I am the Co-founder of Kifarunix.com, Linux and the whole FOSS enthusiast, Linux System Admin and a Blue Teamer who loves to share technological tips and hacks with others as a way of sharing knowledge as: "In vain have you acquired knowledge if you have not imparted it to others".

3 thoughts on “Install and Configure NAXSI Nginx WAF on Ubuntu 18.04 LTS”

Leave a Comment