Czym jest rate limiting i dlaczego ma znaczenie?
Krótko: ograniczaj tempo żądań, zanim przeciążą Twoją infrastrukturę.
Rate limiting to fundament nowoczesnego bezpieczeństwa i niezawodności aplikacji. Polega na kontrolowaniu liczby żądań, jakie użytkownik, adres IP czy klucz API może wykonać w określonym czasie. Dzięki temu chronisz serwery przed przeciążeniem, utrzymujesz sprawiedliwe wykorzystanie zasobów i zniechęcasz atakujących do prób nadużyć oraz ataków DDoS na poziomie aplikacji.
W praktyce oznacza to nadawanie „budżetu żądań” i jego odświeżanie w czasie. Gdy limit zostanie przekroczony, serwer odpowiada błędem 429 Too Many Requests, czasem wraz z nagłówkiem Retry-After, by zasugerować klientowi, kiedy spróbować ponownie. W dobrze zaprojektowanej architekturze to jeden z filarów – obok WAF, CDN i filtracji na poziomie L3/L4 – który zapewnia ciągłość działania.
Jak to działa od kuchni: modele limitowania
Wybór algorytmu wpływa na doświadczenie użytkownika i skuteczność ochrony.
- Token Bucket (wiaderko żetonów): daje elastyczność na „wybuchy” ruchu, ale utrzymuje średnią w ryzach. Dobry do API konsumenckich.
- Leaky Bucket: wygładza ruch do stałego strumienia, redukuje skoki. Świetny do usług wrażliwych na chwilowe przeciążenia.
- Fixed Window: proste okna czasowe (np. 100 żądań/minutę), ale podatne na „przebicia” przy granicach okien.
- Sliding Window: sprawiedliwsze okna przesuwne; bardziej precyzyjne, lecz minimalnie bardziej kosztowne.
- Limity równoległości (concurrency): ograniczają jednoczesne połączenia/operacje – ważne dla endpointów ciężkich (np. generowanie raportów).
W praktyce często łączy się kilka podejść, np. Sliding Window + Token Bucket, aby zapewnić i elastyczność, i kontrolę długoterminową.
Typy ataków DDoS a rola rate limiting
Nie każdy DDoS „pokonasz” tylko ograniczając tempo – potrzebna jest obrona warstwowa.
- Warstwa sieciowa (L3) i transportowa (L4): masowe zalewanie ruchem (UDP, SYN flood). Tu potrzebne są mechanizmy operatorskie, Anycast, scrubbing, ACL-e i ochrona na brzegu (CDN, dostawca chmury).
- Warstwa aplikacyjna (L7): ataki imitujące normalnych użytkowników (np. zalewanie loginów, wyszukiwania). Tutaj rate limiting jest wyjątkowo skuteczny, zwłaszcza w połączeniu z WAF i regułami wykrywającymi anomalie.
Kluczowe jest, by nie przeceniać jednej techniki. Rate limiting najlepiej działa na L7 i nadużycia API, ale musi współgrać z ochroną sieciową oraz filtracją ruchu zanim dotrze do aplikacji.
Strategia warstwowa: WAF, CDN i rate limiting
Zasada: zatrzymuj zły ruch jak najbliżej źródła i jak najtaniej.
- CDN z Anycast i scrubbingiem: przejmuje volumetryczne ataki i rozprasza je globalnie.
- WAF: rozpoznaje wzorce ataków, blokuje znane exploity oraz niestandardowe sygnatury.
- Rate limiting na brzegu (edge) i w aplikacji: dba o sprawiedliwe zasoby dla realnych użytkowników i neutralizuje L7 DDoS.
Ustal jasną ścieżkę: ruch trafia na CDN/WAF, potem do warstwowej limitacji (per IP, per konto, per klucz API), a na końcu do logiki aplikacji wyposażonej w dodatkowe „bezpieczniki”.
Projektowanie polityk: jak dobrać limity i zakresy
Zacznij od danych, nie od intuicji – najpierw obserwuj normalny ruch.
- Segmentacja: różne limity dla publicznych endpointów, operacji kosztownych (np. raporty, wyszukiwanie), akcji krytycznych (logowanie, reset hasła) i zasobów internal.
- Wymiary limitów:
- per IP (dobry baseline, pamiętaj o NAT i CGNAT),
- per użytkownik/konto/klucz API (najbardziej sprawiedliwe),
- per ścieżka/endpoint (różne koszty operacji),
- per region/ASN (gdy wzorce wskazują nadużycia).
- Burst vs. sustain: dopuszczaj krótkie piki (np. 10 żądań w 2 sekundy), ale trzymaj średnią (np. 300/min).
- „Allowlist” i „denylist”: z rozsądkiem. Nie dawaj nieograniczonego zaufania szerokim zakresom IP.
- Obsługa przekroczeń: błąd 429, nagłówki Retry-After, komunikaty pomagające użytkownikom i developerom zrozumieć problem.
- Wrażliwe akcje: rozważ progressive challenges (np. CAPTCHA dopiero po kilku przekroczeniach), by nie karać uczciwych.
- Idempotencja i retry: promuj nagłówki/macierze idempotency i backoff (np. wykładniczy) po stronie klienta.
Rate limiting w praktyce: od edge do aplikacji
Wybierz miejsce wdrożenia zgodnie z celem i kosztami.
- Na brzegu (CDN/WAF): tanio zatrzymasz masowe nadużycia zanim obciążą origin.
- Na load balancerze/reverse proxy: spójne limity dla całego klastra.
- W aplikacji: najwięcej kontekstu (użytkownik, plan taryfowy, rola), ale i największy koszt.
Rate limiting w NGINX
Prosty, szybki i skuteczny na warstwie reverse proxy.
Przykład (limit na IP z lekkim burstem):
limit_req_zone $binary_remote_addr zone=perip:10m rate=5r/s
limit_req_zone $http_authorization zone=perkey:10m rate=60r/m
server {
location /api/ {
limit_req zone=perip burst=10 nodelay;
limit_req zone=perkey burst=20;
add_header X-RateLimit-Policy “5r/s per IP; 60r/m per key”;
}
}
Powyżej łączymy dwa wymiary: IP oraz klucz. Warto dodać logowanie 429 i korelację z identyfikatorem żądania.
Rate limiting w chmurze: Cloudflare, AWS, GCP
Skorzystaj z natywnych usług, by ograniczyć opóźnienia wdrożenia.
- Cloudflare: Ruleset-y L7, bot management, dynamiczne limity per ścieżka, integracja z Turnstile (wyzwania bez CAPTCHA obrazkowych).
- AWS: WAF rate-based rules, API Gateway usage plans i throttling, CloudFront Function/Workers do niestandardowej logiki, Shield Advanced do volumetrii.
- GCP: Cloud Armor z politykami L7, Apigee do limitów per produkt/klucz, Cloud CDN na brzegu.
Rate limiting na poziomie aplikacji
Najbardziej elastyczne – wykorzystaj Redis i okna przesuwne.
Prosty schemat:
- Klucz: rate:{wymiar}:{identyfikator}, np. rate:user:123.
- Wartość: znaczniki czasu ostatnich żądań lub licznik + TTL.
- Algorytm Sliding Window: przy każdym żądaniu usuwasz stare wpisy, liczysz bieżące, decydujesz o akceptacji, ustawiasz TTL równy długości okna.
W Javie, Node czy Pythonie świetnie działa Redis + skrypt Lua dla atomowości. Pamiętaj o poziomych limitach na wąskie gardła (np. kolejki z maksymalną liczbą jednoczesnych zadań).
Monitorowanie i alertowanie
Bez obserwowalności każdy limit to strzał w ciemno.
- Metryki: liczba 429, odsetek 429 per endpoint, p95/p99 opóźnienia, błędy 5xx podczas ataków, saturacja CPU/RAM/IO, cache hit ratio.
- Logi: kto został ograniczony i dlaczego (IP, klucz, user-agent, ASN), korelacja z ruchem marketingowym lub wydaniami.
- Dashboards i alerty: progi dynamiczne (anomalia do mediany/odchylenia), osobne alarmy na sudden spikes i długotrwałe nadużycia.
- SLO/SLA: zdefiniuj akceptowalne czasy odpowiedzi i dostępność; limity nie mogą ich nadmiernie naruszać.
Testowanie i walidacja ochrony
Traktuj to jak funkcję biznesową – regularnie ćwicz i mierz.
- Testy obciążeniowe: k6, Locust, Gatling – weryfikuj progi, bursty, „cold starty”.
- Symulacje nadużyć: wiele IP, wiele kluczy, różne ścieżki ataku (np. wolne żądania, randomized user-agent).
- Canary i shadow mode: najpierw loguj potencjalne 429 bez egzekwowania, potem stopniowo zaostrzaj.
- Game days: ćwicz runbook zespołu – kto podnosi limity, kto kontaktuje się z CDN, kto komunikuje się z klientami.
Użyteczność i komunikacja z użytkownikami
Ochrona nie może być kosztem dobrego doświadczenia.
- Jasne komunikaty: „Przekroczono limit. Spróbuj ponownie za 30 s.” i link do dokumentacji.
- Developer-friendly: nagłówki X-RateLimit-Limit, X-RateLimit-Remaining, Retry-After, opis polityki w docs.
- Sprawiedliwość: różne plany taryfowe z transparentnymi limitami; możliwość podniesienia progu dla zaufanych partnerów.
- Prywatność: ogranicz zbieranie danych o użytkowniku – loguj tyle, ile potrzeba do bezpieczeństwa i zgodności.
Najczęstsze błędy przy wdrażaniu
Unikaj pułapek, które osłabiają ochronę lub psują UX.
- Jeden globalny limit dla całego API – uderza w kluczowe funkcje.
- Takie same limity dla tanich i drogich operacji.
- Blokowanie szerokich zakresów IP/ASN bez analizy – ryzyko fałszywych trafień.
- Ignorowanie IPv6 i nagłówków PROXY/Forwarded – zła identyfikacja klienta.
- Brak idempotencji i backoffu – klienci „dokręcają” pętlę retry i pogarszają sytuację.
- Brak limitów na GraphQL lub wyszukiwanie – pojedyncze zapytania potrafią być ekstremalnie kosztowne.
- Brak cache’owania często odczytywanych zasobów – niepotrzebnie „przepalasz” budżet limitów.
Plan reakcji na incydenty DDoS
Z góry uzgodniony runbook skraca czas niedostępności.
- Identyfikacja: wykryj warstwę ataku (L3/L4/L7), wolumetrię, geografie, ASN.
- Eskalacja do dostawcy: włącz tryby awaryjne CDN/WAF, poproś o dodatkowe filtrowanie.
- Zaostrzenie limitów: tymczasowo obniż progi na newralgicznych endpointach, włącz wyzwania.
- Feature flags: wyłącz na chwilę najcięższe funkcje (np. generowanie raportów).
- Komunikacja: status page, ETA, informacje dla kluczowych klientów.
- Post mortem: co zadziałało, co usprawnić, jakie progi i reguły zmienić.
Podsumowanie
Skuteczna ochrona to połączenie rozsądnych limitów, mądrej infrastruktury i dobrej obserwowalności.
Rate limiting to prosta idea o ogromnej mocy – szczególnie wobec ataków na warstwę aplikacji i codziennych nadużyć. Najlepiej działa jako element strategii warstwowej: CDN i scrubbing na brzegu, WAF do filtrowania wzorców, a następnie granularne limity per IP, użytkownik i endpoint. Zaprojektuj polityki na podstawie realnych danych, testuj je regularnie i komunikuj jasno użytkownikom. Dzięki temu utrzymasz wydajność, obniżysz koszty i zapewnisz stabilne działanie nawet pod presją niespodziewanych skoków ruchu.