How to configure HTTP/Password Authentication for Nginx in linux servers

This guide walks you through setting up basic HTTP authentication on Nginx web servers running on Linux. HTTP authentication prompts visitors for a username and password before they can access protected areas of your website.

Prerequisites

Before starting, make sure you have:

  • A Linux server with Nginx installed and running
  • Root or sudo access to the server
  • Basic familiarity with the command line
  • The htpasswd utility (we'll install this in Step 1)

Understanding HTTP Basic Authentication

HTTP Basic Authentication is a straightforward method that prompts users for credentials before granting access to specific directories or files on your web server. When configured, visitors see a browser pop-up requesting a username and password before they can view the protected content.

This authentication method works well for:

  • Restricting access to development or staging environments
  • Protecting administrative dashboards
  • Adding a security layer to sensitive directories
  • Controlling access to internal tools and applications
  • Securing staging sites before public launch

Install the htpasswd Utility

The htpasswd utility helps you create and manage password files for HTTP authentication. It originates from Apache's HTTP server utilities, but it works perfectly with Nginx.

For Ubuntu/Debian-based systems:

$ sudo apt-get update
$ sudo apt-get install apache2-utils -y

## Enable Required Apache Modules

$ sudo a2enmod auth_basic
$ sudo a2enmod authn_file
$ sudo a2enmod authz_user
$ sudo apachectl configtest
$ sudo systemctl reload apache2

For CentOS/RHEL/Fedora systems:

$ sudo yum install httpd-tools -y(Use dnf instead of yum for EL7+)

## Review Required Apache Modules

$ sudo yum install httpd-tools
$ sudo httpd -M | grep auth
auth_basic_module (shared)
authn_file_module (shared)
authz_user_module (shared)

After installation, verify that htpasswd is available:

htpasswd --help

You should see the help information for the htpasswd command.

Create the Password File and Add Your First User

Now you'll need to create a password file that stores encrypted usernames and passwords. The standard location is /etc/nginx/.htpasswd, though you can choose any secure location outside your web root directory.

Create the password file and add your first user:

$ sudo htpasswd -c /etc/nginx/.htpasswd username

Replace username with your desired username.
You'll be prompted to enter and confirm a password:

New password:
Re-type new password:
Adding password for user alma_user

Important Note: The -c flag creates a new file. Only use this flag when creating the file for the first time.
Using -c on an existing file will overwrite all previous entries.

Understanding the Command Options

  • -c - Creates a new password file (use only once)
  • /etc/nginx/.htpasswd - The path where the password file will be stored.
  • username - The username for authentication.

Add Additional Users

To add more users to your existing password file, use the same command without the -c flag:

$ sudo htpasswd /etc/nginx/.htpasswd seconduser

Enter and confirm the password when prompted. You can add as many users as needed by repeating this command with different usernames.

Quick Reference for Adding Users

$ sudo htpasswd /etc/nginx/.htpasswd alma_user
$ sudo htpasswd /etc/nginx/.htpasswd admin
$ sudo htpasswd /etc/nginx/.htpasswd testuser

Verify Your Password File

Check that your password file was created correctly and contains your users:

$ sudo cat /etc/nginx/.htpasswd
alma_user:$apr1$IRxrtSSe$BjmYowEgu5M7LyoxUH18e.
admin:$apr1$pwRYKYsw$dO4IPGjikWKbzZdVIKT76.
testuser:$apr1$pxQgX0sX$h2B1o2WzGjUZ775XEdD9T.

Each line contains:

  • A username
  • A colon (:)
  • An encrypted password hash

The passwords are encrypted using APR1 (Apache's MD5 algorithm), making them secure even if someone gains access to the file.

Set Proper File Permissions

Secure your password file with appropriate permissions to prevent unauthorized access:

$ sudo chmod 640 /etc/nginx/.htpasswd

For Ubuntu/Debian systems:

$ sudo chown root:www-data /etc/nginx/.htpasswd

For CentOS/RHEL/Fedora systems:

$ sudo chown root:nginx /etc/nginx/.htpasswd

This configuration ensures:

  • Only the root can modify the file
  • The Nginx process can read it
  • Other users cannot access it

Verify the permissions:

$ ls -l /etc/nginx/.htpasswd

You should see something like:

-rw-r----- 1 root www-data 145 Jan 17 10:30 /etc/nginx/.htpasswd

Configure Nginx to Require Authentication

Now you'll modify your Nginx configuration to require authentication for specific locations or your entire site.

Option A: Protect a Specific Directory

Open your site's Nginx configuration file. This is typically located at:

  • Ubuntu/Debian: /etc/nginx/sites-available/default or /etc/nginx/sites-available/yoursite
  • CentOS/RHEL: /etc/nginx/conf.d/default.conf or /etc/nginx/nginx.conf
$ sudo vim /etc/nginx/sites-available/default

Add the authentication directives within a location block for the directory you want to protect

server {
    listen 80;
    server_name example.com;
    root /var/www/html;

    # Public area - no authentication required
    location / {
        try_files $uri $uri/ =404;
    }

    # Protected admin area
    location /admin {
        auth_basic "Admin Area - Restricted Access";
        auth_basic_user_file /etc/nginx/.htpasswd;
        
        try_files $uri $uri/ =404;
    }
}

Configuration Explanation:

  • auth_basic "Admin Area - Restricted Access" - Sets the message displayed in the authentication pop-up
  • auth_basic_user_file /etc/nginx/.htpasswd - Specifies the path to your password file

Option B: Protect Your Entire Website

To require authentication for your entire site, place the directives at the server level:

server {
    listen 80;
    server_name example.com;
    root /var/www/html;

    # Authentication required for entire site
    auth_basic "Private Site - Authentication Required";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        try_files $uri $uri/ =404;
    }
}

Option C: Protect Multiple Directories with Different Credentials

You can use different password files for different areas:

server {
    listen 80;
    server_name example.com;
    root /var/www/html;

    # Public area
    location / {
        try_files $uri $uri/ =404;
    }

    # Admin area with admin credentials
    location /admin {
        auth_basic "Admin Panel";
        auth_basic_user_file /etc/nginx/.htpasswd-admin;
    }

    # Staff portal with staff credentials
    location /staff {
        auth_basic "Staff Portal";
        auth_basic_user_file /etc/nginx/.htpasswd-staff;
    }

    # Developer area with developer credentials
    location /dev {
        auth_basic "Development Area";
        auth_basic_user_file /etc/nginx/.htpasswd-dev;
    }
}

Test Your Configuration

Before restarting Nginx, always test your configuration for syntax errors:

$ sudo nginx -t

If your configuration is correct, you'll see:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

If there are errors, the output will show you exactly what needs to be fixed, including the line number and file location.

Reload Nginx

Apply your changes by reloading the Nginx service:

$ sudo systemctl reload nginx

Alternatively, you can restart Nginx:

$ sudo systemctl restart nginx

Difference between reload and restart:

  • reload - Gracefully reloads configuration without dropping connections
  • restart - Stops and starts Nginx, which briefly interrupts service

Test Authentication in Your Browser

Open your web browser and navigate to the protected area (e.g., http://yourserver.com/admin).

You should see an authentication dialog box appear with the message you configured in the auth_basic directive.

Test the following scenarios:

  1. Enter valid credentials - You should gain access to the protected area
  2. Enter invalid credentials - Access should be denied with a 401 error
  3. Click "Cancel" - Access should be denied
  4. Try accessing unprotected areas - These should load without requiring authentication

You should see a pop-up like below: -
Once you enter the correct credentials, you will be allowed to access the content.

If you enter the wrong credentials or hit “Cancel”, you will see the following error page

Managing Users

Change a User's Password

To update an existing user's password:

$ sudo htpasswd /etc/nginx/.htpasswd username

Enter the new password when prompted. The old password will be replaced.

Remove a User

Delete a user from the password file:

$ sudo htpasswd -D /etc/nginx/.htpasswd username

Replace username with the username you want to remove.

View All Users

To see all usernames in your password file (without passwords):

$ sudo cut -d: -f1 /etc/nginx/.htpasswd

This displays only the usernames, one per line.

Verify a Password

Test if a password is correct for a specific user:

$ sudo htpasswd -v /etc/nginx/.htpasswd username

You'll be prompted to enter the password, and htpasswd will tell you if it matches.

After Making Changes

Always reload Nginx after modifying password files or adding/removing users:

$ sudo systemctl reload nginx

Security Best Practices

Always Use HTTPS

HTTP Basic Authentication transmits credentials encoded in Base64, which can be easily decoded. Never use basic authentication over plain HTTP in production environments.

Always configure SSL/TLS certificates and use HTTPS:

server {
    listen 443 ssl http2;
    server_name example.com;
    
    ssl_certificate /etc/ssl/certs/your-certificate.crt;
    ssl_certificate_key /etc/ssl/private/your-private-key.key;
    
    # Modern SSL configuration
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    auth_basic "Secure Area";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        root /var/www/html;
        try_files $uri $uri/ =404;
    }
}

# Redirect HTTP to HTTPS
server {
    listen 80;
    server_name example.com;
    return 301 https://$server_name$request_uri;
}

Use Strong Passwords

When creating users, ensure passwords are:

  • At least 12 characters long
  • Include uppercase and lowercase letters
  • Include numbers and special characters
  • Not based on dictionary words
  • Unique to this system

Restrict Password File Access

Ensure your password file permissions are correct:

# Set permissions
$ sudo chmod 640 /etc/nginx/.htpasswd

# Set ownership (Ubuntu/Debian)
$ sudo chown root:www-data /etc/nginx/.htpasswd

# Set ownership (CentOS/RHEL)
$ sudo chown root:nginx /etc/nginx/.htpasswd

Store Files Outside Web Root

Never store password files inside your web root directory (e.g., /var/www/html).

Always use locations like:

  • /etc/nginx/.htpasswd
  • /etc/apache2/.htpasswd
  • /usr/local/etc/nginx/.htpasswd

Regular Password Rotation

Implement a password rotation policy:

  • Change passwords every 90 days
  • Update passwords when team members leave
  • Rotate passwords after suspected security incidents

Combining with IP Restrictions

For enhanced security, combine authentication with IP address restrictions:

Require Both Authentication AND Valid IP

location /admin {
    satisfy all;
    
    # Allow specific IP addresses
    allow 192.168.1.0/24;
    allow 10.0.0.50;
    deny all;
    
    # Require authentication
    auth_basic "Admin Access";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

With satisfy all, users must have BOTH a valid IP address AND correct credentials.

Require Either Authentication OR Valid IP

location /admin {
    satisfy any;
    
    # Allow office IP addresses without authentication
    allow 192.168.1.0/24;
    deny all;
    
    # Or require authentication from anywhere else
    auth_basic "Admin Access";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

With satisfy any, users from allowed IPs can access without authentication, while others must authenticate.

Advanced Configuration Examples

Protect Specific File Types

Require authentication only for certain file types:

location ~ \.(zip|tar|gz|sql|bak)$ {
    auth_basic "Download Authentication Required";
    auth_basic_user_file /etc/nginx/.htpasswd;
}

Exclude Specific Files from Authentication

Protect a directory but allow public access to certain files:

location /admin {
    auth_basic "Admin Area";
    auth_basic_user_file /etc/nginx/.htpasswd;
    
    # Allow public access to login.html
    location ~ /admin/login\.html$ {
        auth_basic off;
    }
}

Different Authentication for API Endpoints

# Public API
location /api/v1 {
    try_files $uri $uri/ =404;
}

# Admin API requires authentication
location /api/admin {
    auth_basic "API Admin";
    auth_basic_user_file /etc/nginx/.htpasswd;
    
    proxy_pass http://backend;
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
}

Custom 401 Error Page

Create a custom unauthorized access page:

server {
    listen 80;
    server_name example.com;
    
    # Custom 401 error page
    error_page 401 /401.html;
    
    location = /401.html {
        root /var/www/errors;
        internal;
    }

    location /protected {
        auth_basic "Restricted";
        auth_basic_user_file /etc/nginx/.htpasswd;
    }
}

Create the custom error page at /var/www/errors/401.html:

<!DOCTYPE html>
<html>
<head>
    <title>Authentication Required</title>
</head>
<body>
    <h1>401 - Authentication Required</h1>
    <p>You must provide valid credentials to access this resource.</p>
</body>
</html>

Subdomain Authentication

Different subdomains with different authentication:

# Admin subdomain
server {
    listen 80;
    server_name admin.example.com;
    
    auth_basic "Admin Subdomain";
    auth_basic_user_file /etc/nginx/.htpasswd-admin;

    root /var/www/admin;
    location / {
        try_files $uri $uri/ =404;
    }
}

# Main site - no authentication
server {
    listen 80;
    server_name www.example.com;
    
    root /var/www/public;
    location / {
        try_files $uri $uri/ =404;
    }
}

Troubleshooting Common Issues

Authentication Prompt Not Appearing

Check configuration syntax:

$ sudo nginx -t

Verify directives are in the correct location:

Ensure auth_basic and auth_basic_user_file are within the proper server or location block.

Check Nginx error logs:

$ sudo tail -f /var/log/nginx/error.log

Verify Nginx is running:

$ sudo systemctl status nginx

403 Forbidden Error

Check file permissions:

$ ls -l /etc/nginx/.htpasswd

The file should be readable by the Nginx user (www-data or nginx).

Verify file ownership:

# Ubuntu/Debian
$ sudo chown root:www-data /etc/nginx/.htpasswd

# CentOS/RHEL
$ sudo chown root:nginx /etc/nginx/.htpasswd

Check Nginx user in configuration:

$ grep "^user" /etc/nginx/nginx.conf

Should show user www-data; (Ubuntu/Debian) or user nginx; (CentOS/RHEL).

Authentication Keeps Prompting (Loop)

Verify password file format:

$ sudo cat /etc/nginx/.htpasswd

Each line should be: username:encryptedpassword

Check for special characters in username:

Avoid spaces and special characters in usernames unless properly escaped.

Clear browser cache:

Clear your browser's cache, cookies, and authentication data for the site.

Try a different browser:

Test with another browser to rule out browser-specific issues.

Password File Not Found

Verify the file exists:

$ ls -l /etc/nginx/.htpasswd

Check the path in Nginx configuration:

$ sudo grep -r "auth_basic_user_file" /etc/nginx/

Ensure the path matches the actual file location.

Use absolute paths:

Always use absolute paths in the configuration:

auth_basic_user_file /etc/nginx/.htpasswd;  # Correct
auth_basic_user_file .htpasswd;              # Wrong

Changes Not Taking Effect

Reload Nginx after changes:

$ sudo systemctl reload nginx

Check for configuration errors:

$ sudo nginx -t

View recent logs:

$ sudo journalctl -u nginx -n 50 --no-pager

Verify the correct config file is being used:

$ sudo nginx -T | grep "auth_basic"

This shows all loaded configurations with your authentication directives.

500 Internal Server Error

Check Nginx error log:

$ sudo tail -f /var/log/nginx/error.log

Common causes:

Syntax errors in the configuration

  • Password file permissions issues
  • SELinux blocking access (on CentOS/RHEL)

For SELinux issues (CentOS/RHEL):

# Check SELinux status
$ getenforce

# Set correct context for password file
$ sudo chcon -t httpd_config_t /etc/nginx/.htpasswd

# Or temporarily disable SELinux for testing
$ sudo setenforce 0

Disabling Authentication

To remove authentication from a location, either delete the directives or explicitly disable it:

location /admin {
    auth_basic off;
    
    try_files $uri $uri/ =404;
}

Or simply remove/comment out the auth lines:

location /admin {
    # auth_basic "Admin Area";
    # auth_basic_user_file /etc/nginx/.htpasswd;
    
    try_files $uri $uri/ =404;
}

After making changes, reload Nginx:

$ sudo systemctl reload nginx

Using htpasswd Command Reference

Here's a quick reference for common htpasswd commands:

# Create new password file with first user
$ sudo htpasswd -c /etc/nginx/.htpasswd username

# Add user to existing file
$ sudo htpasswd /etc/nginx/.htpasswd username

# Delete a user
$ sudo htpasswd -D /etc/nginx/.htpasswd username

# Verify a password
$ sudo htpasswd -v /etc/nginx/.htpasswd username

# Batch mode (password on command line - less secure)
$ sudo htpasswd -b /etc/nginx/.htpasswd username password

# Display help
$ htpasswd --h

# Force MD5 encryption (default)
$ sudo htpasswd -m /etc/nginx/.htpasswd username

# Use bcrypt encryption (more secure, requires newer htpasswd)
$ sudo htpasswd -B /etc/nginx/.htpasswd username

# Use SHA encryption
$ sudo htpasswd -s /etc/nginx/.htpasswd username

Conclusion

You've now successfully configured HTTP password authentication on your Nginx server using the htpasswd utility. This provides a simple yet effective security layer for protecting sensitive areas of your website.

Key Takeaways:

  • Install apache2-utils (Ubuntu/Debian) or httpd-tools (CentOS/RHEL) for htpasswd
  • Use htpasswd -c only when creating a new password file
  • Always use HTTPS in production environments
  • Set proper file permissions (640) and ownership
  • Store password files outside your web root
  • Reload Nginx after configuration changes
  • Combine with IP restrictions for enhanced security

These solutions provide better user management, auditing capabilities, and security features suitable for enterprise applications.