Menu
Szybki wybór
Hosting Domeny VPS SSL Kalkulator Porównania FAQ
Aktywne kody
Wszystkie kody rabatowe

Nginx rate limiting: limit_req_zone, burst, nodelay i ochrona przed DDoS

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

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.