HTTP Basic Auth with nginx

Sometimes you need to secure a small set of files on your webserver. There is a protocol made for this, called “HTTP Basic Authentication”. Here’s how to set it up in nginx using the stock ngx_http_auth_basic_module module. Please note that this form of security, quite frankly, isn’t very secure. If anyone gets ahold of the associated password file, it will be easy to crack. Keep in mind that this only handles authentication, it does not securely transfer the files over the internet; for that, you will also want to set up SSL.

For this example we’ll be securing everything under the fake website “secure.beginlinux.com”. All of its files will be located at /var/www/secure.beginlinux.com. We’ll assume you just want to securely share a few images or something, so for brevity the examples won’t include things like handling PHP, or any optimizations. These instructions are distribution-agnostic, so it won’t matter what distro you’re running so long as you have a sane UNIX-like environment, and a recent version of Python to help generate the passwords.

First, grab a copy of this well known and maintained helper script that generates passwords. The download link is at the bottom of its page, choose to download in the “Original Format” for a hassle free experience. This script takes a lot of the leg work out of this process.

Now, lets set up the new subdomain under nginx. Under your /etc/nginx/sites-enabled directory (or it’s equivalent), create a file similar to this:

server {
        listen 80;
        server_name secure.beginlinux.com;

        root /var/www/secure.beginlinux.com;
        index index.html index.php;

        location / {
	        auth_basic              "Restricted";
	        auth_basic_user_file    htpasswd;
	        autoindex on;
        }
}

The important parts are the lines in the “location” section that start with “auth_basic”. The first line that simply says “auth_basic” takes a single parameter, which is the “realm” of the authentication. If a user authenticates under one realm on a domain, then accesses other parts of the site that require authentication, they will remain authenticated so long as the realm is the same. The realm is also displayed to the user when they log in, in various ways depending on the browser. You can also set the realm to “off” which will disable authentication for directories deeper in the site’s structure. A site can have multiple realms, and any location can require authentication.

The next line defines what file lists the users and their associated passwords. It is relative to the nginx configuration root, so for most sane installations it will be relative to /etc/nginx, so in this case the file is /etc/nginx/htpasswd.

Once you reload nginx’s configuration with “nginx -s reload”, you can go ahead and test your configuration, but you won’t be able to log in.

The next step is to generate the username and password file.

touch /etc/nginx/htpasswd
python htpasswd.py /etc/nginx/htpasswd bob neato

This will append the user “bob” with a password of “neato” to the htpasswd list. Run it as many times as is needed to add all of your users and passwords. There’s no need to reload nginx when adding or removing users.