Nginx Reverse Proxy, Load Balancing & TLS Guide

Configure Nginx for reverse proxy, load balancing, and TLS termination. Enhance performance and security in your web applications with these expert tips.

Nginx Configuration: Reverse Proxy, Load Balancing, and TLS

Setting up Nginx as a reverse proxy with load balancing and TLS termination is crucial for optimizing the performance, scalability, and security of your web applications. This guide provides comprehensive instructions for configuring Nginx to handle these tasks effectively in a production environment, supplemented with advanced configurations and practical tips.

Key Takeaways:

  • Learn how to configure Nginx as a reverse proxy to direct client requests to backend servers
  • Understand load balancing techniques to distribute traffic efficiently across multiple servers
  • Implement TLS termination for secure communication between clients and servers
  • Recognize and avoid common configuration errors to optimize for production

Reverse Proxy Setup

A reverse proxy acts as an intermediary server that forwards client requests to backend servers. This setup enhances security by masking your backend infrastructure and simplifies client interactions with your application.

You landed the Cloud Storage of the future internet. Cloud Storage Services Sesame Disk by NiHao Cloud

Use it NOW and forever!

Support the growth of a Team File sharing system that works for people in China, USA, Europe, APAC and everywhere else.
server {
    listen 80;
    server_name myapp.example.com;

    location / {
        proxy_pass http://backend_servers;
        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;
    }
}

proxy_pass: Directs requests to backend servers.
proxy_set_header: Maintains original client headers for precise request handling.
X-Forwarded-Proto: Useful for applications that need to know the original protocol (HTTP/HTTPS).

This configuration forwards all requests to the upstream backend server group while preserving original client headers. This is crucial for applications that need to log client IPs or determine the original host and protocol.

Advanced Configuration

To enhance security and performance in production, consider additional configurations:

location / {
    proxy_pass http://backend_servers;
    
    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;

    proxy_read_timeout 90;
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_buffer_size 16k;
    proxy_buffers 4 32k;
    proxy_busy_buffers_size 64k;
    proxy_http_version 1.1;
    proxy_set_header Connection "";
}

proxy_read_timeout, proxy_connect_timeout, proxy_send_timeout: Define timeouts for various stages of the proxying process.
proxy_buffer_size, proxy_buffers, proxy_busy_buffers_size: Control buffer sizes to efficiently handle large responses.
proxy_http_version: Ensures compatibility with HTTP/1.1 for persistent connections.

Load Balancing Configuration

Nginx can distribute incoming requests across multiple backend servers using different load balancing strategies. This ensures efficient resource utilization and improves fault tolerance.

upstream backend_servers {
    server backend1.example.com;
    server backend2.example.com;
    server backend3.example.com;
}

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

    location / {
        proxy_pass http://backend_servers;
    }
}

upstream: Defines a server pool for load balancing.
server: Specifies each backend server.

The default load balancing method is round-robin, which evenly distributes requests. Nginx also supports other algorithms:

AlgorithmDescriptionUse Case
Round RobinDistributes requests evenlyGeneral use
Least ConnectionsRoutes to the server with the fewest connectionsBest for long-lived connections
IP HashRoutes requests from the same IP to the same serverSticky sessions

Advanced Load Balancing

For more granular control, you can use additional directives within the upstream block:

upstream backend_servers {
    server backend1.example.com weight=3;
    server backend2.example.com max_fails=3 fail_timeout=30s;
    server backend3.example.com backup;
}

weight: Assigns more requests to a server with a higher weight.
max_fails and fail_timeout: Define failure handling for servers.
backup: Designates a server as a backup to be used only if primary servers fail.

TLS Termination

Implementing TLS termination in Nginx involves decrypting incoming SSL/TLS traffic before forwarding it to backend servers. This offloads encryption tasks from application servers, improving performance.

server {
    listen 443 ssl;
    server_name myapp.example.com;

    ssl_certificate /etc/nginx/ssl/myapp.crt;
    ssl_certificate_key /etc/nginx/ssl/myapp.key;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers 'HIGH:!aNULL:!MD5';

    location / {
        proxy_pass http://backend_servers;
    }
}

listen 443 ssl: Listens for HTTPS connections.
ssl_certificate / ssl_certificate_key: Specifies certificate and key files.
ssl_protocols and ssl_ciphers: Choose secure protocols and ciphers.

Upstream Health Checks and Observability

In production environments, load balancing without visibility can silently route traffic to unhealthy or degraded backend servers. Adding health checks and observability signals ensures Nginx only forwards requests to healthy backends and gives operators insight into system behavior.

Passive Health Checks

Nginx Open Source supports passive health checks by monitoring failed requests and timeouts:

upstream backend_servers {
    server backend1.example.com max_fails=3 fail_timeout=30s;
    server backend2.example.com max_fails=3 fail_timeout=30s;
}

If a backend fails repeatedly within the configured time window, Nginx temporarily removes it from rotation.

Request Tracing and Logging

To troubleshoot latency and routing issues, enhance access logs with upstream metadata:

log_format upstream_log '$remote_addr - $host '
                       '$request '
                       'upstream=$upstream_addr '
                       'status=$status '
                       'upstream_status=$upstream_status '
                       'rt=$request_time '
                       'urt=$upstream_response_time';

access_log /var/log/nginx/access.log upstream_log;

This allows you to correlate slow responses or failures directly to specific backend servers.

Advanced TLS Settings

Enhance security with advanced settings:

ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/nginx/ssl/dhparam.pem;

ssl_session_cache and ssl_session_timeout: Improve performance with session caching.
ssl_prefer_server_ciphers: Enforce server cipher preference.
ssl_dhparam: Use a custom Diffie-Hellman group for stronger encryption.

Hardening Nginx for Production Traffic

Beyond basic reverse proxying and TLS, production-grade Nginx deployments should be hardened against abuse, traffic spikes, and misbehaving clients.

Connection and Request Limits

Limit concurrent connections and request rates to protect backend services:

limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;

server {
    location / {
        limit_conn conn_limit 20;
        limit_req zone=req_limit burst=20 nodelay;
        proxy_pass http://backend_servers;
    }
}

This prevents a single client from exhausting server resources.

Header and Buffer Hardening

Defensive defaults reduce attack surface and memory pressure:

client_max_body_size 10m;
large_client_header_buffers 4 16k;
ignore_invalid_headers on;

These settings protect against oversized payloads and malformed headers commonly used in abuse scenarios.

Common Pitfalls and Pro Tips

Misconfigured Headers: Ensure all necessary headers are set to avoid losing client information, which can affect logging and application behavior.
SSL Configuration: Regularly validate your SSL settings using tools like SSL Labs to ensure encryption strength and security compliance.
Backend Health Checks: Implement health checks for backend servers to prevent routing requests to non-functional nodes. This can be achieved with the Nginx ngx_http_healthcheck_module.

Security and Performance Best Practices

Rate Limiting: Use the limit_req module to prevent abuse by limiting the number of requests a client can make.
Caching: Implement caching with the proxy_cache directive to reduce load on backend servers.
Logging: Configure detailed logging to capture request and error data, aiding in debugging and monitoring.

For more on Nginx configuration, refer to the official Nginx documentation.

Conclusion

Properly configuring Nginx for reverse proxying, load balancing, and TLS termination can significantly improve your application’s performance, scalability, and security. By leveraging advanced features and following best practices, you can optimize Nginx to handle modern web application demands. For further exploration, consider diving into Nginx’s module ecosystem to tailor configurations to your specific needs. This allows you to maximize both performance and security, ensuring a robust infrastructure for your web applications.

Start Sharing and Storing Files for Free

You can also get your own Unlimited Cloud Storage on our pay as you go product.
Other cool features include: up to 100GB size for each file.
Speed all over the world. Reliability with 3 copies of every file you upload. Snapshot for point in time recovery.
Collaborate with web office and send files to colleagues everywhere; in China & APAC, USA, Europe...
Tear prices for costs saving and more much more...
Create a Free Account Products Pricing Page