Nginx Configuration Cheatsheet: Reverse Proxy and Load Balancing
This comprehensive guide provides essential nginx configurations for setting up reverse proxies, SSL/TLS termination, and load balancing. Whether you’re deploying a single service or managing multiple backend servers, these configurations will help you create secure, efficient nginx setups.
Overview
Nginx is a powerful web server and reverse proxy that excels at handling high-traffic applications. This cheatsheet covers the most common nginx configurations for:
- Reverse Proxy Setup: Forwarding requests to backend services
- SSL/TLS Termination: Handling HTTPS connections securely
- Load Balancing: Distributing traffic across multiple backend servers
- Security Headers: Implementing modern web security practices
- WebSocket Support: Enabling real-time communication protocols
Basic Reverse Proxy Configuration
Single Backend Server
The most common nginx use case is proxying requests to a single backend service running on a different port. This configuration includes SSL/TLS termination - for certificate creation and management, see our OpenSSL certificate management guide:
server {
# Redirect all HTTP requests to HTTPS
listen 80;
server_name metrics.lab.net;
return 301 https://$host$request_uri;
}
server {
# Listen on port 443 for HTTPS connections
listen 443 ssl;
server_name metrics.lab.net;
# SSL Certificate and Key
ssl_certificate /etc/grafana/certs/cert.crt;
ssl_certificate_key /etc/grafana/certs/cert.key;
# SSL settings (you can customize these as needed)
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers HIGH:!aNULL:!MD5;
# Reverse proxy configuration
location / {
proxy_pass http://localhost:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
# Additional security headers (optional, but recommended)
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header X-XSS-Protection "1; mode=block";
}
Key Configuration Elements
HTTP to HTTPS Redirect:
- The first server block catches all HTTP traffic and redirects it to HTTPS
- This ensures all connections are encrypted
SSL/TLS Configuration:
- Supports modern TLS versions (1.2 and 1.3)
- Uses secure cipher suites
- Prefers server cipher selection for better security
- For creating SSL certificates, use OpenSSL commands
Proxy Headers:
Host
: Preserves the original host headerX-Real-IP
: Provides the client’s real IP addressX-Forwarded-For
: Maintains the forwarding chainX-Forwarded-Proto
: Indicates the original protocol (HTTP/HTTPS)
Load Balancing Configuration
Multiple Backend Servers
For high-availability applications, nginx can distribute requests across multiple backend servers:
upstream websocket_backend {
# Define the 8 backend servers (local ports) with round-robin load balancing
server 127.0.0.1:3333;
server 127.0.0.1:3334;
server 127.0.0.1:3335;
server 127.0.0.1:3336;
server 127.0.0.1:3337;
server 127.0.0.1:3338;
server 127.0.0.1:3339;
server 127.0.0.1:3340;
# Optionally, you can adjust the weight of each server if needed.
# server 127.0.0.1:3333 weight=3; # Example of weighting
}
server {
listen 22000 ssl;
server_name _; # Listen on any IP
# SSL Configuration
ssl_certificate /opt/metric-collector/cert.crt;
ssl_certificate_key /opt/metric-collector/cert.key;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;
# WebSocket-specific settings
location / {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Optionally, set timeouts to handle WebSocket connections properly
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 3600s;
}
}
Load Balancing Methods
Nginx supports several load balancing algorithms:
Round Robin (Default):
upstream backend {
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
Weighted Round Robin:
upstream backend {
server 127.0.0.1:3000 weight=3;
server 127.0.0.1:3001 weight=2;
server 127.0.0.1:3002 weight=1;
}
IP Hash (for session persistence):
upstream backend {
ip_hash;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
Least Connections:
upstream backend {
least_conn;
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
WebSocket Configuration
WebSocket connections require special handling to maintain the persistent connection:
Essential WebSocket Headers
location /ws {
proxy_pass http://websocket_backend;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Extended timeouts for WebSocket connections
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_connect_timeout 3600s;
}
WebSocket with Load Balancing
For WebSocket applications that need session persistence:
upstream websocket_backend {
ip_hash; # Ensures same client connects to same backend
server 127.0.0.1:3000;
server 127.0.0.1:3001;
server 127.0.0.1:3002;
}
SSL/TLS Best Practices
Modern SSL Configuration
server {
listen 443 ssl http2;
server_name example.com;
# Certificate configuration
ssl_certificate /path/to/cert.crt;
ssl_certificate_key /path/to/cert.key;
# Modern SSL settings
ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers off;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
# OCSP stapling
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /path/to/chain.crt;
# Session settings
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
}
Security Headers
Implement comprehensive security headers:
# Security headers
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header X-Content-Type-Options nosniff always;
add_header X-Frame-Options DENY always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline';" always;
Performance Optimization
Caching Configuration
# Static file caching
location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# API response caching
location /api/ {
proxy_pass http://backend;
proxy_cache api_cache;
proxy_cache_valid 200 302 5m;
proxy_cache_valid 404 1m;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
}
Connection Optimization
# Connection settings
keepalive_timeout 65;
keepalive_requests 100;
# Gzip compression
gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
Health Checks and Monitoring
Backend Health Monitoring
upstream backend {
server 127.0.0.1:3000 max_fails=3 fail_timeout=30s;
server 127.0.0.1:3001 max_fails=3 fail_timeout=30s backup;
}
Status Page Configuration
location /nginx_status {
stub_status on;
access_log off;
allow 127.0.0.1;
allow ::1;
deny all;
}
Common Troubleshooting
Connection Issues
502 Bad Gateway:
- Check if backend service is running
- Verify firewall rules
- Ensure correct upstream configuration
504 Gateway Timeout:
- Increase proxy timeout values
- Check backend service performance
- Verify network connectivity
SSL Issues
SSL Certificate Problems:
- Verify certificate paths and permissions
- Check certificate expiration dates using OpenSSL verification commands
- Ensure proper certificate chain
Mixed Content Warnings:
- Ensure all resources use HTTPS
- Check
X-Forwarded-Proto
header configuration - Verify application URL generation
Network Connectivity Issues
Firewall Configuration:
- Verify firewall rules allow HTTP (80) and HTTPS (443) traffic
- Use UFW firewall commands to check and configure access
- Ensure backend services are accessible through firewall rules
Testing Configuration
Syntax Validation
# Test nginx configuration
nginx -t
# Reload configuration
nginx -s reload
# Check nginx status
systemctl status nginx
Connection Testing
# Test HTTP to HTTPS redirect
curl -I http://example.com
# Test SSL configuration
curl -I https://example.com
# Test SSL certificate details (requires OpenSSL)
openssl s_client -connect example.com:443 -servername example.com
# Test WebSocket connection
curl -i -N -H "Connection: Upgrade" -H "Upgrade: websocket" -H "Sec-WebSocket-Version: 13" -H "Sec-WebSocket-Key: test" https://example.com/ws
For comprehensive SSL testing and certificate verification, see OpenSSL testing commands.
Questions Answered in This Document
Q: How do I configure nginx as a reverse proxy with SSL termination? A: Use a server block listening on port 443 with SSL certificates, proxy_pass to your backend service, and include proper proxy headers like Host, X-Real-IP, and X-Forwarded-For.
Q: What’s the difference between round-robin and IP hash load balancing? A: Round-robin distributes requests evenly across all backend servers, while IP hash ensures requests from the same client always go to the same backend server, enabling session persistence.
Q: How do I configure nginx for WebSocket connections? A: Set proxy_http_version to 1.1, include Upgrade and Connection headers, and configure extended timeouts (proxy_read_timeout, proxy_send_timeout, proxy_connect_timeout).
Q: What security headers should I include in my nginx configuration? A: Include Strict-Transport-Security, X-Content-Type-Options, X-Frame-Options, X-XSS-Protection, Referrer-Policy, and Content-Security-Policy headers for comprehensive security.
Q: How do I handle SSL certificate configuration in nginx? A: Specify ssl_certificate and ssl_certificate_key paths, use modern protocols (TLSv1.2 and TLSv1.3), configure secure ciphers, and optionally enable OCSP stapling. Use OpenSSL commands to create and manage certificates.
Q: What’s the proper way to redirect HTTP to HTTPS in nginx?
A: Create a server block listening on port 80 with a return 301 redirect to the HTTPS version using return 301 https://$host$request_uri;
.
Q: How do I configure health checks for backend servers? A: Use max_fails and fail_timeout parameters in the upstream configuration to define failure thresholds and recovery time.
Q: What are the essential proxy headers for reverse proxy configuration? A: Include Host (preserves original host), X-Real-IP (client’s real IP), X-Forwarded-For (forwarding chain), and X-Forwarded-Proto (original protocol).
Q: How do I optimize nginx performance for high-traffic applications? A: Enable gzip compression, configure appropriate keepalive settings, implement caching strategies, and use connection pooling with upstream servers.
Q: What’s the correct way to test nginx configuration changes?
A: Use nginx -t
to validate syntax, nginx -s reload
to apply changes, and test with curl commands to verify functionality.
Q: How should I secure my nginx deployment at the network level? A: Combine nginx configurations with proper firewall rules to allow only necessary ports (80, 443, SSH) and restrict access to backend services by IP ranges.