October DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix NowOctober DealsAmazon USDeal season is back - check today's better picksAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
VGSources
Blog

How to Block DDoS Attacks Using NGINX: A Practical, Safe Configuration Guide

A practical NGINX DDoS guide covering request-rate and connection limits, real-IP configuration, TCP stream protection, safe rollout, troubleshooting and when upstream scrubbing is required.
Length11 min Posted Quest giverVGSources Team
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

NGINX can absorb and reject many application-layer attacks by limiting requests, concurrent connections, and bandwidth before they reach your application. It cannot stop a volumetric attack that fills your server’s internet link; place a CDN or managed DDoS-scrubbing service in front of the origin for that problem. The reliable design is layered: restore the real client IP from trusted proxies, apply endpoint-specific request limits, cap simultaneous connections, observe in dry-run mode, and escalate upstream when the access link is saturated.

What NGINX can and cannot block

DDoS is not one traffic pattern. A login flood, an HTTP request storm, thousands of idle TCP handshakes, and a multi-gigabit UDP flood require different controls. NGINX operates at the origin, so it is effective only for traffic that reaches the machine and still leaves it enough CPU, memory, sockets, and network capacity to process the request.

As an Amazon Associate I earn from qualifying purchases.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

NGINX’s own documentation describes rate limiting as a way to prevent DDoS attacks and keep upstream servers from being overwhelmed. Its request limiter uses a leaky-bucket algorithm: tokens are consumed at a configured rate, a finite burst is queued or accepted immediately, and excess requests are rejected. Connection limiting is a separate control. It caps active connections, not requests per second.

If an attacker fills the physical or virtual access link before packets reach the host, NGINX never gets a chance to apply a rule. That is a provider-edge problem. Route traffic through an upstream CDN or managed scrubbing service, keep the origin reachable only from that service where your architecture permits, and ask the network provider to filter or divert the attack.

#1 Best Overall
SonicWall TZ500 Network Security/Firewall Appliance
  • SonicWALL TZ500 Network Security/Firewall Appliance
  • Intrusion Prevention, Malware Protection, Application Control, Content Filtering, Spyware Protection, URL Filtering, Denial of Service (DoS), Stateful Packet Filtering, Signature-based Intrusion Prevention, Distributed Denial of Service (DDoS) - 8 Port - 10/100/1000Base-T Gigabit Ethernet - DES, 3DES, MD5, SHA-1, AES (128-bit), AES (192-bit), AES (256-bit) - USB - 8 x RJ-45 - Manageable - Power Supply - Desktop
  • TZ500 Network Security FirewallExpand, control and protect your network.A fast connection to your business, school, remote office or retail site is only half the story; you also need to be able to securely manage it. The TZ500 and TZ600 give you enterprise-grade protection to stop cyberattacks as you expand and control your network.
  • TZ500 TotalSecure 1YRDell SonicWALL TZ500 Appliance with 1 year of Comprehensive Gateway Security Suite and 24x7 Support
  • SonicWALL 01-SSC-0445

Choose the control that matches the attack

Control What it limits Typical scope What happens at the limit Works if the origin link is saturated?
limit_req HTTP request processing rate, keyed by an expression such as $binary_remote_addr Usually an expensive endpoint, location, server, or selected API Requests are delayed, served immediately within a burst when nodelay is used, or rejected after the burst No
limit_conn Concurrent HTTP connections for a key Per client key and/or virtual server New connections above the configured count are rejected No
stream limit_conn Simultaneous TCP connections TCP services such as game, chat, or database proxies Additional connections are refused No
limit_rate Response bandwidth per connection Selected locations or responses Each connection is slowed to the configured rate No
CDN or managed scrubbing Traffic before it reaches your host Public origin and network edge Provider-specific filtering, absorption, or diversion Yes, when the provider has capacity and the origin is shielded

These controls complement one another. A request-rate rule will not prevent one client from opening many connections, and a connection cap will not stop one persistent connection from issuing expensive requests. Use separate limits for each resource you need to protect.

Prerequisites before changing the configuration

  • Access to the NGINX configuration and a safe reload procedure (nginx -t followed by a reload).
  • Metrics or logs showing normal request rates, concurrency, response latency, upstream queueing, and 4xx/5xx responses.
  • An inventory of endpoints by cost: login, password reset, search, upload, checkout, and ordinary static pages do not have the same safe rate.
  • A list of trusted load balancer or CDN address ranges if NGINX sits behind a proxy.
  • A rollback method, such as a version-controlled configuration and a tested previous release.

Do not select a number because it appears in an example. The official documentation uses values such as 1r/s, burst=5, and a connection limit of 1 to demonstrate syntax, not to promise capacity or protection.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Restore the real client IP safely

IP-based limits are only as good as the key. When a reverse proxy terminates TLS and forwards requests, NGINX normally sees the proxy’s address. Configure the real-IP module to trust only the documented address ranges of your own load balancer or CDN, then use the restored address for logging and limiting. Never trust an arbitrary client-supplied forwarding header: an attacker can forge it and create a new apparent IP for every request.

Shared networks create the opposite problem. NAT gateways, corporate forward proxies, schools, mobile carriers, and some VPNs can put many legitimate users behind one public address. A strict per-IP rule may throttle an entire household or office. NGINX documentation specifically warns about this false-positive risk. If authentication is available, consider a key that combines a trusted client identity with the address, or give authenticated and anonymous traffic separate zones. Do not expose a user-controlled identifier as a substitute for a verified identity.

A conservative HTTP configuration

Define shared-memory zones in the http context. The zone stores counters shared by workers; its size and rate must be tuned from observed traffic. The following pattern deliberately starts in dry-run mode and applies a stricter policy only to login requests.

http {
    # Illustrative values: measure your own traffic before enforcing.
    limit_req_zone  $binary_remote_addr zone=per_ip_req:10m rate=5r/s;
    limit_conn_zone $binary_remote_addr zone=per_ip_conn:10m;

    server {
        location = /login {
            limit_req zone=per_ip_req burst=10 nodelay;
            limit_conn per_ip_conn 10;
            limit_req_dry_run on;
            limit_req_status 429;
        }

        location / {
            limit_conn per_ip_conn 50;
        }
    }
}

$binary_remote_addr uses a compact binary representation of the client address and is the usual key for a per-address zone. A 10m zone is not a universal capacity recommendation; size it for the number of keys you expect and verify memory use.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

What each directive does

  • limit_req_zone: creates a shared zone and defines the average request rate for each key.
  • limit_req: attaches that zone to a location or server. burst=10 permits a temporary queue or burst of ten requests; with nodelay, requests within the burst are processed immediately instead of being spaced out.
  • limit_req_dry_run on: records what would have been delayed or rejected while allowing requests to continue. It is an observation mode, not protection.
  • limit_req_status 429: returns HTTP 429 Too Many Requests when enforcement rejects a request. Choose a deliberate status that your clients and monitoring understand.
  • limit_conn_zone: creates the shared counter for active connections.
  • limit_conn: applies the maximum for the selected key. The value is concurrent connections, not requests per second.

HTTP/2 and HTTP/3 can carry multiple concurrent requests over one connection, and NGINX counts concurrent requests according to the connection-limiting module’s rules. Do not assume a single browser connection means a single outstanding operation.

Roll out limits without locking out users

  1. Measure a normal baseline. For each important endpoint, record request rate and concurrency by authentication state, geography, client type, and known shared networks. Include busy periods rather than relying on a quiet hour.
  2. Start with dry run. Add limit_req_dry_run on; to the candidate location. Inspect NGINX logs and metrics for would-be delays and rejects. Compare those events with support reports and legitimate traffic patterns.
  3. Protect the most expensive endpoint first. Login, password-reset, search, and write operations usually deserve tighter limits than static assets. Avoid imposing a single low global rate on every URL.
  4. Enforce with an explicit response. Remove dry-run mode after reviewing observations and keep limit_req_status 429 (or another intentional status) so clients can back off rather than treating the response as an unexplained server failure.
  5. Add a connection ceiling. Apply a broader limit_conn rule as a final safeguard against clients that open many simultaneous sockets.
  6. Reload and verify. Run nginx -t, reload gracefully, then generate controlled test traffic. Confirm that normal requests pass, the intended endpoint receives 429 responses only after the configured behavior, and upstream latency improves rather than merely moving the queue.
  7. Adjust per endpoint. Watch latency, upstream queueing, 4xx/5xx rates, connection counts, and legitimate-user complaints. Change the affected location or client class instead of weakening every rule.

How to tune request rates and bursts

Choose a rate from measured legitimate behavior. If a login flow normally produces a short sequence of requests, the burst should cover that sequence while the sustained rate limits repeated attempts. A public API may need a key based on an authenticated account or API credential in addition to an address. Anonymous traffic generally needs a more conservative policy because the identity is weaker.

A delayed burst smooths traffic but increases latency. nodelay preserves responsiveness for requests inside the burst and then rejects once the queue is exhausted; it can therefore pass a short spike to the upstream application. Use it where a small burst is harmless and the upstream has headroom. Omit it when smoothing is more valuable than immediate response time.

Do not use NGINX’s limiter as an authentication policy. It cannot tell whether a request is a valid player, a bot using a stolen account, or several people behind one NAT address unless you supply a trustworthy key. Pair it with application-level account lockout, CAPTCHA or challenge controls where appropriate, and logging that lets you investigate abuse.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Limit connections and bandwidth separately

Connection limits defend socket, worker, and upstream resources. Set a per-client limit for suspicious or expensive locations and a broader server-level ceiling to preserve capacity for all users. A client can evade a request-rate rule by opening many connections, so connection and request controls should be evaluated together.

limit_rate reduces response bandwidth per connection. It can protect download-heavy endpoints from one client consuming disproportionate egress, but it does not cap the number of connections. Apply it only where a slower response is acceptable; a low value on game-state or latency-sensitive traffic can damage the user experience without stopping a connection flood.

Protect TCP services with the stream module

HTTP directives do not protect a raw TCP service. For a TCP proxy, define a stream-context connection zone and apply limit_conn using a source key. This limits simultaneous connections per source, which is useful for services such as custom game protocols or administrative proxies.

Rank #2
Sonicwall TZ 180 Totalsecure 25 Vpn Gateway Firewall (01-SSC-6085)
  • Nodes supported : 25
  • Stateful Throughput : 90+ Mbps
stream {
    limit_conn_zone $binary_remote_addr zone=tcp_per_ip:10m;

    server {
        listen 25565;
        proxy_pass game_backend:25565;
        limit_conn tcp_per_ip 20;
    }
}

The port and upstream in this example are illustrative. Confirm that your NGINX build includes the stream module and that the key reflects the real source address after any trusted proxy or load-balancer translation. Stream connection limits do not inspect application messages, authenticate users, or absorb a saturated network link.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

When NGINX cannot save the origin

Watch the point at which capacity fails. If CPU or upstream workers are exhausted while the link still has room, origin-side request and connection rules can help. If the interface, virtual NIC, transit provider, or firewall is already receiving more traffic than the link can carry, packets are dropped or delayed before NGINX sees them. No directive in the origin configuration can recover that lost capacity.

For a link-saturating event, put a CDN or managed DDoS-scrubbing service in front of the origin. Configure the origin firewall to accept traffic only from the provider’s published ranges where operationally possible, and keep an emergency path for administration. During an incident, contact the hosting or transit provider as soon as saturation is apparent; upstream filtering must happen before the congested link.

Observability and incident response

Log the information needed to tune

Include the restored client address, request path, status, request time, upstream response time, bytes sent, and a request identifier in access logs. Track limiter events separately from ordinary 4xx responses so a policy rejection is not mistaken for an application bug. Alert on sudden increases in 429 responses, active connections, upstream queue depth, and latency.

Use dry-run findings as evidence

Dry-run mode lets you estimate the blast radius before enforcement. Group would-be violations by endpoint and address class. A large cluster from one address may be abuse; a broad cluster from a corporate or mobile NAT may indicate that the key is too coarse. Change the key or scope before lowering the rate.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep a rollback path

Store configuration in version control, test syntax automatically, and document the last known-good reload command. If legitimate traffic is blocked, remove the location-specific rule or turn dry-run back on rather than deleting every safeguard. Preserve logs from the incident so the next tuning decision is based on observed behavior.

Common failure modes and fixes

Everyone appears to come from one address

Symptom: a whole office, region, or CDN appears to hit the same bucket. Cause: NGINX is limiting the proxy address or a NAT gateway. Fix: configure the real-IP module for trusted proxy ranges only, verify the resulting address in logs, and reconsider the per-address policy for shared networks.

Attackers bypass the limit by changing the forwarding header

Symptom: every request has a different apparent address despite coming from one source. Cause: an untrusted header is being used as the key. Fix: accept forwarding headers only from known proxy addresses and discard or ignore client-supplied values from other sources.

Legitimate bursts receive 429

Symptom: normal sign-in or API clients fail during a short spike. Cause: the sustained rate or burst is below measured behavior, or one NAT address represents many users. Fix: inspect dry-run data, increase the burst or rate only for the affected endpoint, and consider a stronger authenticated key.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

NGINX stays healthy while the site is unreachable

Symptom: worker metrics look normal but users cannot connect. Cause: the access link or provider edge is saturated. Fix: engage upstream filtering or scrubbing; origin configuration changes cannot process traffic that never arrives.

Connection limits have no visible effect

Symptom: a client still creates many operations. Cause: request rate and concurrent connections are different dimensions, or multiplexed HTTP traffic was misunderstood. Fix: inspect active connections and requests separately, then combine appropriately scoped limit_conn and limit_req rules.

Enterprise application-layer option

F5 NGINX App Protect DoS is a separate, licensed product rather than an open-source directive. Its policy documentation describes standard, conservative, and none mitigation modes, along with signatures, bad-actor detection, automation-tool detection, and TLS fingerprinting. Evaluate its licensing, deployment model, policy ownership, and false-positive handling separately from an open-source NGINX rollout. It still does not remove the need for upstream protection when the network path is overwhelmed.

A practical decision checklist

  • Is the failure at the application, host, firewall, interface, or provider edge?
  • Does NGINX have a verified real client address, or only a proxy address?
  • Which endpoint or TCP service is expensive enough to need a stricter policy?
  • Have normal rate and concurrency been measured for authenticated users and shared networks?
  • Have you observed the proposed rule with dry run before enforcing it?
  • Are request-rate and concurrent-connection limits both needed?
  • Will a 429 response be handled correctly by clients and monitoring?
  • Can the origin be firewalled to a trusted CDN or scrubbing provider?
  • Is there a tested rollback and an escalation contact at the network provider?

Key takeaways

Use NGINX as an origin-side control plane: restore trusted client identity, limit expensive HTTP request rates with the leaky-bucket module, cap concurrent HTTP or TCP connections, and use bandwidth limits only where slower responses are acceptable. Start in dry run, enforce endpoint by endpoint, and tune from logs rather than copied example values. When traffic exhausts the network link before reaching the server, move mitigation upstream to a CDN, scrubbing service, or transit provider.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Quick Recap

Bestseller No. 1
SonicWall TZ500 Network Security/Firewall Appliance
SonicWall TZ500 Network Security/Firewall Appliance
SonicWALL TZ500 Network Security/Firewall Appliance; SonicWALL 01-SSC-0445
$489.00
Bestseller No. 2
Sonicwall TZ 180 Totalsecure 25 Vpn Gateway Firewall (01-SSC-6085)
Sonicwall TZ 180 Totalsecure 25 Vpn Gateway Firewall (01-SSC-6085)
Nodes supported : 25; Stateful Throughput : 90+ Mbps
$290.16

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

Leave a Reply

Your email address will not be published. Required fields are marked *

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

More quests from Patch Notes

  1. How to Set Up a RedM (RDR2) Server in 2026: License Key, txAdmin and server.cfg, Step by StepBlog11min
  2. Best RedM (RDR2) Server Hosting in 2026: Comparing Four Hosts on Slots, Memory and PriceBlog10min
  3. How to Host a Mindustry Server in 2026: server-release.jar, Port 6567 and the Commands That MatterBlog7min
Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Crashes, No Sound, or Screen Glitches?Free driver scan

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.