How to Secure Nginx with Naxsi Firewall on Ubuntu 18.04 VPS
Last updated: November 10th 2022
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 18.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.
Prerequisites
- A Webdock cloud Ubuntu 18.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 18.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.17.0
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.17.0.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.17.0.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.17.0 built with OpenSSL 1.1.1b 26 Feb 2019 (running with OpenSSL 1.1.1c 28 May 2019) TLS SNI support enabled configure arguments: --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-RFWPEB/nginx-1.17.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module --add-dynamic-module=/build/nginx-RFWPEB/nginx-1.17.0/debian/modules/http-auth-pam --add-dynamic-module=/build/nginx-RFWPEB/nginx-1.17.0/debian/modules/http-dav-ext --add-dynamic-module=/build/nginx-RFWPEB/nginx-1.17.0/debian/modules/http-echo --add-dynamic-module=/build/nginx-RFWPEB/nginx-1.17.0/debian/modules/http-upstream-fair –add-dynamic-module=/build/nginx-RFWPEB/nginx-1.17.0/debian/modules/http-subs-filter
Next, stop the running Nginx service with the following command:
systemctl stop nginx
Next, remove all dynamic modules, 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.17.0 ./configure --with-cc-opt='-g -O2 -fdebug-prefix-map=/build/nginx-RFWPEB/nginx-1.17.0=. -fstack-protector-strong -Wformat -Werror=format-security -fPIC -Wdate-time -D_FORTIFY_SOURCE=2' --with-ld-opt='-Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-z,now -fPIC' --add-module=../naxsi-master/naxsi_src/ --sbin-path=/usr/sbin/nginx --prefix=/usr/share/nginx --conf-path=/etc/nginx/nginx.conf --http-log-path=/var/log/nginx/access.log --error-log-path=/var/log/nginx/error.log --lock-path=/var/lock/nginx.lock --pid-path=/run/nginx.pid --modules-path=/usr/lib/nginx/modules --http-client-body-temp-path=/var/lib/nginx/body --http-fastcgi-temp-path=/var/lib/nginx/fastcgi --http-proxy-temp-path=/var/lib/nginx/proxy --http-scgi-temp-path=/var/lib/nginx/scgi --http-uwsgi-temp-path=/var/lib/nginx/uwsgi --with-debug --with-pcre-jit --with-http_ssl_module --with-http_stub_status_module --with-http_realip_module --with-http_auth_request_module --with-http_v2_module --with-http_dav_module --with-http_slice_module --with-threads --with-http_addition_module --with-http_geoip_module=dynamic --with-http_gunzip_module --with-http_gzip_static_module --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_xslt_module=dynamic --with-stream=dynamic --with-stream_ssl_module --with-stream_ssl_preread_module --with-mail=dynamic --with-mail_ssl_module
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 - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled) Active: active (running) since Fri 2019-08-16 09:17:06 UTC; 7s ago Docs: man:nginx(8) Process: 16521 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Process: 16520 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 16522 (nginx) Tasks: 13 (limit: 4915) CGroup: /system.slice/nginx.service ├─16522 nginx: master process /usr/sbin/nginx -g daemon on; master_process on; ├─16523 nginx: worker process ├─16524 nginx: worker process ├─16525 nginx: worker process ├─16526 nginx: worker process ├─16527 nginx: worker process ├─16528 nginx: worker process ├─16529 nginx: worker process ├─16530 nginx: worker process ├─16531 nginx: worker process ├─16532 nginx: worker process ├─16533 nginx: worker process └─16534 nginx: worker process Aug 16 09:17:06 ubuntu systemd[1]: Starting A high performance web server and a reverse proxy server... Aug 16 09:17:06 ubuntu systemd[1]: Started A high performance web server and a reverse proxy 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 136.243.240.38; 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
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://136.243.240.38/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:
2019/08/15 03:03:13 [error] 12773#0: *6 NAXSI_FMT: ip=27.61.137.35&server=136.243.240.38&uri=/&vers=0.56&total_processed=4&total_blocked=3&config=block&cscore0=$SQL&score0=8&cscore1=$XSS&score1=8&zone0=ARGS&id0=1001&var_name0=q, client: 27.61.137.35, server: localhost, request: "GET /?q="><script>alert(1)</script> HTTP/1.1", host: "136.243.240.38"
To test Naxsi against SQLi attack, open your web browser from the remote system and type the URL http://136.243.240.38/?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:
2019/08/15 02:59:52 [error] 12773#0: *1 NAXSI_FMT: ip=27.61.137.35&server=136.243.240.38&uri=/&vers=0.56&total_processed=1&total_blocked=1&config=block&cscore0=$SQL&score0=40&cscore1=$XSS&score1=40&zone0=ARGS&id0=1001&var_name0=q, client: 27.61.137.35, server: localhost, request: "GET /?q=1%22%20or%20%221%22=%221%22 HTTP/1.1", host: "136.243.240.38"
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