How to Configure Nginx Proxy with Basic Authentication for Backend Services


2 views

When setting up an Nginx reverse proxy, you might need to authenticate with backend services that require HTTP Basic Auth. The standard proxy_pass directive doesn't natively support passing credentials in the URL format like http://user:pass@backend.

Here's the complete configuration approach that solves this problem:

server {
    listen 80;
    server_name proxy.example.com;

    location /protected/ {
        proxy_pass http://192.168.0.5/;
        proxy_set_header Authorization "Basic [base64-encoded-credentials]";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

You'll need to Base64 encode your credentials in the format username:password. Here's how to generate it:

# Using OpenSSL
echo -n "username:password" | openssl base64

# Using Python
python3 -c "import base64; print(base64.b64encode(b'username:password').decode('ascii'))"

For the specific case mentioned in the question with UUID parameter:

server {
    listen 80;
    server_name files.example.com;

    location /export {
        proxy_pass http://192.168.0.5/export;
        proxy_set_header Authorization "Basic dXNlcm5hbWU6cGFzc3dvcmQ=";
        
        # Preserve original query parameters
        proxy_pass_request_headers on;
        proxy_pass_request_body on;
        
        # Handle redirects properly
        proxy_redirect off;
        proxy_buffering off;
    }
}

For production environments, consider these additional settings:

location /secure-downloads/ {
    proxy_pass http://internal-server/export;
    proxy_set_header Authorization "Basic [your-credentials]";
    
    # Security enhancements
    proxy_hide_header X-Powered-By;
    proxy_hide_header Server;
    
    # Performance tuning
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    
    # SSL verification if needed
    proxy_ssl_verify on;
    proxy_ssl_trusted_certificate /path/to/ca.crt;
}

After implementing the solution, verify it works:

curl -I http://proxy.example.com/export?uuid=1234567890

Check the response headers to ensure you're getting the expected content from the backend server.

For dynamic credential handling, you can use Nginx variables with lua or JavaScript modules:

location /dynamic-auth/ {
    set $auth "Basic dXNlcm5hbWU6cGFzc3dvcmQ=";
    proxy_set_header Authorization $auth;
    proxy_pass http://backend/;
}

When setting up an Nginx reverse proxy to a backend service requiring HTTP Basic authentication, we need to properly handle credentials in the proxy_pass directive while maintaining security. The standard approach of including credentials directly in the URL (like http://user:pass@backend) presents several technical challenges.

Instead of embedding credentials in the proxy URL (which might appear in logs), we should use Nginx's proxy_set_header directive:

location /export/ {
    proxy_pass http://192.168.0.5/;
    proxy_set_header Authorization "Basic $(echo -n 'username:password' | base64)";
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

Here's a full server block implementation:

server {
    listen 80;
    server_name proxy.example.com;

    location /protected/ {
        # Base64 encoded credentials (generate with: echo -n 'user:pass' | base64)
        set $auth "dXNlcm5hbWU6cGFzc3dvcmQ=";
        
        proxy_pass http://192.168.0.5/export/;
        proxy_set_header Authorization "Basic $auth";
        proxy_set_header X-Original-URI $request_uri;
        
        # Cache settings
        proxy_cache my_cache;
        proxy_cache_valid 200 302 10m;
        
        # Timeout configurations
        proxy_connect_timeout 5s;
        proxy_read_timeout 30s;
    }
    
    # Additional security headers
    add_header X-Content-Type-Options nosniff;
    add_header X-Frame-Options DENY;
}

For more complex scenarios, consider using Nginx's auth_request module:

location = /auth {
    internal;
    proxy_pass http://auth-server/validate;
    proxy_pass_request_body off;
    proxy_set_header Content-Length "";
}

location /secure/ {
    auth_request /auth;
    proxy_pass http://backend-server/;
}

When troubleshooting:

  1. Check Nginx error logs: tail -f /var/log/nginx/error.log
  2. Verify headers with: curl -v http://proxy.example.com/protected/
  3. Test credentials independently: curl -u username:password http://192.168.0.5/export/
  • Never store credentials in plaintext config files
  • Consider using environment variables for credentials
  • Implement proper SSL/TLS for all connections
  • Regularly rotate credentials
  • Restrict access to the proxy server