How to Configure Nginx Proxy with Basic Authentication for Backend Services


14 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