100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
DevOps

Mitigating DDoS with Nginx

Use Nginx's rate limiting, connection limiting, and buffering controls as a first line of defense against volumetric and application-layer DDoS attacks.

SecurityAdvanced10 min readJul 10, 2026
Analogies

Nginx's Role in DDoS Defense

Nginx cannot stop a true volumetric flood that saturates your network bandwidth - that requires upstream scrubbing at a CDN or ISP level - but it is highly effective against application-layer (Layer 7) attacks like HTTP floods, slow-loris style connection exhaustion, and login-endpoint brute forcing. The core tools are limit_req_zone for request-rate limiting, limit_conn_zone for concurrent-connection limiting, and tuned timeout directives that reject clients who hold connections open without sending complete requests.

🏏

Cricket analogy: It's like a ground's turnstiles that can efficiently manage a surge of fans arriving at once, but can't do anything if the actual stadium itself is too small for the demand - that's a capacity problem upstream, not a gate-management problem.

Rate Limiting Requests and Connections

limit_req_zone defines a shared memory zone keyed by a variable, typically $binary_remote_addr, that tracks request rate per client and rejects excess requests with 503 once the configured rate is exceeded; the burst parameter allows short spikes to queue rather than being dropped immediately, and nodelay processes burst requests without added latency. limit_conn_zone works similarly but caps simultaneous open connections per client, which is particularly effective against slow-loris attacks that try to exhaust the worker connection pool by holding many connections open.

🏏

Cricket analogy: It's like a bowler being restricted to a maximum number of overs per spell, with a short-burst allowance for a couple of extra deliveries in an emergency, but never letting one bowler monopolize the entire innings.

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

    server {
        location /login {
            limit_req zone=req_limit burst=20 nodelay;
            limit_conn conn_limit 5;
            limit_req_status 429;
            proxy_pass http://backend;
        }

        client_body_timeout 10s;
        client_header_timeout 10s;
        keepalive_timeout 15s;
        send_timeout 10s;
    }
}

Set limit_req_status 429 to return the semantically correct "Too Many Requests" code instead of the default 503, which helps monitoring tools and clients distinguish rate limiting from a genuine server outage.

Timeouts and Buffer Tuning Against Slowloris

Slowloris-style attacks send HTTP headers extremely slowly, one byte at a time, to keep connections open and exhaust the worker_connections pool without ever completing a request. Tightening client_header_timeout and client_body_timeout forces Nginx to drop connections that don't send data fast enough, while reasonable client_max_body_size and buffer size settings prevent an attacker from tying up memory with oversized or fragmented request bodies.

🏏

Cricket analogy: It's like a bowler enforcing a strict shot clock between deliveries - a batsman who takes forever fiddling with their gloves before every ball gets timed out and penalized rather than allowed to stall indefinitely.

Setting timeouts too aggressively can cut off legitimate users on slow mobile connections uploading large files - tune client_body_timeout and client_max_body_size to match realistic traffic patterns, and test with real-world slow connections before rolling out to production.

  • Nginx defends effectively against Layer 7 (application) DDoS attacks but cannot stop true volumetric floods that saturate network bandwidth - that requires upstream scrubbing.
  • limit_req_zone throttles request rate per client, typically keyed on $binary_remote_addr, with burst and nodelay controlling how spikes are handled.
  • limit_conn_zone caps concurrent connections per client, directly mitigating slow-loris style connection exhaustion attacks.
  • limit_req_status 429 returns the correct 'Too Many Requests' status instead of the default 503.
  • client_header_timeout and client_body_timeout drop connections that send data too slowly, closing off slowloris-style attacks.
  • Timeout and buffer settings must be tuned against real traffic patterns to avoid rejecting legitimate slow-connection users.
  • Rate limiting should be applied selectively to sensitive endpoints like /login rather than uniformly, to avoid degrading normal traffic elsewhere.

Practice what you learned

Was this page helpful?

Topics covered

#DevOps#NginxStudyNotes#MitigatingDDoSWithNginx#Mitigating#DDoS#Nginx#Role#StudyNotes#SkillVeris#ExamPrep