Restricting portions of a web application or directories on a web server to a small group of trusted users can greatly improve the security of a website or web application. Most web applications provide their own form-based methods for authentication, however, we can also make use of the web server’s built-in HTTP authentication capabilities when form authentication is not implemented, or not sufficient.
For this how-to, we’ll be securing assets on an Nginx web server running on Ubuntu 16.04. For more tips on hardening Nginx, refer to our two-part Nginx hardening series.
Getting started
To get started, you’ll need a Ubuntu 16.04 server environment as well as Nginx installed.
If you have not yet installed Nginx, you can do so by running the following two commands.
sudo apt update sudo apt install nginx
To verify that Nginx is installed and running, run the following command. It should return something similar to the output below.
sudo service nginx status --> ● 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 Wed 2016-08-03 09:42:19 UTC; 2min 38s ago Main PID: 12947 (nginx) CGroup: /system.slice/nginx.service ├─12947 nginx: master process /usr/sbin/nginx -g daemon on; master_process on ├─12948 nginx: worker process └─12949 nginx: worker process Aug 03 09:42:19 ubuntu-xenial systemd[1]: Starting A high performance web server and a reverse proxy server... Aug 03 09:42:19 ubuntu-xenial systemd[1]: Started A high performance web server and a reverse proxy server.
Creating a password file
For us to set-up HTTP authentication with Nginx, we need to store the combination of usernames and hashed passwords in a file. In order to generate this file, we can use OpenSSL (which should already be installed on your system automatically).
htpasswd
utility found in the apache2-utils
package if you prefer it to OpenSSL.We will start by creating a file called .htpasswd
in /etc/nginx
, which is Nginx’s default configuration directory to store our username and password combinations.
You can add usernames to .htpasswd
by running the following command. The username we’ve chosen is alice
, of course, change this to fit your requirements.
sudo bash -c "echo -n 'alice:' >> /etc/nginx/.htpasswd"
Next, we’ll need to add a hashed password to the user we just created by running the following command. You will be prompted for a password, and you will be asked to verify that password once again.
sudo bash -c "openssl passwd -apr1 >> /etc/nginx/.htpasswd" --> Password: Verifying - Password:
This process can be repeated as many times as necessary to add additional users. To see all users and their hashed passwords, you can simply cat the .htpasswd
file.
cat /etc/nginx/.htpasswd --> alice:$apr1$rxVhn96T$nm0/ZD4J0w9xv6rDvYQ36/
Setting-up Nginx HTTP Authentication
Once our .htpasswd
file is created, we can now configure Nginx to consult this file before serving content in a particular directory.
We will be customizing the default
site configuration as it is installed through Ubuntu’s Nginx package. If you installed Nginx from a different package or you compiled it from source yourself, the path below could be different.
sudo nano /etc/nginx/sites-enabled/default
Before restricting anything, you need to decide what you would like to restrict. Nginx is very flexible here and allows you to restrict access to the entire server (therefore, your configuration should reside in the configuration’s server block) or, to a specific location (therefore, your configuration should reside in the configuration’s location
block).
We shall be restricting a directory named private that resides in the root of the server. We want the rest of the server to function normally and be accessible to all users.
To achieve this, we will make use of Nginx’s auth_basic
directive to enforce this restriction. We will need to specify a realm name, which is what will be displayed to the user attempting to authenticate. We will make use of the auth_basic_user_file
directive to direct Nginx to the .htpasswd
file we created earlier.
server {
listen 80 default_server;
listen [::]:80 default_server;
root /var/www/html;
index index.html index.htm index.nginx-debian.html;
server_name localhost;
location / {
try_files $uri $uri/ =404;
}
location /private {
try_files $uri $uri/ =404;
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
}
}
After saving and closing the file, we need to restart the Nginx daemon for our changes to take effect.
sudo service nginx restart
That’s it! Now anything inside of the private directory should now require HTTP authentication before the web server serves the client with the requested resource.
Testing
To make sure we implemented everything correctly, it’s best to test out our configuration. We can simply use a web browser for this by trying to navigate to the page in question.
Only if the correct credentials are entered are we shown the restricted page.
Otherwise, we get a 401 HTTP response telling us that authorization is required for us to view the requested resource.
Get the latest content on web security
in your inbox each week.