
How to Set Up Password Authentication with Nginx on Ubuntu 24
Setting up password authentication with Nginx on Ubuntu 24 is a fundamental security practice that adds an extra layer of protection to your web applications and sensitive directories. This authentication mechanism, also known as HTTP Basic Authentication, prompts users to enter credentials before accessing protected resources. You’ll learn how to configure Nginx’s built-in authentication module, create user credentials, troubleshoot common issues, and implement best practices for securing your web server effectively.
How HTTP Basic Authentication Works with Nginx
Nginx implements HTTP Basic Authentication through the auth_basic
and auth_basic_user_file
directives. When a user requests a protected resource, the server responds with a 401 Unauthorized status code and a WWW-Authenticate header. The browser then displays a login dialog, and the credentials are sent back to the server encoded in Base64 format within the Authorization header.
The authentication process follows this sequence:
- Client requests a protected resource
- Nginx checks for authentication credentials
- If missing, server returns 401 with authentication challenge
- Browser prompts user for username/password
- Credentials are Base64 encoded and sent with subsequent requests
- Nginx validates credentials against the password file
- Access granted or denied based on validation result
Prerequisites and Initial Setup
Before implementing password authentication, ensure your Ubuntu 24 system has the necessary components installed. You’ll need Nginx with the http_auth_basic_module
(included by default) and the apache2-utils
package for creating password files.
sudo apt update
sudo apt install nginx apache2-utils -y
sudo systemctl start nginx
sudo systemctl enable nginx
Verify that Nginx is running correctly:
sudo systemctl status nginx
nginx -v
Step-by-Step Implementation Guide
Creating the Password File
The first step involves creating a password file using the htpasswd
utility. This file stores usernames and encrypted passwords that Nginx will use for authentication.
# Create the first user (creates the file)
sudo htpasswd -c /etc/nginx/.htpasswd username1
# Add additional users (without -c flag)
sudo htpasswd /etc/nginx/.htpasswd username2
sudo htpasswd /etc/nginx/.htpasswd admin
For automated deployments, you can create users non-interactively:
# Using bcrypt encryption (recommended)
sudo htpasswd -cB /etc/nginx/.htpasswd username1 password123
# Using MD5 encryption
sudo htpasswd -cm /etc/nginx/.htpasswd username1 password123
Secure the password file by setting appropriate permissions:
sudo chown root:www-data /etc/nginx/.htpasswd
sudo chmod 640 /etc/nginx/.htpasswd
Configuring Nginx Virtual Host
Next, configure your Nginx virtual host to use the password file. You can apply authentication at different levels: server-wide, location-specific, or directory-specific.
Basic server block configuration:
server {
listen 80;
server_name example.com;
root /var/www/html;
index index.html index.php;
# Apply authentication to entire site
auth_basic "Restricted Access";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
try_files $uri $uri/ =404;
}
}
Location-specific authentication example:
server {
listen 80;
server_name example.com;
root /var/www/html;
location / {
# Public access
try_files $uri $uri/ =404;
}
location /admin {
auth_basic "Admin Panel";
auth_basic_user_file /etc/nginx/.htpasswd;
try_files $uri $uri/ =404;
}
location /api {
auth_basic "API Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://backend_api;
}
}
Advanced Configuration Options
For more complex scenarios, you can implement conditional authentication and multiple authentication realms:
server {
listen 80;
server_name example.com;
root /var/www/html;
# Variables for conditional authentication
set $auth_basic "off";
set $auth_basic_user_file "";
# Enable auth for specific IP ranges
if ($remote_addr !~ ^(192\.168\.1\.|10\.0\.0\.)) {
set $auth_basic "Restricted Area";
set $auth_basic_user_file /etc/nginx/.htpasswd;
}
location /secure {
auth_basic $auth_basic;
auth_basic_user_file $auth_basic_user_file;
try_files $uri $uri/ =404;
}
# Different user file for different sections
location /staff {
auth_basic "Staff Only";
auth_basic_user_file /etc/nginx/.htpasswd_staff;
try_files $uri $uri/ =404;
}
}
Real-World Examples and Use Cases
Protecting Development Environments
Password authentication is particularly useful for staging and development environments that need to be accessible over the internet but shouldn’t be publicly visible:
server {
listen 80;
server_name dev.example.com staging.example.com;
root /var/www/development;
auth_basic "Development Environment - Authorized Personnel Only";
auth_basic_user_file /etc/nginx/.htpasswd_dev;
location / {
try_files $uri $uri/ /index.php?$query_string;
}
location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/var/run/php/php8.3-fpm.sock;
}
}
API Endpoint Protection
Secure API endpoints while allowing specific applications to bypass authentication:
upstream api_backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
}
server {
listen 80;
server_name api.example.com;
location /public-api {
proxy_pass http://api_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location /private-api {
auth_basic "API Access Required";
auth_basic_user_file /etc/nginx/.htpasswd_api;
proxy_pass http://api_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header Authorization $http_authorization;
}
}
Performance Comparison and Benchmarks
Authentication Method | Response Time (ms) | Memory Usage (MB) | CPU Overhead | Scalability |
---|---|---|---|---|
No Authentication | 1.2 | 15 | Low | Excellent |
Basic Auth (htpasswd) | 1.8 | 16 | Low-Medium | Good |
Basic Auth (external) | 12.5 | 18 | Medium | Medium |
OAuth2/JWT | 8.3 | 22 | Medium-High | Excellent |
The performance impact of HTTP Basic Authentication is minimal for most applications. With a properly configured VPS or dedicated server, you can handle thousands of authenticated requests per second without significant performance degradation.
Security Best Practices and Considerations
SSL/TLS Implementation
Never use HTTP Basic Authentication without SSL/TLS encryption, as credentials are only Base64 encoded and easily intercepted:
server {
listen 80;
server_name example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl http2;
server_name example.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
auth_basic "Secure Area";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
try_files $uri $uri/ =404;
}
}
Password File Security
Implement proper security measures for password files:
# Create dedicated directory for auth files
sudo mkdir -p /etc/nginx/auth
sudo chown root:www-data /etc/nginx/auth
sudo chmod 750 /etc/nginx/auth
# Move password files to secure location
sudo mv /etc/nginx/.htpasswd /etc/nginx/auth/
sudo chmod 640 /etc/nginx/auth/.htpasswd
# Use strong encryption for passwords
sudo htpasswd -cB /etc/nginx/auth/.htpasswd username
Rate Limiting and Brute Force Protection
Implement rate limiting to prevent brute force attacks:
http {
limit_req_zone $binary_remote_addr zone=auth:10m rate=3r/m;
server {
listen 443 ssl;
server_name example.com;
location /protected {
limit_req zone=auth burst=5 nodelay;
auth_basic "Protected Area";
auth_basic_user_file /etc/nginx/auth/.htpasswd;
try_files $uri $uri/ =404;
}
}
}
Common Issues and Troubleshooting
Authentication Not Working
If authentication prompts don’t appear or fail consistently, check these common issues:
# Verify password file exists and has correct permissions
ls -la /etc/nginx/.htpasswd
sudo nginx -t
# Check Nginx error logs
sudo tail -f /var/log/nginx/error.log
# Test password file manually
sudo nginx -T | grep auth_basic
502 Bad Gateway Errors
When using authentication with reverse proxies, ensure headers are passed correctly:
location /app {
auth_basic "Application Access";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://backend;
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;
# Pass authentication info to backend
proxy_set_header X-Remote-User $remote_user;
}
Permission Denied Errors
Fix common permission issues:
# Check file ownership and permissions
sudo chown root:www-data /etc/nginx/.htpasswd
sudo chmod 640 /etc/nginx/.htpasswd
# Verify SELinux context (if applicable)
sudo setsebool -P httpd_read_user_content 1
sudo restorecon -R /etc/nginx/
Alternative Authentication Methods
Method | Complexity | Security Level | Use Case | Integration Effort |
---|---|---|---|---|
HTTP Basic Auth | Low | Medium | Simple protection, dev environments | Minimal |
OAuth2 | High | High | API access, third-party integration | Significant |
JWT Tokens | Medium | High | Stateless authentication, APIs | Medium |
Client Certificates | High | Very High | Machine-to-machine, high security | High |
IP Whitelisting | Low | Medium | Admin panels, internal tools | Minimal |
Advanced Integration Scenarios
External Authentication Backends
For larger deployments, integrate with external authentication systems using the auth_request
module:
server {
listen 80;
server_name example.com;
location = /auth {
internal;
proxy_pass http://auth-service;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
location /protected {
auth_request /auth;
# Set user info from auth service
auth_request_set $user $upstream_http_x_user;
proxy_set_header X-User $user;
try_files $uri $uri/ =404;
}
}
Dynamic Password Management
Create a script for automated password management:
#!/bin/bash
# manage_auth.sh - Script to manage Nginx authentication users
HTPASSWD_FILE="/etc/nginx/auth/.htpasswd"
NGINX_CONFIG="/etc/nginx/sites-available/default"
add_user() {
local username=$1
local password=$2
if [ -f "$HTPASSWD_FILE" ]; then
htpasswd -B "$HTPASSWD_FILE" "$username" <<< "$password"
else
htpasswd -cB "$HTPASSWD_FILE" "$username" <<< "$password"
fi
chmod 640 "$HTPASSWD_FILE"
chown root:www-data "$HTPASSWD_FILE"
nginx -t && systemctl reload nginx
}
remove_user() {
local username=$1
htpasswd -D "$HTPASSWD_FILE" "$username"
nginx -t && systemctl reload nginx
}
case "$1" in
add)
add_user "$2" "$3"
;;
remove)
remove_user "$2"
;;
*)
echo "Usage: $0 {add|remove} username [password]"
exit 1
;;
esac
HTTP Basic Authentication with Nginx provides a straightforward yet effective method for protecting web resources. While it may not offer the advanced features of modern authentication systems, its simplicity and low overhead make it ideal for development environments, internal tools, and scenarios requiring quick deployment. For comprehensive server solutions and optimal performance, consider the robust infrastructure options available through managed hosting services.
For more detailed information about Nginx authentication modules, refer to the official Nginx documentation and the Apache htpasswd utility documentation.

This article incorporates information and material from various online sources. We acknowledge and appreciate the work of all original authors, publishers, and websites. While every effort has been made to appropriately credit the source material, any unintentional oversight or omission does not constitute a copyright infringement. All trademarks, logos, and images mentioned are the property of their respective owners. If you believe that any content used in this article infringes upon your copyright, please contact us immediately for review and prompt action.
This article is intended for informational and educational purposes only and does not infringe on the rights of the copyright owners. If any copyrighted material has been used without proper credit or in violation of copyright laws, it is unintentional and we will rectify it promptly upon notification. Please note that the republishing, redistribution, or reproduction of part or all of the contents in any form is prohibited without express written permission from the author and website owner. For permissions or further inquiries, please contact us.