CODEX
Adding Basic Authentication with Nginx as a reverse proxy
In this article, we are going to set up an Nginx reverse proxy that will add basic authentication to an existing application.
Big picture
We are running a basic web application or service that is missing authentication. We would like to add a simple authentication layer, in our case basic authentication, using a reverse proxy in front of that application.
We will use Docker to power our nginx reverse proxy.
Dockerfile
Starting with our Dockerfile for the nginx reverse proxy:
Starting from the official nginx docker image we are doing the following:
- Install apache2-utils so that we can later use htpasswd command line to generate the file that will contain our basic credentials (login and password if you prefer)
- Define 4 environment variables that we will use to configure our Nginx reverse proxy :
- BASIC_USERNAME: The username (or login) that we will use to authenticate.
- BASIC_PASSWORD: The password associated to our username.
- FORWARD_HOST: The hostname of our backend application that we want to protect with basic authentication.
- FORWARD_PORT: The port used by our backend application.
- Copy a simple nginx configuration file that we will detail in the next section
- Modify the CMD to point to a little script “run.sh” that will detail later.
Nginx configuration
Let’s look at the nginx-basic-auth.conf file now:
It is fairly simple configuration with:
- Instructions to add basic authentication. Note the .htpasswd that will contain username and password.
- Reverse proxy configuration (proxy_pass) to route traffic to our backend.
Run.sh script
Let’s now look at our run.sh script that we are using in the docker CMD command:
The first instruction will take advantage of envsubst to replace environment variables FORWARD_HOST and FORWARD_PORT. We then copy generated nginx config file in /etc/nginx/conf.d/default.conf to override the default configuration.
The second instruction is simple generating the .htpasswd file given BASIC_USERNAME and BASIC_PASSWORD environment variables.
Last instruction is starting nginx. “daemon off;” ensures that nginx stays in foreground (otherwise your container will stop immediately after starting).
Let’s build this and run it
Building the docker image is as simple as:
docker build -t nginx-basic-auth .
We can now use it:
docker run -it -p 80:80 --env BASIC_USERNAME=john.doe --env BASIC_PASSWORD=myp@ssword! --env FORWARD_HOST=localhost --env FORWARD_PORT=8080 nginx-basic-auth
Browsing to http://localhost will prompt you for credentials:
Docker Compose example
Here is a basic example with docker compose. We are using a simple Apache server (httpd)as the backend application (could be anything) and simple add our nginx reverse proxy to add basic authentication:
Note the the Apache application is not exposed using the port instruction. Nginx is using the network named “mynetwork” to access Apache, also exposed over port 80.
To start the stack simply run:
docker-compose up
Source code
The complete source code is available here :
https://gist.github.com/laurentbel/c4c7696890fc71c8061172a932eb52e4
Important security considerations
Basic Authentication over http is NOT secure at all. You indeed need to run it over HTTPS. To simplify this tutorial, I did not configure nginx to use HTTPS, but this is required shall you want to deploy that to production.