Skip to content

[Linux] Using htpasswd for Nginx Authentication

Last Updated on 2024-08-04 by Clay

htpasswd is a tool used for Apache and Nginx web servers to create and manage username and password files, enabling basic authentication when using Nginx as a reverse proxy.

It’s important to emphasize that while htpasswd and Nginx’s authentication mechanism is simple to implement, it’s suitable for applications that only need basic protection, such as internal tools or small applications that don’t involve sensitive data. Depending on the application’s domain and privacy management needs, a more complex authentication system may be required to enhance security.

Here is a detailed tutorial on how to use htpasswd for basic authentication in Nginx. For instructions on setting up Nginx, refer to my previous article: [Linux] Using Nginx to Reverse Proxy and Forward Service Requests to Different Ports on a Single Port


Setting Up a Simple Python API Service

Python API Service

To test the htpasswd authentication mechanism, we’ll quickly start two simple services using Python’s fastapi and uvicorn packages.

pip install fastapi uvicorn


Then

from fastapi import FastAPI
import uvicorn
import argparse


def create_app(api_name: str, port: str) -> FastAPI:
    app = FastAPI()

    @app.get(f"/api/{api_name}")
    async def read_root():
        return {"message": f"Hi, I am the endpoint /api/{api_name} on port {port}"}

    return app


if __name__ == "__main__":
    parser = argparse.ArgumentParser(description="FastAPI server")
    parser.add_argument("--port", type=int, default=8000, help="Port to run the server on")
    parser.add_argument("--api-name", type=str, required=True, help="API name to be used in the endpoint")
    args = parser.parse_args()

    app = create_app(
        api_name=args.api_name,
        port=args.port,
    )
    uvicorn.run(app, host="0.0.0.0", port=args.port)


Next, we start services on two different ports with different API names:

python3 fastapi_service.py --api-name service1 --port 8001
python3 fastapi_service.py --api-name service2 --port 8002



Setting Up Nginx Reverse Proxy with htpasswd Authentication

Step 1. Install Nginx

First, we install Nginx:

sudo apt update
sudo apt install nginx


Step 2. Install htpasswd

sudo apt update
sudo apt install apache2-utils


For CentOS or RHEL systems, use the following command:

sudo yum install httpd-tools


Step 3. Generate htpasswd Configuration File

Next, use the htpasswd command to create a new .htpasswd password file and add users.

sudo htpasswd -c /etc/nginx/.htpasswd <USER_NAME>


After execution, the system will prompt for and confirm the new user’s password.

To add more users, use the following command:

sudo htpasswd /etc/nginx/.htpasswd <USER_NAME>


Note that to add users later, do not use the -c parameter, as it will overwrite the previously created .htpasswd file.


Step 4. Configure Nginx .conf and Restart Nginx

First, edit the Nginx configuration file /etc/nginx/conf.d/default.conf:

sudo vim /etc/nginx/conf.d/default.conf


Configure the location logic for forwarding, the .htpasswd file location, and the services that require authentication:

upstream service1 {
    server 192.168.212.152:8001;
}

upstream service2 {
    server 192.168.212.152:8002;
}

server {
    listen 443;

    location /api/service1 {
	auth_basic "Restricted Area";
	auth_basic_user_file /etc/nginx/.htpasswd;
	
        proxy_pass http://service1;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }

    location /api/service2 {
        proxy_pass http://service2;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}


Here, I’ve only configured the /api/service1 service on port 8001 to require authentication; the other does not.

Next, verify the Nginx configuration and restart the Nginx service to apply the settings.

sudo nginx -t
sudo systemctl restart nginx


The final result will show that the /api/service2 service does not require authentication:


But the /api/service1 service will prompt for a username and password:


This concludes the notes on using htpasswd with Nginx to establish a simple authentication mechanism.


References


Read More

Tags:

Leave a Reply