cheatsheets devlog projects search

basic-auth.md

File Uploads with Nginx - Part 1

2023-01-25 1

This set of articles is going to build a file upload site using just nginx and some plain html. I could do this using a proper backend like node or go but that adds complexity to my blog site. I’d much rather have a simple solution to the problem of dragging and dropping files onto my blog. This hopefully turns out to be a simple solution!

The first step to doing a file upload site for myself is a login system. I don’t want everyone dumping things into an open dumping ground.

Luckily HTTP has a way of doing authentication. It is rudimentary and a bit dangerous but SSL and some obscurity will get around the danger.

HTTP Basic Authentication works by adding the Authorization header which contains the username:password encoded in base64. This header is sent on every request.

Now on to the show!

Create the User and Password

We first need to create the password file. This file will contain usernames and passwords that nginx will use to validate against. The nginx convention seems to use the apache style .htpasswd.

sudo htpasswd -c .htpasswd username

This command will prompt you for a password, which will then be encrypted and saved in the file .htpasswd.

cat ~/.htpasswd
username:$sp31$6Bd8511BdJ9xcBx9LmhF7WklZriL710

We can add more users by using the htpasswd utility again with the same file. This will append users to the .htpasswd.

Setting Up Nginx

Now we can update nginx to use http basic authentication:

server {
    listen 8081;
    server_name _;

    root /usr/share/nginx/html/blog;

    location /admin {
        auth_basic "Admin Area";
        auth_basic_user_file /home/username/.htpasswd;
    }
}

The auth_basic field will take in any string. Any string here will enable basic authentication. The default is off.

The second field, auth_basic_user_file, will be the path to the password file we generated earlier.

Now we can do service nginx restart and we are off to the races.

We should now be able to go to the admin url and get prompted for a username and password. On success we’ll enter the admin part of the website.

Now we have the ability to log in, the next step is to try and get nginx to handle the file uploads directly!

Postscript

The big downside in my eyes is that the password and username is a static string that is sent with every future request made to this website. With SSL, this data is encrypted but it is still quite uncomfortable to be sending such things constantly.

It probably doesn’t matter if the password was generated and was unique to just this site. At that point even with that many requests, the password being broken doesn’t cause too much damage. It would be like breaking a session token.