{"id":21255,"date":"2026-09-02T08:35:33","date_gmt":"2026-09-02T06:35:33","guid":{"rendered":"https:\/\/webhosting.de\/nginx-rate-limiting-schutz-vor-bot-traffic-angriffen-secure\/"},"modified":"2026-09-02T08:35:33","modified_gmt":"2026-09-02T06:35:33","slug":"nginx-hastighedsbegraensning-beskyttelse-mod-bot-trafikangreb-sikkerhed","status":"publish","type":"post","link":"https:\/\/webhosting.de\/da\/nginx-rate-limiting-schutz-vor-bot-traffic-angriffen-secure\/","title":{"rendered":"NGINX-ratebegr\u00e6nsning: Effektiv beskyttelse mod bot-trafik og angreb"},"content":{"rendered":"<p><strong>NGINX-hastighed<\/strong> Limiting stopper automatiserede foresp\u00f8rgsler, d\u00e6mper spidsbelastninger og beskytter login-, API- og formular-endepunkter mod bots og angreb. Jeg viser dig, hvordan du definerer gr\u00e6nser og bruger dem til <strong>Beskyttelse mod bots<\/strong> anvender og ud fra dette udarbejder et robust sikkerhedskoncept til meget bes\u00f8gte hjemmesider.<\/p>\n\n<h2>Centrale punkter<\/h2>\n\n<p><strong>V\u00e6sentligt<\/strong> Dette er de centrale budskaber:<\/p>\n<ul>\n  <li><strong>Prisgr\u00e6nser<\/strong> bremser ondsindede angreb og beskytter backend-ressourcer.<\/li>\n  <li><strong>Burst\/ingen forsinkelse<\/strong> opfanger legitime spidsbelastninger uden at blokere brugerne.<\/li>\n  <li><strong>zoner<\/strong> adskiller mennesker og bots med forskellige begr\u00e6nsninger.<\/li>\n  <li><strong>Logning<\/strong> leverer data til iterativt at sk\u00e6rpe gr\u00e6nserne.<\/li>\n  <li><strong>Integration<\/strong> med WAF, DDoS-beskyttelse og overv\u00e5gning \u00f8ges effektiviteten.<\/li>\n<\/ul>\n\n<h2>Hvorfor rate limiting stopper angreb i tide<\/h2>\n\n<p>Angribere satser p\u00e5 h\u00f8je <strong>Anmodningsfrekvenser<\/strong>, for at misbruge login-formularer, overbelaste API\u2019er eller automatisk scrape indhold. Derfor begr\u00e6nser jeg antallet af foresp\u00f8rgsler pr. n\u00f8gle \u2013 som regel pr. IP-adresse \u2013 og beslutter, om jeg skal begr\u00e6nse dem, forsinke dem eller svare med en 429-fejl. P\u00e5 den m\u00e5de holder jeg bottrafik v\u00e6k fra CPU, database og applikationslogik og lader legitime brugere komme igennem. S\u00e6rligt f\u00f8lsomme stier som \/login, \/auth, \/xmlrpc.php eller ressourcekr\u00e6vende s\u00f8gninger drager stor fordel heraf. Kilden til denne fremgangsm\u00e5de er <strong>Nginx-dokumentation<\/strong> om ngx_http_limit_req_module.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img fetchpriority=\"high\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-rate-limiting-rechenzentrum-4738.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>S\u00e5dan fungerer NGINX-modulet i praksis<\/h2>\n\n<p>Modulet fungerer efter princippet om <strong>Ut\u00e6t spand<\/strong>-Princip: For hver n\u00f8gle gemmer NGINX t\u00e6llerstande i en zone og sammenligner dem med den tilladte hastighed. Typiske n\u00f8gler er $binary_remote_addr for IP-adresser, tokens for API-n\u00f8gler eller afledte v\u00e6rdier via map. Hvis en klient vedvarende overskrider hastigheden og burst-bufferen, afviser NGINX anmodningen, inden den n\u00e5r backenden. Det sparer regnetid og reducerer ventetider for \u00e6gte bes\u00f8gende. Reaktionen indstiller jeg til 429 Too Many Requests eller eventuelt en anden <strong>Statuskode<\/strong> um.<\/p>\n\n<h2>Konfiguration: Forklaret trin for trin<\/h2>\n\n<p>Jeg starter med en zone i http-sektionen, indstiller en moderat hastighed og aktiverer den m\u00e5lrettet p\u00e5 f\u00f8lsomme stier. Ved kortvarige spidsbelastninger definerer jeg en burst, eventuelt med nodelay, for at undg\u00e5 pludselige afvisninger. Derefter tester jeg i staging-milj\u00f8et og analyserer logfilerne, f\u00f8r jeg tager det i brug i produktionsmilj\u00f8et. P\u00e5 den m\u00e5de undg\u00e5r jeg un\u00f8dvendige sp\u00e6rringer for \u00e6gte brugere. Et kortfattet eksempel illustrerer dette <strong>Syntaks<\/strong> h\u00e5ndgribelig:<\/p>\n\n<pre><code># http {}\nlimit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r\/s;\n\nserver {\n  location \/api\/ {\n    limit_req zone=req_limit_per_ip burst=20 nodelay;\n    limit_req_status 429;\n  }\n\n  location \/login {\n    limit_req zone=req_limit_per_ip burst=5;\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n<h2>Bot-beskyttelse med zoner og user-agent-logik<\/h2>\n\n<p>IP-baserede begr\u00e6nsninger er sj\u00e6ldent tilstr\u00e6kkelige mod distribuerede botnet, derfor opdeler jeg trafikken i <strong>zoner<\/strong>: Mennesker f\u00e5r mere gener\u00f8se v\u00e6rdier, mens generiske crawlere f\u00e5r strengere. Med \u00bbmap\u00ab vurderer jeg user-agenter, genkender godkendte bots som Googlebot og tildeler dem deres egne, n\u00f8je overv\u00e5gede gr\u00e6nser. For ukendte scrapere s\u00e6tter jeg strenge gr\u00e6nser p\u00e5 ressourcekr\u00e6vende ruter. Hvis der dukker m\u00f8nstre op, sk\u00e6rper jeg restriktionerne dynamisk, indtil <strong>Vurder<\/strong> igen er inden for det normale.<\/p>\n\n<h2>Finjustering: hastighed, burst, nodelay og statuskoder<\/h2>\n\n<p>Rate styrer gennemstr\u00f8mningen pr. sekund, Burst tillader kortvarige buffere, og nodelay afg\u00f8r, om jeg foretr\u00e6kker buffering eller \u00f8jeblikkelig gennemladning. Jeg starter moderat, f.eks. 10r\/s med burst 20 p\u00e5 API'er, og finjusterer efter loganalyse. For login-ruter indstiller jeg f.eks. 1r\/s med en lille burst for at bremse brute-force-angreb. Ved overskridelser returnerer jeg 429, fordi klienter dermed <strong>klare sig<\/strong> og at \u00bbRetry\u00ab-logikken fungerer korrekt. I s\u00e6rlige tilf\u00e6lde bruger jeg alternative koder, hvis kunderne \u00f8nsker det.<\/p>\n\n<h2>Oversigt i tabellen: Direktiver og anvendelse<\/h2>\n\n<p>Det f\u00f8lgende <strong>Bord<\/strong> opsummerer de vigtigste retningslinjer og viser, hvorn\u00e5r de er relevante.<\/p>\n\n<table>\n  <thead>\n    <tr>\n      <th>direktiv<\/th>\n      <th>Effekt<\/th>\n      <th>Eksempel<\/th>\n      <th>Typisk brug<\/th>\n    <\/tr>\n  <\/thead>\n  <tbody>\n    <tr>\n      <td>limit_req_zone<\/td>\n      <td>Angiv n\u00f8gle, zone og <strong>Vurder<\/strong> fast<\/td>\n      <td>limit_req_zone $binary_remote_addr zone=perip:10m rate=10r\/s;<\/td>\n      <td>Grundlag pr. IP, token eller user-agent<\/td>\n    <\/tr>\n    <tr>\n      <td>limit_req<\/td>\n      <td>Aktiverer gr\u00e6nsen i <strong>Placering<\/strong>\/Server<\/td>\n      <td>limit_req zone=perip burst=20 nodelay;<\/td>\n      <td>Finjustering pr. sti eller vHost<\/td>\n    <\/tr>\n    <tr>\n      <td>limit_req_status<\/td>\n      <td>Tilf\u00f8jer HTTP-kode <strong>Overskridelse<\/strong><\/td>\n      <td>limit_req_status 429;<\/td>\n      <td>Korrekt klientadf\u00e6rd og gentagelser<\/td>\n    <\/tr>\n    <tr>\n      <td>kort<\/td>\n      <td>Videresender anmodninger til <strong>zoner<\/strong> p\u00e5<\/td>\n      <td>map $http_user_agent $is_bot {\u2026}<\/td>\n      <td>Skelnen mellem bot og menneske baseret p\u00e5 User-Agent<\/td>\n    <\/tr>\n  <\/tbody>\n<\/table>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/NGINXLimitingMeeting1234.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Praksis: M\u00e5lrettet beskyttelse af login-endepunktet<\/h2>\n\n<p>Jeg begr\u00e6nser \/login meget strengt, fordi bots bruger adgangskoder med h\u00f8j <strong>Frekvens<\/strong> Pr\u00f8ve sig frem. 1 anmodning pr. sekund med burst 3 forhindrer massiv g\u00e6tning uden at ramme rigtige brugere for h\u00e5rdt. Derudover registrerer jeg gentagne fejlfors\u00f8g i loggen for midlertidigt at blokere IP-adresser. Kombineret med 2FA og eventuelt Captcha mindskes belastningen p\u00e5 databasen og sessionh\u00e5ndteringen m\u00e6rkbart. P\u00e5 den m\u00e5de holder jeg antallet af fejlfors\u00f8g nede og sikrer, at <strong>Adgang<\/strong> klar og stabil.<\/p>\n\n<h2>Praksis: At stille API\u2019er til r\u00e5dighed p\u00e5 en retf\u00e6rdig og kontrolleret m\u00e5de<\/h2>\n\n<p>API\u2019er kr\u00e6ver klare <strong>Odds<\/strong>, s\u00e5 enkelte klienter ikke optager hele b\u00e5ndbredden. For generelle ruter indstiller jeg 10r\/s og burst 20, mens jeg anvender strengere v\u00e6rdier for dyre slutpunkter. Hvis der er tokens eller API-n\u00f8gler til r\u00e5dighed, begr\u00e6nser jeg pr. token i stedet for pr. IP. Det skaber retf\u00e6rdighed mellem kunderne og forhindrer misbrug. En mere dybdeg\u00e5ende introduktion findes i min vejledning til <a href=\"https:\/\/webhosting.de\/da\/api-rate-limiting-hosting-beskyttelse-mod-misbrug-sikkerhed\/\">API-ratebegr\u00e6nsning<\/a>, som s\u00e6tter begrebet ind i en bredere sammenh\u00e6ng.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-rate-limiting-security-5721.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Overv\u00e5gning, logning og iterativ finjustering<\/h2>\n\n<p>Jeg logger 429-svarene sammen med <strong>N\u00f8gle<\/strong> (f.eks. IP eller token) og sti for at genkende m\u00f8nstre. Pludselige stigninger p\u00e5 f\u00e5 stier tyder p\u00e5 scraping eller brute-force-angreb; en j\u00e6vnt fordelt belastning tyder p\u00e5 botnet. Med disse data indf\u00f8rer jeg kun begr\u00e6nsninger, hvor det er n\u00f8dvendigt, og minimerer falske positiver. Dashboards med hastigheder, fejlprocent og latenstid viser mig effekten af hver \u00e6ndring. P\u00e5 den m\u00e5de forbliver <strong>Ydelse<\/strong> h\u00f8j, mens beskyttelsen \u00f8ges.<\/p>\n\n<h2>Integration i et helhedsorienteret beskyttelseskoncept<\/h2>\n\n<p>Jeg anser rate limiting for at v\u00e6re et st\u00e6rkt f\u00f8rste skridt <strong>lag<\/strong>, men jeg kombinerer det med WAF-regler, IP-reputation og TLS-h\u00e6rdning. Mod angreb med stor datam\u00e6ngde hj\u00e6lper en forudg\u00e5ende DDoS-beskyttelse, der filtrerer trafikken p\u00e5 netv\u00e6rksniveau, inden NGINX skal tr\u00e6de i aktion. Jeg m\u00e5ler l\u00f8bende n\u00f8gletal, indstiller alarmer ved us\u00e6dvanlige spidsbelastninger og reagerer med regelopdateringer. P\u00e5 den m\u00e5de skabes der et robust beskyttelsesnetv\u00e6rk ud af flere byggesten. Disse giver et praktisk overblik <a href=\"https:\/\/webhosting.de\/da\/ddos-mitigation-webhosting-strategier-beskyttelse-netvaerk\/\">DDoS-strategier<\/a>.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx_schutz_tech_office_6352.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Konkrete konfigurationsm\u00f8nstre for bots kontra mennesker<\/h2>\n\n<p>Jeg inddeler bes\u00f8gende i kategorier ved hj\u00e6lp af map og omdirigerer dem til deres egne <strong>zoner<\/strong>. Kendte crawlere f\u00e5r moderate begr\u00e6nsninger, mens generiske agenter f\u00e5r strengere. For stier som \/search eller \/report er jeg strengere, da de belaster CPU\u2019en meget. Ved gentagne overtr\u00e6delser \u00f8ger jeg ikke gr\u00e6nserne, men sp\u00e6rrer adgangen midlertidigt eller flytter kontrollen over til et bot-genkendelsesmodul. P\u00e5 den m\u00e5de forbliver <strong>Misbrugsfrekvens<\/strong> lav, uden at forstyrre s\u00f8gemaskinerne.<\/p>\n\n<h2>Eksempel: To zoner og brugeragent-tilknytning<\/h2>\n\n<p>F\u00f8lgende uddrag viser opdelingen efter <strong>Brugeragent<\/strong> og tildeling af passende gr\u00e6nser. Jeg kombinerer dette med differentierede statuskoder og logningsfelter for at kunne m\u00e5le effekten pr\u00e6cist. Bots med generiske agenter havner i den strenge zone. Mennesker eller verificerede crawlere benytter den mere lempelige zone. Denne tilgang giver forudsigelige <strong>Gennemstr\u00f8mning<\/strong> pr. klasse:<\/p>\n\n<pre><code>map $http_user_agent $is_bot {\n  default 0;\n  \"~*googlebot\"     0;\n  \"~*bingbot\" 0;\n  \"~*crawler|scraper|bot\" 1;\n}\n\nlimit_req_zone $binary_remote_addr zone=human:10m rate=10r\/s;\nlimit_req_zone $binary_remote_addr zone=bot:10m   rate=1r\/s;\n\nserver {\n  location \/ {\n    if ($is_bot) {\n limit_req zone=bot burst=5;\n    }\n    if ($is_bot = 0) {\n limit_req zone=human burst=20 nodelay;\n    }\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx_rate_limiting_schutz_3947.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Fejlh\u00e5ndtering: Korrekt kommunikation ved fejlkode 429<\/h2>\n\n<p>Hos Limits leverer jeg en klar <strong>Svar<\/strong> med en angivelse af, hvorn\u00e5r det er hensigtsm\u00e6ssigt at pr\u00f8ve igen. For API\u2019er skal den gyldige \u00bbRetry-After\u00ab-header v\u00e6re til stede, s\u00e5 klienter kan anvende \u00bbBackoff\u00ab. Menneskelige brugere f\u00e5r en kort forklaring uden tekniske detaljer. Det reducerer antallet af supportanmodninger og sikrer en forst\u00e5elig adf\u00e6rd. En overskuelig <strong>UX<\/strong> g\u00f8r gr\u00e6nser acceptable og forhindrer frustration.<\/p>\n\n<h2>Webhost, netv\u00e6rk og kerne: styrke grundlaget<\/h2>\n\n<p>H\u00f8j m\u00e6ngde legitim trafik og sikkerhedsforanstaltninger kr\u00e6ver p\u00e5lidelige <strong>Ressourcer<\/strong> og fornuftige standardindstillinger p\u00e5 netv\u00e6rksniveau. Jeg s\u00f8rger for, at NGINX-versionerne er opdaterede, at der er tilstr\u00e6kkelig RAM til zoner, og at der er beskyttelsesfunktioner mod transportangreb. Mod SYN-floods hj\u00e6lper det at aktivere <a href=\"https:\/\/webhosting.de\/da\/tcp-syn-cookies-beskyttelse-mod-syn-flood-kerne\/\">TCP SYN-cookies<\/a> i kernen, s\u00e5 forbindelser ikke h\u00e6nger fast. Alt i alt aflaster dette NGINX for un\u00f8dvendig belastning. P\u00e5 den m\u00e5de fokuserer jeg begr\u00e6nsningerne p\u00e5 HTTP-lagene og holder <strong>Gennemstr\u00f8mning<\/strong> stabil.<\/p>\n\n\n<figure class=\"wp-block-image size-full is-resized\">\n  <img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/webhosting.de\/wp-content\/uploads\/2026\/09\/nginx-ratelimit-schutz-4829.png\" alt=\"\" width=\"1536\" height=\"1024\"\/>\n<\/figure>\n\n\n<h2>Kort sagt: S\u00e5dan bruger jeg NGINX-ratebegr\u00e6nsning effektivt<\/h2>\n\n<p>Jeg begr\u00e6nser antallet af foresp\u00f8rgsler pr. <strong>n\u00f8gle<\/strong>, afsk\u00e6rmer kritiske stier og holder bots p\u00e5 afstand med strenge zoner. Burst og nodelay hj\u00e6lper med at tillade legitime spidsbelastninger uden at fremme misbrug. Via 429-logfiler kalibrerer jeg l\u00f8bende v\u00e6rdierne og sk\u00e6rper gr\u00e6nserne kun der, hvor der er behov for det. I kombination med WAF, DDoS-forsvar, overv\u00e5gning og kernel-h\u00e6rdning skabes et robust beskyttelseskoncept. Den, der konsekvent implementerer dette, reducerer bot-trafikken markant og bevarer <strong>Ydelse<\/strong> selv under belastning.<\/p>\n\n<h2>Elementer, der ofte mangler i praksis<\/h2>\n\n<p>I mange ops\u00e6tninger mangler der nogle afg\u00f8rende komponenter, som m\u00e6rkbart \u00f8ger effekten af rate limiting:<\/p>\n<ul>\n  <li><strong>Den egentlige klient-IP bag proxyservere<\/strong>: Uden korrekt h\u00e5ndtering af den reelle IP-adresse begr\u00e6nser NGINX ofte load balancerens IP-adresse \u2013 begr\u00e6nsningerne g\u00e6lder da for alle de brugere, der er samlet bagved.<\/li>\n  <li><strong>T\u00f8rtest (Dry-Run)<\/strong>: Gr\u00e6nser aktiveres \u201eblindt\u201c. Det er bedre f\u00f8rst at registrere, hvor ofte en gr\u00e6nse ville v\u00e6re blevet udl\u00f8st.<\/li>\n  <li><strong>Finkornede n\u00f8gler<\/strong>: I stedet for kun at begr\u00e6nse adgangen pr. IP-adresse, er det en god id\u00e9 at indf\u00f8re begr\u00e6nsninger pr. API-token, session eller bruger for at sikre st\u00f8rre retf\u00e6rdighed.<\/li>\n  <li><strong>Samspil med limit_conn<\/strong>: Parallelle forbindelser og anmodningsfrekvenser d\u00e6kker forskellige m\u00f8nstre for misbrug.<\/li>\n  <li><strong>M\u00e5lrettede undtagelser<\/strong>: Sundhedstjek, webhooks eller interne tjenester kr\u00e6ver ofte mere fleksible begr\u00e6nsninger eller slet ingen.<\/li>\n<\/ul>\n\n<h2>Reverse proxy: sikker analyse af den reelle klient-IP-adresse<\/h2>\n\n<p>Hvis NGINX k\u00f8rer bag en load balancer, indstiller jeg Real-IP-direktiverne, s\u00e5 $binary_remote_addr afspejler den reelle klient. Jeg stoler kun p\u00e5 netv\u00e6rk, som jeg selv ejer, og aktiverer rekursiv evaluering:<\/p>\n\n<pre><code>http {\n  # P\u00e5lidelige proxy-IP-intervaller (eksempel)\n  set_real_ip_from 10.0.0.0\/8;\n  set_real_ip_from 192.168.0.0\/16;\n  # Tilf\u00f8j eventuelt offentlige LB-\/CDN-intervaller\n\n  real_ip_header X-Forwarded-For;\n  real_ip_recursive on;\n\n  limit_req_zone $binary_remote_addr zone=perip:20m rate=10r\/s;\n}\n<\/code><\/pre>\n\n<p>Uden denne indstilling vil en begr\u00e6nsning ellers ramme mange brugere p\u00e5 \u00e9n gang, selvom de ikke har gjort noget forkert. Efter ops\u00e6tningen tjekker jeg i adgangslogfilerne, om den forventede klient-IP-adresse vises.<\/p>\n\n<h2>N\u00f8glestrategi: IP, bruger, token og sti<\/h2>\n\n<p>Det valgte n\u00f8glekoncept er afg\u00f8rende for retf\u00e6rdighed og effekt. Her er nogle gennempr\u00f8vede modeller:<\/p>\n<ul>\n  <li><strong>Pro IP<\/strong> ($binary_remote_addr): Hurtig at s\u00e6tte i drift, velegnet til \/login og anonyme slutpunkter.<\/li>\n  <li><strong>Per API-token<\/strong>: Retf\u00e6rdighed mellem kunderne; beskytter mod NAT-bundling. Jeg udtr\u00e6kker tokens ved hj\u00e6lp af map.<\/li>\n  <li><strong>Pr. sti-klasse<\/strong>: Begr\u00e6ns dyre slutpunkter separat, f.eks. \/search i h\u00f8jere grad end \/status.<\/li>\n<\/ul>\n\n<pre><code>map $http_authorization $api_token {\n  default \"\";\n  \"~*^Bearer\\s+(.+)$\" $1;\n}\n\nlimit_req_zone $api_token zone=per_token:30m rate=5r\/s;\n\nserver {\n  location \/api\/ {\n    # G\u00e6lder kun, hvis der findes et token\n    limit_req zone=per_token burst=10;\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n<p>Vigtigt: H\u00f8j n\u00f8glekardinalitet bruger hukommelse i zonen. S\u00f8rg for at afs\u00e6tte bufferplads, og hold \u00f8je med udnyttelsen.<\/p>\n\n<h2>Lagring og dimensionering af zonerne<\/h2>\n\n<p>Zonen gemmer metadata for hver aktiv n\u00f8gle. Forbruget ligger p\u00e5 nogle f\u00e5 dusin byte pr. post plus overhead. Herudfra konkluderer jeg:<\/p>\n<ul>\n  <li>Hvis der er mange samtidige IP-adresser\/tokens, v\u00e6lger jeg st\u00f8rre zoner, f.eks. 50\u2013100 MB.<\/li>\n  <li>Jeg starter med en ret gener\u00f8s indstilling og l\u00e6ser NGINX-logfilerne: \u201eshared memory zone is full\u201c indikerer, at der skal foretages en finjustering.<\/li>\n  <li>Ubrugte n\u00f8gler udl\u00f8ber efter kortvarig inaktivitet; spidsbelastninger er vigtigere end dagsgennemsnittet.<\/li>\n<\/ul>\n\n<h2>Pr\u00e6cis anvendelse af burst og nodelay<\/h2>\n\n<p>Uden at <strong>nodelay<\/strong> NGINX placerer overskridelser i burst-bufferen og <em>forsinket<\/em> Anmodninger. Med <strong>nodelay<\/strong> Tilladte burst-anmodninger slippes straks igennem, mens overskydende afvises. Min fremgangsm\u00e5de:<\/p>\n<ul>\n  <li><strong>Interaktive ruter<\/strong> (HTML): helst uden nodelay for at skabe korte ventetider i stedet for en direkte 429-fejl.<\/li>\n  <li><strong>API'er<\/strong>: ofte med \u00bbnodelay\u00ab, s\u00e5 klienterne tydeligt modtager en 429-fejl og anvender backoff.<\/li>\n  <li><strong>Dyre slutpunkter<\/strong>: en lille burst for at udj\u00e6vne spidsbelastninger i backend.<\/li>\n<\/ul>\n\n<h2>T\u00f8rk\u00f8rsel, logniveau og evaluering<\/h2>\n\n<p>Inden jeg aktiverer begr\u00e6nsningerne, aktiverer jeg Dry-Run og justerer log-niveauet. P\u00e5 den m\u00e5de kan jeg se effekten uden risiko:<\/p>\n\n<pre><code>server {\n  location \/api\/ {\n    limit_req zone=perip burst=20;\n    limit_req_dry_run on; # kun logge, ikke blokere\n    limit_req_log_level notice;  # mindre alvorligt end 'error'\n  }\n}\n<\/code><\/pre>\n\n<p>Derefter analyserer jeg adgangsdata fra de seneste 3\u20137 dage, identificerer hotspots, justerer rate\/burst og deaktiverer f\u00f8rst derefter dry-run.<\/p>\n\n<h2>429-fejlh\u00e5ndtering: HTML, JSON og Retry-After<\/h2>\n\n<p>For at sikre en god brugeroplevelse skelner jeg mellem browsere og API-klienter og indstiller <strong>Retry-After<\/strong>. S\u00e5dan kommunikerer jeg gr\u00e6nser tydeligt:<\/p>\n\n<pre><code>map $http_accept $wants_json {\n  default 0;\n  \"~*application\/json|\/json\"    1;\n}\n\nserver {\n  error_page 429 = @rate_limited;\n\n  location @rate_limited {\n    add_header Retry-After 2 always;\n    if ($wants_json) {\n add_header Content-Type application\/json;\n      return 429 '{\"error\":\"too_many_requests\",\"retry_after\":2}';\n    }\n    return 429 \"Pr\u00f8v igen senere.\";\n  }\n}\n<\/code><\/pre>\n\n<p>API'er kan reagere programmatisk, og brugerne f\u00e5r en forst\u00e5elig meddelelse.<\/p>\n\n<h2>Kombinering af limit_req og limit_conn<\/h2>\n\n<p><strong>limit_req<\/strong> angiver gennemstr\u00f8mning pr. tidsvindue, <strong>limit_conn<\/strong> begr\u00e6nser antallet af samtidige forbindelser. Mod downloads, chatty-klienter eller HTTP\/2-oversv\u00f8mmelser kombinerer jeg begge dele:<\/p>\n\n<pre><code>limit_conn_zone $binary_remote_addr zone=perip_conn:10m;\n\nserver {\n  location \/api\/ {\n    limit_req  zone=perip burst=20 nodelay;\n    limit_conn zone=perip_conn 20;  # maks. 20 samtidige forbindelser pr. IP\n  }\n}\n<\/code><\/pre>\n\n<p>P\u00e5 den m\u00e5de undg\u00e5r jeg, at nogle f\u00e5 klienter ganske vist overholder hastigheden, men alligevel optager ressourcer med for mange samtidige forbindelser.<\/p>\n\n<h2>Undtagelser, sundhedstjek og interne ruter<\/h2>\n\n<p>Ikke alle paths beh\u00f8ver begr\u00e6nsninger. Health-checks (\/healthz), interne webhooks eller betalings-callbacks f\u00e5r deres egne locations uden limit_req \u2013 eller med lavere v\u00e6rdier:<\/p>\n\n<pre><code>server {\n  # ingen begr\u00e6nsninger for sundhedstjek\n  location = \/healthz { return 200 \"ok\"; }\n\n  # bl\u00f8de begr\u00e6nsninger for betalings-callbacks\n  location \/webhooks\/pay\/ {\n    limit_req zone=perip burst=5;\n  }\n\n  # streng beskyttelse ved login\n  location = \/login {\n    limit_req zone=perip rate=1r\/s burst=3;\n  }\n}\n<\/code><\/pre>\n\n<p>Granul\u00e6re undtagelser reducerer antallet af falske positiver og sikrer stabile integrationer.<\/p>\n\n<h2>Mere robust zonestyring uden \u00bbif-magi\u00ab<\/h2>\n\n<p>N\u00e5r det g\u00e6lder opdelingen mellem \u201ebot og menneske\u201c, foretr\u00e6kker jeg interne omdirigeringer via navngivne placeringer. Det g\u00f8r konfigurationen overskuelig og forudsigelig:<\/p>\n\n<pre><code>map $http_user_agent $is_bot {\n  default 0;\n  \"~*googlebot|bingbot\" 0;\n  \"~*crawler|scraper|bot\" 1;\n}\n\nlimit_req_zone $binary_remote_addr zone=human:20m rate=10r\/s;\nlimit_req_zone $binary_remote_addr zone=bot:10m   rate=1r\/s;\n\nserver {\n  error_page 418 = @bot;\n\n  location \/ {\n    if ($is_bot) { return 418; }   # intern omdirigering\n    limit_req zone=human burst=20 nodelay;\n    limit_req_status 429;\n    try_files $uri $uri\/ \/index.html;\n  }\n\n  location @bot {\n    limit_req zone=bot burst=5;\n    limit_req_status 429;\n  }\n}\n<\/code><\/pre>\n\n<p>S\u00e5ledes ender bots deterministisk i den strenge zone, mens mennesker ender i den afslappede \u2013 uden at begge gr\u00e6nser virker samtidigt.<\/p>\n\n<h2>Test, m\u00e5ling, p\u00e5tagning: en pragmatisk fremgangsm\u00e5de<\/h2>\n\n<ul>\n  <li><strong>Iscenes\u00e6ttelse<\/strong>: V\u00e6lg en konservativ hastighed\/burst, aktiver dry-run, og k\u00f8r syntetisk belastning mod hot-path.<\/li>\n  <li><strong>R\u00f8gpr\u00f8ver<\/strong>: Brug curl eller Lasttools til at generere korte bursts og kontroll\u00e9r 429\/Delay-adf\u00e6rden.<\/li>\n  <li><strong>Produktiv-Pilot<\/strong>: Anvend det f\u00f8rst p\u00e5 enkelte lokationer, og f\u00f8lg logfilerne n\u00f8je.<\/li>\n  <li><strong>Iterativ skarphedsjustering<\/strong>: Indf\u00f8r kun begr\u00e6nsninger der, hvor der ses m\u00f8nstre; minimer falske alarmer.<\/li>\n<\/ul>\n\n<pre><code># Eksempel: hurtig burst-test med curl\nfor i in {1..50}; do curl -s -o \/dev\/null -w \"%{http_code}\\n\" https:\/\/example.com\/login &amp; done; wait\n<\/code><\/pre>\n\n<h2>Minut- i stedet for sekundhastigheder og detaljerede stier<\/h2>\n\n<p>NGINX tillader hastigheder i sekunder eller minutter (<strong>r\/s<\/strong>, <strong>r\/m<\/strong>). Ved misbrug af login indstiller jeg ofte 60r\/m i stedet for 1r\/s for at tillade korte, legitime dobbeltklik, men begr\u00e6nse kontinuerlige indtastninger. Dyre stier f\u00e5r strammere begr\u00e6nsninger end billige. Eksempel:<\/p>\n\n<pre><code>limit_req_zone $binary_remote_addr zone=perip_min:20m rate=60r\/m;\n\nserver {\n  location \/search\/ {\n    limit_req zone=perip_min burst=10;   # strengere\n  }\n  location \/status {\n    # ingen begr\u00e6nsning \u2013 billig og bruges internt\n    return 200;\n  }\n}\n<\/code><\/pre>\n\n<h2>Faldgruber og hvordan jeg undg\u00e5r dem<\/h2>\n\n<ul>\n  <li><strong>Forkert n\u00f8gle<\/strong>: N\u00e5r der bruges proxyservere uden en rigtig IP-adresse, begr\u00e6nser jeg ved en fejltagelse alle brugere p\u00e5 \u00e9n gang.<\/li>\n  <li><strong>For sm\u00e5 zoner<\/strong>: \u201ezone is full\u201c medf\u00f8rer uforudsigelig adf\u00e6rd \u2013 s\u00f8rg for gener\u00f8s dimensionering.<\/li>\n  <li><strong>En gr\u00e6nse for alt<\/strong>: Forskellige veje kr\u00e6ver forskellige v\u00e6rdier; en l\u00f8sning, der passer til alle, skaber frustration.<\/li>\n  <li><strong>Ingen overv\u00e5gning<\/strong>: Uden en 429-analyse forbliver fejlkonfigurationer ubem\u00e6rket.<\/li>\n  <li><strong>Over-whitelist<\/strong>: For brede undtagelser \u00e5bner d\u00f8r og port \u2013 lav en hvidliste, der er m\u00e5lrettet, midlertidig og gennemsigtig.<\/li>\n<\/ul>\n\n<h2>S\u00e6rlige forhold ved HTTP\/2, SSE og caching<\/h2>\n\n<p>HTTP\/2 samler anmodninger i f\u00e5 forbindelser; <strong>limit_conn<\/strong> er er stadig relevant, da streams bruger ressourcer. Server-sent events eller lange downloads udl\u00f8ser sj\u00e6ldent rate-limits (f\u00e5 anmodninger), men tager tid \u2013 her begr\u00e6nser jeg antallet af samtidige forbindelser med `limit_conn` eller implementerer b\u00e5ndbreddestrategier. Hvor det er muligt, aflaster jeg med <strong>Caching<\/strong> (f.eks. statiske ressourcer, hyppige GET-anmodninger), s\u00e5 begr\u00e6nsningerne udl\u00f8ses sj\u00e6ldnere, og brugerne f\u00e5r hurtigere svar.<\/p>\n\n<h2>Operativ tjekliste<\/h2>\n\n<ul>\n  <li>Real-IP er korrekt, n\u00f8gler er defineret (IP\/token\/bruger)<\/li>\n  <li>Zoner er gener\u00f8st dimensioneret, m\u00e5linger\/logfiler er tilg\u00e6ngelige<\/li>\n  <li>hastighed\/burst tilpasset pr. sti-klasse, nodelay bevidst indstillet<\/li>\n  <li>Testet med dry-run, 429-kommunikation (Retry-After) implementeret<\/li>\n  <li>Undtagelser for Health\/Webhooks, kombination med limit_conn<\/li>\n  <li>Iterativ genfokusering og alarmering ved afvigelser<\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Find ud af, hvordan du med NGINX Rate Limiting kan beskytte din hjemmeside mod bot-trafik og angreb og dermed \u00f8ge webserverens sikkerhed. Inkluderer praktiske eksempler og bedste praksis.<\/p>","protected":false},"author":1,"featured_media":21248,"comment_status":"","ping_status":"","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[834],"tags":[],"class_list":["post-21255","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-plesk-webserver-plesk-administration-anleitungen"],"acf":[],"_wp_attached_file":null,"_wp_attachment_metadata":null,"litespeed-optimize-size":null,"litespeed-optimize-set":null,"_elementor_source_image_hash":null,"_wp_attachment_image_alt":null,"stockpack_author_name":null,"stockpack_author_url":null,"stockpack_provider":null,"stockpack_image_url":null,"stockpack_license":null,"stockpack_license_url":null,"stockpack_modification":null,"color":null,"original_id":null,"original_url":null,"original_link":null,"unsplash_location":null,"unsplash_sponsor":null,"unsplash_exif":null,"unsplash_attachment_metadata":null,"_elementor_is_screenshot":null,"surfer_file_name":null,"surfer_file_original_url":null,"envato_tk_source_kit":null,"envato_tk_source_index":null,"envato_tk_manifest":null,"envato_tk_folder_name":null,"envato_tk_builder":null,"envato_elements_download_event":null,"_menu_item_type":null,"_menu_item_menu_item_parent":null,"_menu_item_object_id":null,"_menu_item_object":null,"_menu_item_target":null,"_menu_item_classes":null,"_menu_item_xfn":null,"_menu_item_url":null,"_trp_menu_languages":null,"rank_math_primary_category":null,"rank_math_title":null,"inline_featured_image":null,"_yoast_wpseo_primary_category":null,"rank_math_schema_blogposting":null,"rank_math_schema_videoobject":null,"_oembed_049c719bc4a9f89deaead66a7da9fddc":null,"_oembed_time_049c719bc4a9f89deaead66a7da9fddc":null,"_yoast_wpseo_focuskw":null,"_yoast_wpseo_linkdex":null,"_oembed_27e3473bf8bec795fbeb3a9d38489348":null,"_oembed_c3b0f6959478faf92a1f343d8f96b19e":null,"_trp_translated_slug_en_us":null,"_wp_desired_post_slug":null,"_yoast_wpseo_title":null,"tldname":null,"tldpreis":null,"tldrubrik":null,"tldpolicylink":null,"tldsize":null,"tldregistrierungsdauer":null,"tldtransfer":null,"tldwhoisprivacy":null,"tldregistrarchange":null,"tldregistrantchange":null,"tldwhoisupdate":null,"tldnameserverupdate":null,"tlddeletesofort":null,"tlddeleteexpire":null,"tldumlaute":null,"tldrestore":null,"tldsubcategory":null,"tldbildname":null,"tldbildurl":null,"tldclean":null,"tldcategory":null,"tldpolicy":null,"tldbesonderheiten":null,"tld_bedeutung":null,"_oembed_d167040d816d8f94c072940c8009f5f8":null,"_oembed_b0a0fa59ef14f8870da2c63f2027d064":null,"_oembed_4792fa4dfb2a8f09ab950a73b7f313ba":null,"_oembed_33ceb1fe54a8ab775d9410abf699878d":null,"_oembed_fd7014d14d919b45ec004937c0db9335":null,"_oembed_21a029d076783ec3e8042698c351bd7e":null,"_oembed_be5ea8a0c7b18e658f08cc571a909452":null,"_oembed_a9ca7a298b19f9b48ec5914e010294d2":null,"_oembed_f8db6b27d08a2bb1f920e7647808899a":null,"_oembed_168ebde5096e77d8a89326519af9e022":null,"_oembed_cdb76f1b345b42743edfe25481b6f98f":null,"_oembed_87b0613611ae54e86e8864265404b0a1":null,"_oembed_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_oembed_time_27aa0e5cf3f1bb4bc416a4641a5ac273":null,"_tldname":null,"_tldclean":null,"_tldpreis":null,"_tldcategory":null,"_tldsubcategory":null,"_tldpolicy":null,"_tldpolicylink":null,"_tldsize":null,"_tldregistrierungsdauer":null,"_tldtransfer":null,"_tldwhoisprivacy":null,"_tldregistrarchange":null,"_tldregistrantchange":null,"_tldwhoisupdate":null,"_tldnameserverupdate":null,"_tlddeletesofort":null,"_tlddeleteexpire":null,"_tldumlaute":null,"_tldrestore":null,"_tldbildname":null,"_tldbildurl":null,"_tld_bedeutung":null,"_tldbesonderheiten":null,"_oembed_ad96e4112edb9f8ffa35731d4098bc6b":null,"_oembed_8357e2b8a2575c74ed5978f262a10126":null,"_oembed_3d5fea5103dd0d22ec5d6a33eff7f863":null,"_eael_widget_elements":null,"_oembed_0d8a206f09633e3d62b95a15a4dd0487":null,"_oembed_time_0d8a206f09633e3d62b95a15a4dd0487":null,"_aioseo_description":null,"_eb_attr":null,"_eb_data_table":null,"_oembed_819a879e7da16dd629cfd15a97334c8a":null,"_oembed_time_819a879e7da16dd629cfd15a97334c8a":null,"_acf_changed":null,"_wpcode_auto_insert":null,"_edit_last":null,"_edit_lock":null,"_oembed_e7b913c6c84084ed9702cb4feb012ddd":null,"_oembed_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_time_bfde9e10f59a17b85fc8917fa7edf782":null,"_oembed_03514b67990db061d7c4672de26dc514":null,"_oembed_time_03514b67990db061d7c4672de26dc514":null,"rank_math_news_sitemap_robots":null,"rank_math_robots":null,"_eael_post_view_count":"65","_trp_automatically_translated_slug_ru_ru":null,"_trp_automatically_translated_slug_et":null,"_trp_automatically_translated_slug_lv":null,"_trp_automatically_translated_slug_fr_fr":null,"_trp_automatically_translated_slug_en_us":null,"_wp_old_slug":null,"_trp_automatically_translated_slug_da_dk":null,"_trp_automatically_translated_slug_pl_pl":null,"_trp_automatically_translated_slug_es_es":null,"_trp_automatically_translated_slug_hu_hu":null,"_trp_automatically_translated_slug_fi":null,"_trp_automatically_translated_slug_ja":null,"_trp_automatically_translated_slug_lt_lt":null,"_elementor_edit_mode":null,"_elementor_template_type":null,"_elementor_version":null,"_elementor_pro_version":null,"_wp_page_template":null,"_elementor_page_settings":null,"_elementor_data":null,"_elementor_css":null,"_elementor_conditions":null,"_happyaddons_elements_cache":null,"_oembed_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_time_75446120c39305f0da0ccd147f6de9cb":null,"_oembed_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_time_3efb2c3e76a18143e7207993a2a6939a":null,"_oembed_59808117857ddf57e478a31d79f76e4d":null,"_oembed_time_59808117857ddf57e478a31d79f76e4d":null,"_oembed_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_time_965c5b49aa8d22ce37dfb3bde0268600":null,"_oembed_81002f7ee3604f645db4ebcfd1912acf":null,"_oembed_time_81002f7ee3604f645db4ebcfd1912acf":null,"_elementor_screenshot":null,"_oembed_7ea3429961cf98fa85da9747683af827":null,"_oembed_time_7ea3429961cf98fa85da9747683af827":null,"_elementor_controls_usage":null,"_elementor_page_assets":[],"_elementor_screenshot_failed":null,"theplus_transient_widgets":null,"_eael_custom_js":null,"_wp_old_date":null,"_trp_automatically_translated_slug_it_it":null,"_trp_automatically_translated_slug_pt_pt":null,"_trp_automatically_translated_slug_zh_cn":null,"_trp_automatically_translated_slug_nl_nl":null,"_trp_automatically_translated_slug_pt_br":null,"_trp_automatically_translated_slug_sv_se":null,"rank_math_analytic_object_id":null,"rank_math_internal_links_processed":"1","_trp_automatically_translated_slug_ro_ro":null,"_trp_automatically_translated_slug_sk_sk":null,"_trp_automatically_translated_slug_bg_bg":null,"_trp_automatically_translated_slug_sl_si":null,"litespeed_vpi_list":null,"litespeed_vpi_list_mobile":null,"rank_math_seo_score":null,"rank_math_contentai_score":null,"ilj_limitincominglinks":null,"ilj_maxincominglinks":null,"ilj_limitoutgoinglinks":null,"ilj_maxoutgoinglinks":null,"ilj_limitlinksperparagraph":null,"ilj_linksperparagraph":null,"ilj_blacklistdefinition":null,"ilj_linkdefinition":null,"_eb_reusable_block_ids":null,"rank_math_focus_keyword":"NGINX Rate","rank_math_og_content_image":null,"_yoast_wpseo_metadesc":null,"_yoast_wpseo_content_score":null,"_yoast_wpseo_focuskeywords":null,"_yoast_wpseo_keywordsynonyms":null,"_yoast_wpseo_estimated-reading-time-minutes":null,"rank_math_description":null,"surfer_last_post_update":null,"surfer_last_post_update_direction":null,"surfer_keywords":null,"surfer_location":null,"surfer_draft_id":null,"surfer_permalink_hash":null,"surfer_scrape_ready":null,"_thumbnail_id":"21248","footnotes":null,"_links":{"self":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/21255","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/comments?post=21255"}],"version-history":[{"count":0,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/posts\/21255\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media\/21248"}],"wp:attachment":[{"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/media?parent=21255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/categories?post=21255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/webhosting.de\/da\/wp-json\/wp\/v2\/tags?post=21255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}