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:
- Check Nginx error logs:
tail -f /var/log/nginx/error.log
- Verify headers with:
curl -v http://proxy.example.com/protected/
- 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