How to Secure Nginx with Naxsi Firewall on Ubuntu 20.04 VPS
Last updated: March 8th 2024
Introduction
Nginx is one of the most popular and high-performance web servers in the world. So it is very important part of any system administrator to increase the security of the Nginx server. Naxsi "Nginx Anti XSS & SQL Injection" is a free, open-source and high-performance web application firewall that can be used to protect your webserver against different types of attacks like SQL Injections and Cross-Site Scripting. Naxsi works by detecting unexpected characters in the HTTP GET and POST requests.
In this tutorial, we will show you how to install and configure Naxsi firewall to protect the Nginx server on Ubuntu 20.04 server.
Please note: Doing these actions will temporarily bring down your server. Do not do this on a live site. If you want to add Naxsi to a live server, create a new server from a snapshot and test this out - then migrate your changes back to your live server once you've verified everything is working.
This guide may not work with latest versions of Nginx and Naxsi. Moreover, Naxsi is not longer maintained. So it's not recommended to use it. If you're a Webdock customer, as an alernative, look at our Botguard addon.
Prerequisites
- A Webdock cloud Ubuntu 20.04 instance with LEMP installed.
- You have shell (SSH) access to your VPS.
Getting Started
Before starting, it is recommended to update your system's package to the latest version. You can update them with the following commands:
apt-get update -y apt-get upgrade -y
Once all the packages are updated, restart your server to apply all the configuration changes.
Next, you will need to install all the dependencies required to install Naxsi. You can install all of them with the following command:
apt-get install zlib1g zlib1g-dev build-essential bzip2 unzip libpcre3-dev libssl-dev libgeoip-dev wget unzip libxslt-dev libgd-dev -y
Once all the dependencies are installed, you can proceed to the next step.
Compile Nginx with Naxsi Support
By default, Nginx is pre-installed in Webdock Ubuntu 20.04 instance. But, Naxsi is a third-party Nginx module that does not comes with Nginx package.
So, you will need to download Nginx and Naxsi source, and compile Nginx with Naxsi support.
First, check the installed version of Nginx on your Webdock instance with the following command:
nginx -v
Output:
nginx version: nginx/1.19.6
Once you get the Nginx version, go to the Nginx official website and download the same Nginx version with the following command:
wget http://nginx.org/download/nginx-1.19.6.tar.gz
Next, download the latest version of Naxsi with the following command:
wget https://github.com/nbs-system/naxsi/archive/master.zip
Next, extract the downloaded source file with the following commands:
tar -xvzf nginx-1.19.6.tar.gz unzip master.zip
Before recompiling Nginx, you will also need to find all the installed Nginx modules in the system.
You can list them with the following command:
nginx -V
You should see the output similar to the following:
nginx version: nginx/1.19.6 built by gcc 9.3.0 (Ubuntu 9.3.0-10ubuntu2) built with OpenSSL 1.1.1f 31 Mar 2020 (running with OpenSSL 1.1.1i 8 Dec 2020) TLS SNI support enabled configure arguments: --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.19.6/debian/debuild-base/nginx-1.19.6=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
Next, stop the running Nginx service with the following command:
systemctl stop nginx
Next, copy the output from the "nginx -V" command as shown in the above output and append it to ./configure command, add new arguement --add-module=/root/naxsi-master/naxsi_src/ and --sbin-path=/usr/sbin/nginx and add ./configure at the beginning of configure arguements.
After making all the changes, copy these commands and run on the terminal as shown below:
cd nginx-1.19.6 ./configure --add-module=/root/naxsi-master/naxsi_src/ --sbin-path=/usr/sbin/nginx --prefix=/etc/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx.pid --lock-path=/var/run/nginx.lock --http-client-body-temp-path=/var/cache/nginx/client_temp --http-proxy-temp-path=/var/cache/nginx/proxy_temp --http-fastcgi-temp-path=/var/cache/nginx/fastcgi_temp --http-uwsgi-temp-path=/var/cache/nginx/uwsgi_temp --http-scgi-temp-path=/var/cache/nginx/scgi_temp --user=nginx --group=nginx --with-compat --with-file-aio --with-threads --with-http_addition_module --with-http_auth_request_module --with-http_dav_module --with-http_flv_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_mp4_module --with-http_random_index_module --with-http_realip_module --with-http_secure_link_module --with-http_slice_module --with-http_ssl_module --with-http_stub_status_module --with-http_sub_module --with-http_v2_module --with-mail --with-mail_ssl_module --with-stream --with-stream_realip_module --with-stream_ssl_module --with-stream_ssl_preread_module --with-cc-opt='-g -O2 -fdebug-prefix-map=/data/builder/debuild/nginx-1.19.6/debian/debuild-base/nginx-1.19.6=. -fstack-protector-strong -Wformat -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fPIC' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -Wl,--as-needed -pie'
Next, run the make command to run a series of tasks defined in the Makefile:
make
Next, run the make install command to copy all the configuration files to their correct location:
make install
Once the above command runs successfully that means Nginx has been recompiled with Naxsi support.
Next, start the Nginx service with the following command:
systemctl start nginx
You can verify the Nginx service status with the following command:
systemctl status nginx
If everything goes fine, you should get the following output:
● nginx.service - nginx - high performance web server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2021-02-08 12:14:07 UTC; 6s ago Docs: http://nginx.org/en/docs/ Process: 11179 ExecStart=/usr/sbin/nginx -c /etc/nginx/nginx.conf (code=exited, status=0/SUCCESS) Main PID: 11180 (nginx) Tasks: 397 (limit: 464185) Memory: 28.0M CGroup: /system.slice/nginx.service ├─11180 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf ├─11181 nginx: worker process ├─11182 nginx: worker process ├─11183 nginx: worker process ├─11184 nginx: worker process ├─11185 nginx: worker process ├─11186 nginx: worker process ├─11187 nginx: worker process ├─11188 nginx: worker process ├─11189 nginx: worker process ├─11208 nginx: worker process ├─11233 nginx: worker process └─11264 nginx: worker process Feb 08 12:14:07 ubuntu2004 systemd[1]: Starting nginx - high performance web server... Feb 08 12:14:07 ubuntu2004 systemd[1]: Started nginx - high performance web server.
Configure Naxsi
Naxsi comes with a set of core rules that can be used to determine how requests are blocked from the server. So, you will need to copy Naxsi core rules to the Nginx configuration directory. You can copy them from Naxsi source directory with the following command:
cp -r /root/naxsi-master/naxsi_config/naxsi_core.rules /etc/nginx/
Next, you will need to enable Naxsi rules and define different types of attacks that can be blocked by Naxsi. You can do it by creating naxsi.rules file:
nano /etc/nginx/naxsi.rules
Add the following lines:
SecRulesEnabled; DeniedUrl "/error.html"; ## Check Naxsi 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 create an error.html file to redirected blocked requests to error.html file. Place this in your web root as defined in your nginx configuration, on Webdock this is typically /var/www/html
nano /var/www/html/error.html
Make sure this file is owned by a user and group which belongs to your web server, typically www-data, or you will get a 403 forbidden response instead of the browser showing the block message - to change ownership of the file, execute:
chown www-data:www-data /var/www/html/error.html
Add the following lines:
<html> <head> <title>Blocked By NAXSI</title> </head> <body> <div style="text-align: center"> <h1>Malicious Request</h1> <hr> <p>This Request Has Been Blocked By NAXSI.</p> </div> </body> </html>
Save and close the file. Then, configure Nginx server to include Naxsi rules by editing nginx.conf file:
nano /etc/nginx/nginx.conf
Add the following lines within http {} section:
include /etc/nginx/naxsi_core.rules;
Save and close the file.
Next, create or edit an existing Nginx virtual host file and include naxsi.rules. You will need to include naxsi.rules file in each virtual host that you want to enable Naxsi.
nano /etc/nginx/sites-available/webdock.conf
Add highlighted line to your location / {} block:
server { listen 80; root /usr/share/nginx/html; index index.html index.htm; # Make site accessible from http://localhost/ server_name 45.148.29.27; location / { include /etc/nginx/naxsi.rules; try_files $uri $uri/ =404; } }
Save and close the file. Then, check Nginx for any syntax error with the following command:
nginx -t
If everything goes fine, you should get the following output:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Next, enable the Nginx virtual host and remove the default virtual host with the following command:
ln -s /etc/nginx/sites-available/naxsi.conf /etc/nginx/sites-enabled/ rm -rf /etc/nginx/sites-enabled/webdock
Finally, restart Nginx service to apply all the configuration changes:
systemctl restart nginx
Test Naxsi Firewall
Naxsi firewall is now installed and configured, it's time to test it against SQLi and XSS attack.
To test Naxsi against XSS attack, open your web browser from the remote system and type the URL http://45.148.29.27/q?="><script>alert(1)</script> . As per the Naxsi rules which you have configured earlier, you should be redirected to the error.html page with the following message:
You can also verify this by checking Nginx log as shown below:
tail -f /var/log/nginx/error.log
You should see that XSS request from the remote host has been blocked by Naxsi firewall:
2021/02/08 11:52:04 [notice] 1186#1186: signal process started 2021/02/08 11:52:08 [notice] 1611#1611: signal process started 2021/02/08 11:52:31 [notice] 2454#2454: signal process started 2021/02/08 11:52:32 [notice] 2851#2851: signal process started 2021/02/08 12:19:20 [error] 12018#12018: *1 NAXSI_FMT: ip=106.213.237.134&server=45.148.29.27&uri=/q&vers=1.3&total_processed=2&total_blocked=1&config=block&cscore0=$SQL&score0=8&cscore1=$XSS&score1=8&zone0=ARGS&id0=1001&var_name0=, client: 106.213.237.134, server: 45.148.29.27, request: "GET /q?=%22%3E%3Cscript%3Ealert(1)%3C/script%3E HTTP/1.1", host: "45.148.29.27"
To test Naxsi against SQLi attack, open your web browser from the remote system and type the URL http://45.148.29.27/?q=1" or "1"="1". You should get the same message as shown in the following page:
You can also check the Nginx server log again with the following command:
tail -f /var/log/nginx/error.log
You should get the same message as shown below:
2021/02/08 12:19:20 [error] 12018#12018: *1 NAXSI_FMT: ip=106.213.237.134&server=45.148.29.27&uri=/q&vers=1.3&total_processed=2&total_blocked=1&config=block&cscore0=$SQL&score0=8&cscore1=$XSS&score1=8&zone0=ARGS&id0=1001&var_name0=, client: 106.213.237.134, server: 45.148.29.27, request: "GET /q?=%22%3E%3Cscript%3Ealert(1)%3C/script%3E HTTP/1.1", host: "45.148.29.27" 2021/02/08 12:23:32 [error] 12018#12018: *3 NAXSI_FMT: ip=106.213.237.134&server=45.148.29.27&uri=/&vers=1.3&total_processed=3&total_blocked=2&config=block&cscore0=$SQL&score0=40&cscore1=$XSS&score1=40&zone0=ARGS&id0=1001&var_name0=q, client: 106.213.237.134, server: 45.148.29.27, request: "GET /?q=1%22%20or%20%221%22=%221%22 HTTP/1.1", host: "45.148.29.27"
Congratulations! you have successfully setup Naxsi firewall to protect Nginx server against malicious attacks. Your Nginx webserver is now secured from XSS and SQL injection attack. For more information, you can visit the Naxsi official documentation at Naxsi Doc.
Related articles
-
Server Security Checklist
In this article we list a number of things you should check if you are setting up a server from scratch as well as a few things which can enhance security on our Perfect Server Stacks.
Last updated: November 10th 2022
-
How to check for open ports on your Ubuntu server
This article details various approaches to finding out which ports are open and accessible on your server.
Last updated: November 10th 2022
-
How to work with your firewall (UFW - Uncomplicated Firewall)
In this article we show how UFW - or Uncomplicated Firewall - works along with common commands and usage examples.
Last updated: January 10th 2024
-
SSH Security Configuration Settings
This article lists various settings for the SSH Daemon which impact server security.
Last updated: February 1st 2024
-
How to configure Fail2Ban for common services
How fail2ban can be configured for common services as well as how to utilize the fail2ban CLI tools to check status of various jails, unbanning users and more.
Last updated: August 22nd 2023
-
How to configure Security Headers in Nginx and Apache
Here we outline which security headers are important to set in different scenarios in Nginx and Apache.
Last updated: November 10th 2022
-
How to enable Encryption for MariaDB
Enable Encryption of your database data with MariaDB as well as force all new tables created to be encrypted.
Last updated: October 29th 2024
-
How to Scan Your Webdock Server for Malware and Virus
This guide provides basic step-by-step instructions to install various tools to scan your server for malware and viruses.
Last updated: July 19th 2023
-
How To Use Our Free BotGuard Bot Protection
In this article we show you how to activate and use our Free BotGuard Bot Protection which is included for free with all our VPS servers.
Last updated: November 4th 2024
-
Enhancing Nginx Security with IP Filtering and Password
A guide to enhance Nginx security with IP filtering (specific IP, and, IP ranges) and Password
Last updated: November 25th 2023
-
Securing Ubuntu: How to Detect System Vulnerabilities
Detect system vulnerabilities using Vuls
Last updated: December 20th 2023
-
Secure VPS Communication with SSL and UFW
A detailed guide to securely your communicate with your servers without requiring a VLAN setup.
Last updated: March 4th 2024
-
Configuring UFW and Fail2Ban to Mitigate Basic DDos Attacks
Instructions to protect your server from basic DDos attacks using UFW and Fail2Ban
Last updated: May 28th 2024