Come impostare il limite di velocità in NGINX

La limitazione della velocità in NGINX è una funzionalità cruciale per controllare la quantità di traffico gestito dal tuo server. Aiuta a proteggere il tuo server dall'essere sopraffatto da troppe richieste in un breve periodo, che possono causare attacchi dannosi come DDoS o picchi di traffico elevati. L'implementazione della limitazione della velocità garantisce che le risorse vengano utilizzate in modo efficiente e che gli utenti legittimi possano accedere ai servizi senza interruzioni.

Questa guida mostrerà come configurare la limitazione della velocità in NGINX, fornendo istruzioni chiare per aiutarti a gestire e controllare il traffico in entrata in modo efficace.

Comprensione delle direttive sui limiti di velocità in NGINX

Direttive chiave sulla limitazione della velocità di NGINX

NGINX configura la limitazione della velocità utilizzando direttive specifiche, ciascuna con una funzione unica:

  • limit_req_zone: La direttiva limit_req_zone in NGINX imposta una zona di memoria condivisa per archiviare informazioni di limitazione della velocità. Posizionato nel contesto http, determina il tasso ammissibile di richieste, stabilendo di fatto la base per i limiti di velocità.
  • limite_req: La direttiva limit_req, utilizzata nel contesto della posizione, impone il limite di velocità impostato da limit_req_zone. Applica queste limitazioni a posizioni o URL specifici, controllando così la frequenza di accesso a questi endpoint.
  • limit_req_status: Posizionata nel contesto della posizione, la direttiva limit_req_status specifica il codice di stato HTTP restituito quando la frequenza delle richieste supera il limite. Questo meccanismo di feedback è fondamentale per informare gli utenti o i sistemi automatizzati quando superano la frequenza di richiesta consentita.

Creazione di una configurazione di limitazione della velocità

Per implementare la limitazione della velocità in NGINX, inserire le direttive appropriate nel file di configurazione NGINX. Considera questo esempio di base:

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

    server {
        ...
        location / {
            limit_req zone=mylimit burst=10;
            ...
        }
    }
}

In questa configurazione, la direttiva limit_req_zone stabilisce una zona di memoria denominata "mylimit", consentendo 5 richieste al secondo (5r/s) da ciascun indirizzo IP del client ($binary_remote_addr). La direttiva limit_req applica quindi questo limite di velocità alla posizione root (/), con una capacità di burst di 10 richieste, offrendo un equilibrio tra limitazione di velocità rigorosa e flessibilità per picchi di traffico legittimi.

Limite di velocità in NGINX: esempi pratici

Configurazione base della limitazione della velocità

Questa sezione esplorerà una configurazione di base di limitazione della velocità applicata a livello di server in NGINX. Lo scopo è limitare le richieste degli utenti al server, garantendo prestazioni stabili e mitigando il rischio di sovraccarico.

Esempio: limite di velocità a livello di server

Considera la seguente configurazione NGINX:

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=2r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_req zone=mylimit burst=5;
            proxy_pass http://backend;
        }
    }
}

Questa configurazione imposta un limite di 2 richieste al secondo per ciascun client, come definito dal relativo indirizzo IP ($binary_remote_addr). Analizziamo i componenti chiave:

  • limit_req_zone: Definisce una zona di memoria (mylimit) per la memorizzazione degli stati limite di velocità con una dimensione di 10 megabyte. Imposta il limite di velocità su 2 richieste al secondo (2r/s).
  • blocco del server: ascolta sulla porta 80 il traffico in entrata su example.com.
  • blocco di posizione: applica il limite di velocità all'URL principale (/). Il parametro burst consente un burst fino a 5 richieste, offrendo flessibilità per brevi picchi di traffico. La direttiva proxy_pass inoltra la richiesta al server backend specificato.
  • Parametro di scoppio: L'impostazione burst=5 nella direttiva limit_req consente un aumento a breve termine delle richieste, fino a 5 richieste aggiuntive oltre la velocità impostata. Questa funzionalità è fondamentale per gestire aumenti improvvisi e legittimi del traffico senza influire sull'esperienza dell'utente.
  • Passaggio per procura: Il proxy_pass http://backend; la direttiva inoltra il traffico a un server back-end. Questo è comunemente usato negli scenari di bilanciamento del carico o quando NGINX funge da proxy inverso.

Esempi di limitazione della velocità avanzata

Limiti di tariffa diversi per località diverse

Potrebbe essere necessario applicare limiti di velocità diversi a diverse parti dell'applicazione in scenari più complessi. Ciò è particolarmente utile quando endpoint specifici richiedono più risorse o sono soggetti ad abusi.

Considera la seguente configurazione:

http {
    limit_req_zone $binary_remote_addr zone=low:10m rate=1r/s;
    limit_req_zone $binary_remote_addr zone=high:10m rate=10r/s;

    server {
        listen 80;
        server_name example.com;

        location /api/low {
            limit_req zone=low burst=3;
            proxy_pass http://backend;
        }

        location /api/high {
            limit_req zone=high burst=20;
            proxy_pass http://backend;
        }
    }
}

Questa configurazione applica un limite di velocità inferiore (1 richiesta al secondo) alla posizione /api/low e un limite di velocità più alto (10 richieste al secondo) alla posizione /api/high.

Ulteriori esempi di limitazione della velocità di Nginx

Limitazione della velocità in base ai tipi di richiesta

È possibile configurare la limitazione della velocità in base a richieste specifiche, ad esempio richieste GET, POST o PUT. Ciò è particolarmente utile quando desideri proteggere endpoint specifici che sono più vulnerabili agli abusi o che hanno un impatto maggiore sulle risorse del tuo server.

È possibile utilizzare la direttiva if e la variabile $request_method per applicare la limitazione della velocità a tipi di richiesta specifici. Ecco un esempio:

http {
    limit_req_zone $binary_remote_addr zone=get_limit:10m rate=5r/s;
    limit_req_zone $binary_remote_addr zone=post_limit:10m rate=2r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($request_method = GET) {
                limit_req zone=get_limit burst=10;
            }

            if ($request_method = POST) {
                limit_req zone=post_limit burst=5;
            }

            proxy_pass http://backend;
        }
    }
}

In questa configurazione abbiamo impostato due limiti di velocità separati: uno per le richieste GET (5 richieste al secondo) e uno per le richieste POST (2 richieste al secondo).

Limitazione della velocità basata sullo user-agent

Un'altra tecnica utile consiste nell'applicare la limitazione della velocità in base all'intestazione User-Agent inviata dai client. Ciò può aiutarti a proteggere i tuoi servizi da bot o crawler specifici che causano problemi.

Per implementare la limitazione della velocità basata su User-Agent, è possibile utilizzare la direttiva map e la variabile $http_user_agent.

Ecco un esempio:

http {
    map $http_user_agent $limit_bots {
        default 0;
        ~*(Googlebot|Bingbot) 1;
    }

    limit_req_zone $binary_remote_addr zone=bot_limit:10m rate=1r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($limit_bots) {
                limit_req zone=bot_limit burst=2;
            }

            proxy_pass http://backend;
        }
    }
}

In questo esempio, abbiamo definito una direttiva mappa che imposta la variabile $limit_bots su 1 se l'intestazione User-Agent corrisponde a "Googlebot" o "Bingbot". Applichiamo quindi un limite di velocità di 1 richiesta al secondo alle richieste provenienti da questi bot.

Whitelist degli IP dalla limitazione della velocità

A volte potresti voler esentare indirizzi IP specifici, come partner fidati o servizi interni, dalla limitazione della velocità. Per raggiungere questo obiettivo, puoi utilizzare la direttiva geo, insieme a if direttiva.

Ecco un esempio:

http {
    geo $rate_limit {
        default 1;
        192.168.0.0/24 0;
        10.0.0.0/8 0;
    }

    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

    server {
        listen 80;
        server_name example.com;

        location / {
            if ($rate_limit) {
                limit_req zone=mylimit burst=10;
            }

            proxy_pass http://backend;
        }
    }
}

Limitazione della velocità di scalabilità in un ambiente distribuito

Quando più istanze Nginx sono in esecuzione in un ambiente distribuito, potresti voler garantire che la limitazione della velocità sia coerente in tutte le istanze. È possibile utilizzare un archivio dati centralizzato come Redis per gestire i limiti di velocità per raggiungere questo obiettivo. Ciò ti consente di mantenere un limite di velocità globale condiviso tra tutte le istanze Nginx.

Per impostare la limitazione della velocità con Redis, è necessario installare e configurare il modulo nginx-module-redis. Una volta installato il modulo, puoi aggiornare la configurazione di Nginx per utilizzare Redis per la limitazione della velocità.

Ecco un esempio:

load_module modules/ngx_http_redis_module.so;

http {
    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=5r/s;

    upstream redis_server {
        server 127.0.0.1:6379;
        keepalive 32;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_req_redis zone=mylimit burst=10 redis_server=redis_server;
            proxy_pass http://backend;
        }
    }
}

In questo esempio, abbiamo definito un blocco upstream per il server Redis e aggiornato il blocco location per utilizzare la direttiva limit_req_redis invece della direttiva limit_req standard. Questa configurazione garantisce che i limiti di velocità vengano applicati utilizzando l'archivio dati Redis condiviso, fornendo limiti di velocità coerenti su più istanze Nginx.

Limitazione della velocità dinamica

In alcune situazioni, potresti voler modificare i limiti di velocità in modo dinamico in base a determinate condizioni o al carico corrente sul tuo server. Ad esempio, potresti voler applicare limiti di velocità più severi durante le ore di punta del traffico per gestire meglio le risorse del server.

Per implementare la limitazione della velocità dinamica, è possibile utilizzare il file map direttiva volta a definire limiti tariffari sulla base di condizioni specifiche.

Ecco un esempio:

http {
    map $http_x_traffic $dynamic_rate {
        default "5r/s";
        high "2r/s";
    }

    limit_req_zone $binary_remote_addr zone=mylimit:10m rate=$dynamic_rate;

    server {
        listen 80;
        server_name example.com;

        location / {
            limit_req zone=mylimit burst=10;
            proxy_pass http://backend;
        }
    }
}

In questa configurazione, utilizziamo la variabile $http_x_traffic derivata da un'intestazione personalizzata X-Traffic. In base al valore di questa intestazione, impostiamo dinamicamente il limite di velocità. Quando il valore dell'intestazione è "alto", applichiamo un limite di velocità più rigido di 2 richieste al secondo. Altrimenti, utilizziamo la velocità predefinita di 5 richieste al secondo.

Tieni presente che questo esempio presuppone che il tuo server backend o un altro componente nella tua infrastruttura imposti l'intestazione X-Traffic in base alle condizioni desiderate.

Testare il limite di velocità nella configurazione NGINX

Verifica della limitazione della velocità con arricciatura

Utilizzo di curl per il test di richiesta semplice

Per convalidare l'efficacia della configurazione di limitazione della velocità in NGINX, curl, uno strumento da riga di comando per l'invio di richieste HTTP, si rivela estremamente utile. Può inviare rapidamente più richieste al tuo server, aiutandoti a valutare se i limiti di velocità sono attivi.

for i in {1..10}; do curl -I http://example.com; done
  • Questo comando invia 10 richieste HEAD al tuo server, indirizzate a http://example.com.
  • Analizza le intestazioni di risposta HTTP da queste richieste per verificare la funzionalità di limitazione della velocità.
  • NGINX dovrebbe restituire un codice di stato 429 Too Many Requests quando la frequenza delle richieste supera il limite specificato.

Test con Apache Bench (ab)

Benchmarking delle risposte del server con Apache Bench

Apache Bench (ab) è uno strumento di benchmarking efficace, ideale per testare i limiti di velocità simulando condizioni di traffico elevato. Aiuta a capire come si comporta il tuo server NGINX sotto un'ondata di richieste.

ab -n 100 -c 10 http://example.com/
  • Questo comando indica ad ab di inviare 100 richieste a http://example.com con un livello di concorrenza 10.
  • L'output di ab fornisce informazioni sull'efficacia della limitazione della velocità.
  • Concentrati sul numero di richieste non riuscite nell'output, che dovrebbe essere in linea con le impostazioni della tua configurazione di limitazione della velocità NGINX.

L'utilizzo dei metodi migliori per testare la configurazione NGINX garantisce che le regole di limitazione della velocità funzionino come previsto.

Conclusione

Configurando la limitazione della velocità in NGINX, puoi proteggere il tuo server da traffico eccessivo e potenziali abusi. Ciò aiuta a mantenere le prestazioni e la disponibilità dei tuoi servizi, garantendo un'esperienza migliore per gli utenti legittimi. Monitora e modifica regolarmente le impostazioni di limitazione della velocità per bilanciare sicurezza e accessibilità. L'implementazione di questi controlli è fondamentale per gestire in modo efficiente le risorse del server.

Joshua James
Seguimi
Ultimi post di Joshua James (vedi tutto)

Lascia un commento