1.  [Strona główna](/) ›
2.  [Baza wiedzy](/baza-wiedzy/) ›
3.  Nginx rate limiting: limit\_req\_zone i ochrona przed DDoS

# Nginx rate limiting: limit\_req\_zone, burst, nodelay i ochrona przed DDoS

Opublikowano: 9 kwietnia 2026 · Kategoria: VPS / Bezpieczeństwo

⚡ W skrócie · 9 min czytania

-   Jak skonfigurować rate limiting w Nginx.
-   limit\_req\_zone, limit\_conn\_zone, parametr burst i nodelay.
-   whitelist IP, kody 429, ochrona przed brute force i DDoS.
-   limit\_req\_zone — ograniczenie tempa żądań.
-   Stosowanie limit\_req w lokalizacjach.

Rate limiting w Nginx to pierwsza linia obrony przed atakami brute force, web scraperem bez respektu dla robots.txt i prostymi atakami DDoS na poziomie HTTP. Moduł `ngx_http_limit_req_module` implementuje algorytm leaky bucket — ogranicza tempo żądań per IP, per URL lub per dowolny klucz. Poprawna konfiguracja chroni serwer bez blokowania legalnych użytkowników.

## limit\_req\_zone — ograniczenie tempa żądań

Dyrektywa `limit_req_zone` definiuje strefę (shared memory zone) przechowującą stan klientów. Musi być w bloku `http`, nie w `server` ani `location`.

```
# /etc/nginx/nginx.conf — blok http { ... }

http {
    # Strefa dla ogólnego rate limiting — 10 MB pamięci (ok. 160 000 IP), limit 10 req/s
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;

    # Strefa dla endpointów logowania — bardziej restrykcyjny limit
    limit_req_zone $binary_remote_addr zone=login:5m rate=5r/m;

    # Strefa dla API — ograniczenie per IP
    limit_req_zone $binary_remote_addr zone=api:10m rate=30r/m;

    # Strefa z kluczem per user agent + IP (bardziej szczegółowa)
    limit_req_zone "$binary_remote_addr$http_user_agent" zone=strict:10m rate=5r/s;

    # Zmien domyslny kod bledu na 429 (Too Many Requests)
    limit_req_status 429;
}
```

Format stawki: `r/s` (requestów na sekundę) lub `r/m` (requestów na minutę). Klucz strefy to zazwyczaj `$binary_remote_addr` (4 bajty dla IPv4, 16 dla IPv6) — bardziej kompaktowy niż `$remote_addr` (string).

## Stosowanie limit\_req w lokalizacjach

```
# /etc/nginx/sites-available/twoja-strona

server {
    listen 443 ssl http2;
    server_name twojadomena.pl;

    # Ogólny rate limiting dla całej strony
    limit_req zone=general burst=20 nodelay;

    # Strona logowania — surowe limity
    location /wp-login.php {
        limit_req zone=login burst=3 nodelay;
        limit_req_status 429;

        # Zwróć error page z Retry-After
        error_page 429 /rate-limit.html;

        include fastcgi_params;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    }

    # Endpoint API — limit + nagłówki informacyjne
    location /api/ {
        limit_req zone=api burst=10 nodelay;

        add_header X-RateLimit-Limit "30" always;
        add_header X-RateLimit-Window "60s" always;

        proxy_pass http://localhost:3000;
    }

    # Strona statyczna — brak rate limiting (CDN to obsługuje)
    location ~* \.(css|js|png|jpg|gif|ico|woff2)$ {
        expires 30d;
        add_header Cache-Control "public, immutable";
    }

    # Strona błędu 429
    location = /rate-limit.html {
        internal;
        add_header Retry-After 60 always;
        return 429 "Za dużo żądań. Poczekaj chwilę i spróbuj ponownie.";
    }
}
```

## limit\_conn\_zone — ograniczenie jednoczesnych połączeń

`limit_conn_zone` ogranicza liczbę równoczesnych połączeń TCP od jednego IP. Przydatne do blokowania download managerów pobierających z wielu wątków i botów otwierających wiele połączeń jednocześnie.

```
# W bloku http:
http {
    # Strefa połączeń — 10 MB, klucz per IP
    limit_conn_zone $binary_remote_addr zone=conn_per_ip:10m;

    # Strefa dla serwera (wszystkie połączenia łącznie)
    limit_conn_zone $server_name zone=conn_per_server:10m;

    limit_conn_status 429;
}

# W bloku server lub location:
server {
    # Maksymalnie 10 połączeń per IP
    limit_conn conn_per_ip 10;

    # Maksymalnie 1000 połączeń do serwera łącznie
    limit_conn conn_per_server 1000;

    # Dla plików do pobrania — mocniejsze ograniczenie
    location /download/ {
        limit_conn conn_per_ip 2;
        limit_rate 500k;     # Dodatkowo: limit prędkości 500 KB/s per połączenie
    }
}
```

## Whitelist — wyłączenie limitów dla zaufanych IP

Najczystszy sposób na whitelist to blok `geo`, który mapuje adresy IP na zmienną. Puste klucze w strefie limit\_req są ignorowane przez Nginx.

```
# W bloku http — PRZED limit_req_zone:
http {
    # Mapuj IP na klucz — pusty string = brak limitu
    geo $limit_key {
        default             $binary_remote_addr;  # normalni uzytkownicy: limit per IP
        192.168.1.0/24      "";                   # siec wewnętrzna: brak limitu
        203.0.113.10        "";                   # IP biura: brak limitu
        127.0.0.1           "";                   # localhost: brak limitu
    }

    # Uzyj $limit_key jako klucza strefy
    limit_req_zone $limit_key zone=general:10m rate=10r/s;
    limit_conn_zone $limit_key zone=conn_per_ip:10m;
}
```

## Logowanie zdarzeń rate limiting

Domyślnie Nginx loguje przekroczenia limitu na poziomie ERROR, co zaśmieca logi. Ogranicz poziom logowania do WARN, a osobny log pozwoli monitorować ataki.

```
# W bloku http:
http {
    limit_req_zone $binary_remote_addr zone=general:10m rate=10r/s;

    # Zmien poziom logowania (domyslnie: error)
    # Opcje: info, notice, warn, error (im wyzsza = mniej logów)
    limit_req_log_level warn;
    limit_conn_log_level warn;
}

# Osobny format logu z IP i limitowanym URL
log_format rate_limit '$remote_addr - [$time_local] '
    '"$request" $status "$http_user_agent" '
    'zone=$limit_req_zone';

# W bloku server — osobny plik dla zdarzeń 429
server {
    error_log /var/log/nginx/rate-limit.log warn;
}

# Monitoruj ataki w czasie rzeczywistym
tail -f /var/log/nginx/rate-limit.log | grep " 429 "

# Znajdz TOP 10 IP przekraczajacych limity
awk '$9 == 429 {print $1}' /var/log/nginx/access.log \
  | sort | uniq -c | sort -rn | head -10
```

## Parametry — tabela referencyjna

Dyrektywa

Opis

Typowa wartość

`rate=Xr/s`

Limit requestów na sekundę per klucz

10r/s strona, 5r/m login

`burst=N`

Bufor tolerancji — max N req do kolejkowania

20 strona, 5 API, 3 login

`nodelay`

Burst obsługiwany natychmiast (bez kolejki)

Dodaj gdy burst > 0

`delay=N`

Pierwsze N z burst natychmiast, reszta kolejkowana

delay=5 (kompromis)

`limit_conn N`

Max jednoczesnych połączeń per klucz

10 strona, 2 pobieranie

`limit_rate Xk`

Limit prędkości transferu per połączenie

500k dla plików do pobrania

## Najczęstsze pytania

Czym różni się limit\_req\_zone od limit\_conn\_zone? +

limit\_req\_zone ogranicza tempo żądań — liczbę requestów HTTP na sekundę/minutę (leaky bucket algorithm). Jeśli klient przekroczy limit, Nginx zwraca 503 lub kolejkuje request (burst). limit\_conn\_zone ogranicza jednoczesne połączenia TCP — ile otwartych połączeń jednocześnie może mieć jeden adres IP. Można używać obu jednocześnie: limit\_conn blokuje nadmierne połączenia (np. download managerów), limit\_req blokuje zbyt szybkie requestowanie (np. brute force login).

Co robi parametr burst w limit\_req? +

Burst to bufor tolerancji dla chwilowych skoków ruchu. Jeśli masz limit 10r/s i burst=20, Nginx pozwoli na natychmiastowe 20 requestów, ale nadmiar będzie kolejkowany i obsługiwany z tempem 10/s. Bez burst każdy request powyżej limitu natychmiast dostaje 503. Z "nodelay" burst requestów są obsługiwane natychmiast (bez kolejkowania), a kolejne ponad burst = 503. Dla login endpoint: mały burst (3-5) z nodelay blokuje brute force ale nie psuje UX przy kilku szybkich kliknięciach.

Jak whitelistować własne IP przy rate limiting? +

Użyj geo lub map do ustawienia zmiennej limitu. Geo pozwala przypisać różne wartości zmiennej do różnych zakresów IP. Następnie w limit\_req\_zone użyj tej zmiennej zamiast $binary\_remote\_addr. Dla zaufanych IP ustaw zmienną na pusty string — Nginx ignoruje puste klucze w strefie rate limiting i nie nalicza limitu. Alternatywnie możesz użyć if i limit\_req\_status, ale geo jest czystsze i bardziej wydajne.

Jakie kody HTTP zwraca Nginx przy przekroczeniu limitu? +

Domyślnie Nginx zwraca 503 Service Unavailable gdy przekroczony zostanie limit żądań lub połączeń. Możesz zmienić kod na 429 Too Many Requests (standard HTTP dla rate limiting) przez dyrektywę limit\_req\_status 429 i limit\_conn\_status 429. 429 jest lepszy dla klientów API — jasno komunikuje "spróbuj później" zamiast mylącego "serwer niedostępny". Dodaj nagłówek Retry-After w bloku error\_page 429, żeby klient wiedział kiedy ponowić.

## Sprawdź oferty pasujące do tego scenariusza

Poniżej masz szybkie przejścia do ofert i stron z kodami rabatowymi tam, gdzie są dostępne.

Contabo

VPS z pełną kontrolą konfiguracji Nginx i reguł rate limiting

VPS

[Aktywuj rabat →](/out/contabo/#reklama "Contabo")

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/contabo)

LH.pl

Hosting z wbudowaną ochroną DDoS — bez ręcznej konfiguracji Nginx

Hosting

[Aktywuj rabat →](/out/lh-pl/#reklama "LH.pl")

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/lh-pl)

Mikrus

Tani VPS do testowania konfiguracji Nginx rate limiting

Dev/Test

[Aktywuj rabat →](/out/mikrus/#reklama "Mikrus")

#Reklama · link partnerski

[Zobacz kod rabatowy →](/kody-rabatowe/mikrus)

## Powiązane strony

-   [Nginx load balancer — konfiguracja upstream](/baza-wiedzy/nginx-load-balancer-konfiguracja)
-   [Nginx virtual hosts — konfiguracja vhostów](/baza-wiedzy/nginx-vhost-konfiguracja)
-   [Bezpieczeństwo VPS — checklist administratora](/baza-wiedzy/bezpieczenstwo-vps-checklist)
-   [Wszystkie artykuły bazy wiedzy](/baza-wiedzy/)

Autor: [Adam Nadolny](/autorzy/adam-nadolny) Ekspert DevOps i infrastruktury · Zweryfikowano Czerwiec 2026

Administruje własnymi serwerami VPS i dedykowanymi, testując konfiguracje pod realnym obciążeniem — nie w sandboxie. W HostGrade.pl buduje bazę wiedzy DevOps: przewodniki po konfiguracji Nginx, Dockera, Redis i backupów serwerowych pisane na podstawie realnych deploymentów. Porównuje parametry techniczne planów VPS: gwarantowane vCPU kontra shared core, przepustowość sieci i IOPS dysków NVMe. Specjalizuje się w hardening serwera Linux — od fail2ban przez iptables po audyty CIS Benchmark. Każdy artykuł techniczny przechodzi przez środowisko testowe: konfiguracja Redis Cluster, setup HAProxy czy skrypt backup z BorgBackup są uruchamiane przed publikacją. Wierzy, że dobry tutorial kończy się komendą, której wynik faktycznie działa.

[Pełny profil autora →](/autorzy/adam-nadolny)