Nginx Authentication
Introduction
Authentication is a critical aspect of web security that verifies the identity of users or systems attempting to access resources. Nginx, as a powerful web server and reverse proxy, offers various authentication mechanisms to protect your web applications and APIs from unauthorized access.
In this guide, we'll explore different authentication methods available in Nginx, from simple HTTP Basic Authentication to more complex setups involving LDAP, JWT tokens, and OAuth integration. By the end of this tutorial, you'll understand how to implement authentication solutions that match your security requirements.
Understanding Authentication in Nginx
Nginx handles authentication primarily through modules that can be configured in your server blocks. The authentication process typically follows these steps:
Authentication configurations in Nginx can be applied at different levels:
- Server-wide (in the
http
context) - Per virtual host (in the
server
context) - Per location (in the
location
context)
HTTP Basic Authentication
HTTP Basic Authentication is the simplest form of authentication in Nginx. It prompts users with a browser dialog to enter a username and password.
Setting Up HTTP Basic Authentication
- First, create a password file using the
htpasswd
utility (from Apache HTTP Server utilities):
# Install htpasswd if needed
sudo apt-get install apache2-utils
# Create a new password file with a user
sudo htpasswd -c /etc/nginx/.htpasswd user1
# Add additional users (without -c flag)
sudo htpasswd /etc/nginx/.htpasswd user2
- Configure Nginx to use this password file:
server {
listen 80;
server_name example.com;
location / {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/html;
index index.html;
}
}
- Test your configuration and reload Nginx:
sudo nginx -t
sudo systemctl reload nginx
When a user accesses your site, they'll see a login prompt:
![HTTP Basic Auth Prompt]
Pros and Cons of HTTP Basic Auth
Pros:
- Simple to set up
- Widely supported across browsers
- Low overhead
Cons:
- Credentials sent with every request (Base64 encoded, not encrypted)
- No built-in session management
- Limited user experience
Authentication Subrequests
Nginx can delegate authentication to another service or application through subrequests, which is useful when you need more complex authentication logic.
Example: Authentication with a Backend Service
server {
listen 80;
server_name example.com;
location / {
auth_request /auth;
auth_request_set $auth_status $upstream_status;
root /var/www/html;
index index.html;
}
location = /auth {
internal;
proxy_pass http://auth-service:8080/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}
In this example:
- The
auth_request
directive specifies a location that will handle authentication - Nginx makes a subrequest to this location before allowing access to the protected content
- The authentication service should return:
- 200 status for successful authentication
- 401 or 403 for authentication failure
LDAP Authentication
For organizations using LDAP directories (like Active Directory), Nginx can authenticate against these systems using the nginx-auth-ldap
module.
Installing the LDAP Module
# Install dependencies
sudo apt-get install libldap2-dev libssl-dev
# Clone the module repository
git clone https://github.com/kvspb/nginx-auth-ldap.git
# Recompile Nginx with the module
# (This process varies based on your installation method)
Configuring LDAP Authentication
# In the http context, configure the LDAP server
ldap_server ldap1 {
url ldap://ldap.example.com:389/dc=example,dc=com?uid?sub?(objectClass=person);
binddn "cn=serviceaccount,dc=example,dc=com";
binddn_passwd "service_account_password";
group_attribute member;
group_attribute_is_dn on;
require valid_user;
}
server {
listen 80;
server_name example.com;
location / {
auth_ldap "LDAP Authentication";
auth_ldap_servers ldap1;
root /var/www/html;
index index.html;
}
}
JWT Authentication
JSON Web Tokens (JWT) provide a modern approach to authentication, especially for APIs and microservices. The nginx-jwt-module
can validate JWTs.
Setting Up JWT Authentication
- Install the module:
# Clone the repository
git clone https://github.com/TeslaGov/ngx-http-auth-jwt-module.git
# Compile Nginx with the module
# (Instructions vary based on your installation)
- Configure Nginx to validate JWTs:
server {
listen 80;
server_name api.example.com;
location /api/ {
auth_jwt "API Authentication";
auth_jwt_key_file /etc/nginx/jwt_secret.key;
proxy_pass http://backend-service:8080/;
}
}
- Example JWT validation with specific claims:
location /admin/ {
auth_jwt "Admin API";
auth_jwt_key_file /etc/nginx/jwt_secret.key;
auth_jwt_claim_set $jwt_role role;
if ($jwt_role != "admin") {
return 403;
}
proxy_pass http://admin-service:8080/;
}
OAuth2 Integration
For a comprehensive authentication solution, you can integrate Nginx with OAuth2 providers using the oauth2-nginx-module
or through subrequests to an OAuth-aware service.
Example Using Vouch Proxy
Vouch Proxy is an external service that handles OAuth authentication and can be integrated with Nginx:
-
Set up Vouch Proxy with your OAuth provider (Google, GitHub, etc.)
-
Configure Nginx:
server {
listen 443 ssl;
server_name secure.example.com;
ssl_certificate /etc/nginx/ssl/cert.pem;
ssl_certificate_key /etc/nginx/ssl/key.pem;
# Vouch Proxy authentication endpoint
location /vouch/ {
proxy_pass http://vouch-proxy:9090/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
# Protected content
location / {
auth_request /vouch/validate;
# Forward user information
auth_request_set $auth_user $upstream_http_x_vouch_user;
proxy_set_header X-User $auth_user;
# If authentication fails
error_page 401 = /vouch/login?url=$scheme://$host$request_uri;
root /var/www/html;
index index.html;
}
}
Multiple Authentication Methods
Nginx allows combining different authentication methods for enhanced security or flexibility:
server {
listen 80;
server_name example.com;
# Public area - no authentication
location /public/ {
root /var/www/html;
}
# Basic auth for general restricted area
location /restricted/ {
auth_basic "Restricted Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/html/restricted;
}
# JWT auth for API
location /api/ {
auth_jwt "API Authentication";
auth_jwt_key_file /etc/nginx/jwt_secret.key;
proxy_pass http://api-service:8080/;
}
# LDAP auth for admin area
location /admin/ {
auth_ldap "Admin Authentication";
auth_ldap_servers ldap1;
root /var/www/html/admin;
}
}
Practical Example: Protecting a Development Environment
Let's create a practical example of protecting a development environment with HTTP Basic Authentication while allowing certain IP addresses without authentication:
server {
listen 80;
server_name dev.example.com;
# Allow office IP range without authentication
satisfy any;
allow 192.168.1.0/24; # Office IP range
deny all;
auth_basic "Development Environment";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://dev-app:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
This configuration:
- Allows access from the office IP range without requiring credentials
- Requires HTTP Basic Authentication for all other IP addresses
- Proxies the requests to a development application server
Troubleshooting Authentication Issues
Common authentication issues and their solutions:
1. Incorrect File Permissions
If authentication isn't working, check permissions on your password file:
# Password file should be readable by nginx user
sudo chown www-data:www-data /etc/nginx/.htpasswd
sudo chmod 600 /etc/nginx/.htpasswd
2. Debugging Authentication
Enable debug logging to trace authentication issues:
error_log /var/log/nginx/error.log debug;
3. Authentication Bypassing Unexpectedly
If authentication is being bypassed unexpectedly, check for:
- Conflicting
satisfy
directives - Location blocks that might override the authentication settings
- Missing
auth_*
directives in the specific context you expect
Security Best Practices
When implementing authentication in Nginx:
- Always use HTTPS for authentication - HTTP Basic Auth sends credentials as Base64 encoded text
- Restrict access to authentication files with proper permissions
- Use strong passwords and consider password rotation policies
- Implement rate limiting to prevent brute force attacks:
# In http context
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/s;
# In server or location context where authentication happens
limit_req zone=login burst=5 nodelay;
- Consider multi-factor authentication for highly sensitive systems
Summary
Nginx provides flexible and powerful authentication mechanisms to secure your web applications and services. In this guide, we've covered:
- HTTP Basic Authentication for simple password protection
- Authentication subrequests for delegating authentication to external services
- LDAP integration for enterprise directory authentication
- JWT validation for modern API security
- OAuth2 integration for comprehensive authentication flows
- Combining multiple authentication methods
- Practical examples and troubleshooting tips
By understanding these authentication options, you can implement appropriate security measures for your specific needs, balancing security requirements with user experience.
Additional Resources
For further learning:
- Nginx Official Documentation on Authentication
- Nginx HTTP Auth Request Module
- LDAP Authentication Module
- JWT Authentication Module
- Vouch Proxy for OAuth
Exercises
- Set up HTTP Basic Authentication for a simple static website and test access.
- Configure authentication for specific endpoints (e.g.,
/admin/
) while keeping others public. - Implement IP-based access control combined with password authentication.
- Set up a test environment with JWT authentication for an API.
- Create a configuration that uses different authentication methods for different parts of your website.
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)