DevOps & Infrastructure

Hardening Nginx in Production: Reverse Proxy, SSL/TLS & Rate Limiting Best Practices

Nginx powers over 30% of the world's busiest web servers. While its default configuration is fast, it leaves servers exposed to fingerprinting, Slowloris exhaustion, and clickjacking attacks. Here is how to configure a hardened, production-ready Nginx instance.

Saud Siraj• Published Sep 2026• 10 min read

Need a hardened Nginx config generated instantly?

Use our visual builder to generate production reverse proxy, SPA, and SSL configs in seconds.

Open Nginx Generator

1. Disable Server Information Leakage (Fingerprinting)

By default, when Nginx serves an error page (e.g., 404 or 502) or responds to an HTTP request, it sends a Server: nginx/1.24.0 (Ubuntu) header. Automated vulnerability scanners (like Shodan) harvest these version numbers to look up published CVE exploits.

Always disable version broadcasting inside the http block of your nginx.conf:

http {
    # Suppress Nginx version number in Server headers and error pages
    server_tokens off;
}

2. Enforce Modern SSL/TLS 1.3 Ciphers

Legacy protocols like SSLv3, TLS 1.0, and TLS 1.1 suffer from severe cryptographic flaws (e.g. POODLE, BEAST). Production web servers in 2026 must support only TLS 1.2 and TLS 1.3 with high-performance Perfect Forward Secrecy (PFS) ciphers:

ssl_protocols TLSv1.2 TLSv1.3;
ssl_prefer_server_ciphers on;
ssl_ciphers 'ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384';

# Session cache for high-throughput TLS handshakes
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;

# OCSP Stapling (speeds up TLS handshakes & avoids CA bottleneck)
ssl_stapling on;
ssl_stapling_verify on;
resolver 1.1.1.1 8.8.8.8 valid=300s;
resolver_timeout 5s;

3. Inject Mandatory Security Response Headers

Security headers instruct modern browsers to enforce strict sandboxing, prevent cross-site scripting (XSS), and prohibit clickjacking iframe embedding:

  • HSTS (Strict-Transport-Security): Forces browsers to interact only over HTTPS for 1 year, even if a user types http://.
  • X-Frame-Options: Prevents unauthorized sites from embedding your application inside hidden <iframe> elements (clickjacking defense).
  • X-Content-Type-Options: Blocks MIME-type sniffing, preventing executable scripts disguised as images from running.
# Add critical HTTP security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;

4. Prevent Slowloris & Buffer Overflow Exhaustion

In a Slowloris attack, an attacker opens hundreds of HTTP connections and sends tiny header fragments very slowly (e.g. 1 byte every 10 seconds), keeping worker connections occupied until the server runs out of file descriptors.

Tuning client timeouts and buffer sizes cuts off malicious slow connections while protecting legitimate traffic:

# Buffer sizes: prevent buffer overflow attacks
client_body_buffer_size 16K;
client_header_buffer_size 1k;
client_max_body_size 10M; # Adjust if your app accepts large file uploads
large_client_header_buffers 4 8k;

# Timeouts: drop stalled or slow connections
client_body_timeout 12s;
client_header_timeout 12s;
keepalive_timeout 65s;
send_timeout 10s;

5. Implementing Leaky-Bucket Rate Limiting

Nginx includes a built-in implementation of the leaky-bucket algorithm (limit_req) to prevent credential stuffing on login routes and API DDoS flooding:

# Define an in-memory zone: 10MB can track ~160,000 distinct IP addresses
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;

server {
    location /api/ {
        # Allow small bursts up to 20 requests without delaying legitimate users
        limit_req zone=api_limit burst=20 nodelay;
        
        proxy_pass http://backend_upstream;
        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;
    }
}

6. Conclusion & Deployment Checklist

Always run nginx -t to validate your configuration syntax before executing nginx -s reload in production. Testing your public endpoints with tools like SSL Labs (aiming for an A+ grade) ensures all cipher suites and HSTS policies are functioning as expected.