Enhancing Nginx Security with IP Filtering and Password
Last updated: November 25th 2023
Introduction
NGINX is a widely used web server and reverse proxy highly regarded for its outstanding performance and scalability. However, ensuring security has become a paramount concern in today's digital landscape, given the escalating number of cyber threats and data breaches.
In this article, I will delve into two fundamental approaches to bolstering NGINX security: IP filtering and password protection. These techniques thwart unauthorized access and guarantee the safety of your web server.
I will elucidate how these methods operate and provide practical suggestions for their implementation, empowering you to fortify your NGINX server and shield your website from potential risks. Let's delve right in!
Prerequisites
- An NGINX server with sudo access
- HTTPS enabled on your server
Restricting Access Based on IP
NGINX offers directives (allow and deny) that enable you to allow or block client access based on their IP addresses. However, before using these directives, you must determine your IP address.
There are various methods available for doing so, including visiting websites like KeyCDN IP locator or WhatIsMyIP.net or conducting a simple internet search.
I’ll be using 7.1.1.0 as an example IP Address for this tutorial.
By a Specific IP Address
Begin by opening your NGINX configuration file as a sudo user:
$ sudo nano /etc/nginx/sites-enabled/webdock
This path is applicable for default Webdock stacks. The path might be different, depending on the service provider. Usually, the most common path is /etc/nginx/nginx.conf. However, if you're not sure, simply run the command to find your NGINX config file:
$ sudo nginx -t
Once you are confident about the location of your NGINX configuration file, open it and locate or create the location block. Insert the following directive within the block:
allow 7.1.1.0;
To implement these changes, refresh the NGINX configuration:
$ sudo systemctl reload nginx
If you prefer blocking an IP address instead of allowing it, simply change the directive to "deny"
You can even define multiple allow and deny directives. The first directive that meets the conditions will be applied. Ensure to place the two special directives, allow all; and deny all; at the end of the allow/deny list, as they always match.
To enhance compatibility, consider including IPv6 addresses to either allow or deny access. This can prove beneficial in specific scenarios, such as when working with tools like Ansible or Docker.
By a Specific IP Range
In today’s digital landscape, dynamic IP addresses, assigned automatically by a network's Dynamic Host Configuration Protocol (DHCP) server and subject to periodic changes, are more prevalent than static IP addresses, which are manually configured and remain fixed to provide a consistent identifier for a device on a network.
However, in scenarios where access to an NGINX server is restricted based on a static IP address or an organization employs a designated range of IP addresses for NGINX access, using allow and deny directives enables access restriction based on an IP address range, removing the chances of uncertainty or multiple configurations.
To achieve this, simply add the directive to the location block in the NGINX config file:
allow 7.1.1.0/24;
And follow the same process as outlined for restricting access to a specific IP address.
Testing Our Setup
Now, let's test if our setup works. I have created a sample VPS to SSH into our server. You can use your computer's terminal to do this. I chose a VPS to simulate an application and to keep my IP address hidden.
There are many ways you can send ping requests to your server using SSH, but I prefer using the following:
$ curl -4 --head https://your-domain.com
The cURL command is a powerful command-line tool that allows you to transfer data to or from a server using different protocols.
In this particular case, the command curl -4 --head https://your-domain.com is used to send an HTTP HEAD request to the specified URL using the IPv4 protocol (-4).
By using the --head option, cURL only retrieves the response headers without downloading the page's actual content.
As illustrated, the IP address of this particular VPS is in our deny list. Notice the response:
As you can see, the response indicates that the request was forbidden, and the server is denying access to the requested resource due to its IP Address.
However, if we change the directive to allow the IP address, we get the following response:
This indicates that the server responded with a status code of 200, which means the request was successful. Congratulations, your setup works well!
Restricting Access with Password
To enhance security further, We'll set up HTTP Basic authentication to improve access restrictions, which grants access solely to password-protected users.
However, using HTTPS rather than HTTP is strongly advised to safeguard your username and password from being transmitted in plain text.
Thanks to Webdock's default stacks, you won't have to configure SSL manually. Consequently, I assume you've already enabled HTTPS on your server as we proceed to the next steps.
To start, create a dedicated file to store usernames and passwords:
$ sudo touch /etc/nginx/users
Running this command would create a new file named ‘users’ in the /etc/nginx directory.
Make sure python3 is installed:
$ sudo apt update $ sudo apt install python3
Once your file is created, run the following:
$ python3 -c 'from subprocess import *; import sys; print("Username: ", end="", file=sys.stderr); user = input(); passwd = run(["openssl", "passwd", "-6"], encoding="utf-8", stdout=PIPE).stdout.strip(); print("A username is neccessary. Try again!", file=sys.stderr) if user == "" or passwd == "" else print(user + ":" + passwd)' | sudo tee -a /etc/nginx/users
This command prompts you to enter your username. It then generates a SHA-512 encrypted version of your password, checks that neither field is left blank, and appends both the generated username and its corresponding hashed password to the "/etc/nginx/users" file.
To include more users in the "/etc/nginx/users" file, execute the same python3 command as previously mentioned.
If you want to remove users, you can manually edit the "/etc/nginx/users" file by deleting the corresponding lines. Make sure that each user is on a separate line in order to maintain proper organization.
Once this particular file is successfully created or updated accordingly, it grants you complete control over your server block configuration.
To further modify and enhance your server configuration, include two directives, auth_basic and auth_basic_user_file, into your existing server setup:
$ sudo nano /etc/nginx/sites-enabled/webdock
Again, for default Webdock stacks, this path is relevant. However, depending on the service provider, the path might vary. Typically, the most frequently used path is /etc/nginx/nginx.conf.
The auth_basic directive is used to enable basic authentication for a specific location or block in your NGINX configuration. It also lets you customize the error message received when trying to log in.
Whereas, auth_basic_user_file specifies the file that contains the username and password information, which in our example is /etc/nginx/users.
Restart NGINX to implement the modifications:
$ sudo systemctl reload nginx
However, the aforementioned directives will cause your entire website to be locked. If you only want to password-protect a specific URL, you will need to add a new location block to your config file and include the auth_basic and auth_basic_user_file directives within this location block. For instance:
location /area-51 { auth_basic "off limits to unauthorized personnel"; auth_basic_user_file /etc/nginx/users; }
The location block above will password-protect only the /area-51 URL. This can be useful if you want to protect a specific page on your website, such as /wp-admin on WordPress, from unauthorized access. As usual, test your NGINX config file for syntax errors and restart it.
Testing Your Setup
Let’s test if the authentication actually works. I’ll again send a cURL request using my VPS:
$ curl --verbose https://your-domain.com
In this case, the command is making a GET request to the specified URL. The --verbose flag is used to display detailed information about the request and response.
You will receive a long response as a result. Look for indications of denied requests towards the end of the response. You will also see the "custom" error message we added.
Now, let’s make a cURL request again, but this time, with our username and password:
$ curl --verbose -u user:password https://your-domain.com
You will receive a lengthy response again. Look for authentication results towards the end. As you can see, we received a 200 OK response, indicating that our request was authenticated and successful.
Curious about what these HTTP response codes mean? Check out my deep dive into this topic here.
Conclusion
By incorporating IP filtering and password protection, you can defend against cyber threats. IP filtering is a gatekeeper, restricting NGINX server access to specific IP addresses for authorized users only. Similarly, password protection requires valid credentials from users to prevent unauthorized access to sensitive information or changes in server configurations.
Updating software regularly and employing firewalls for managing incoming and outgoing traffic is crucial to bolster NGINX security. Additionally, active monitoring of server activities helps promptly detect suspicious behavior, allowing for timely resolution.
When you implement these security measures together, your NGINX server can transform into an impenetrable fortress, ensuring the integrity and privacy of your website's valuable data.
Meet Aayush Nair, a WordPress website designer with almost a decade of experience who doesn’t only craft visually appealing websites but also has a knack for writing engaging technology blogs. In his spare time, he enjoys illuminating the minds around him.
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 Secure Nginx with Naxsi Firewall on Ubuntu 18.04 VPS
This Article describes how you can set up and configure Naxsi firewall on a Webdock LEMP stack on Ubuntu Bionic 18.04.
Last updated: November 10th 2022
-
How to Secure Nginx with Naxsi Firewall on Ubuntu 20.04 VPS
This Article describes how you can set up and configure Naxsi firewall on a Webdock LEMP stack on Ubuntu Focal 20.04.
Last updated: March 8th 2024
-
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
-
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