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).

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.

Http authentication 1

Only if the correct credentials are entered are we shown the restricted page.

http authentication 2

Otherwise, we get a 401 HTTP response telling us that authorization is required for us to view the requested resource.

http authentication 3

SHARE THIS POST
THE AUTHOR
Ian Muscat

Ian Muscat used to be a technical resource and speaker for Acunetix. More recently, his work centers around cloud security and phishing simulation.