Comment évaluer la limite dans NGINX

La limitation de débit dans NGINX est une fonctionnalité cruciale pour contrôler la quantité de trafic gérée par votre serveur. Cela aide à protéger votre serveur contre une surcharge de requêtes sur une courte période, que peuvent provoquer des attaques malveillantes telles que DDoS ou des pics de trafic élevés. La mise en œuvre d'une limitation de débit garantit que vos ressources sont utilisées efficacement et que les utilisateurs légitimes peuvent accéder à vos services sans interruption.

Ce guide montrera comment configurer la limitation de débit dans NGINX, en fournissant des instructions claires pour vous aider à gérer et contrôler efficacement le trafic entrant.

Comprendre les directives de limite de débit dans NGINX

Directives clés de limitation de débit NGINX

NGINX configure la limitation de débit à l'aide de directives spécifiques, chacune remplissant une fonction unique :

  • limit_req_zone : La directive limit_req_zone dans NGINX configure une zone de mémoire partagée pour stocker les informations de limitation de débit. Positionné dans le contexte http, il détermine le taux de requêtes autorisé, définissant ainsi la référence pour les limites de débit.
  • limite_req : La directive limit_req, utilisée dans le contexte de localisation, applique la limite de débit définie par limit_req_zone. Il applique ces limitations à des emplacements ou des URL spécifiques, contrôlant ainsi la fréquence d'accès à ces points de terminaison.
  • limit_req_status : Positionnée dans le contexte de localisation, la directive limit_req_status spécifie le code d'état HTTP renvoyé lorsque le taux de requêtes dépasse la limite. Ce mécanisme de retour d'information est crucial pour informer les utilisateurs ou les systèmes automatisés lorsqu'ils dépassent la fréquence de requête autorisée.

Création d'une configuration de limitation de débit

Pour implémenter la limitation de débit dans NGINX, insérez les directives appropriées dans le fichier de configuration NGINX. Considérez cet exemple de base :

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

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

Dans cette configuration, la directive limit_req_zone établit une zone mémoire nommée 'mylimit', autorisant 5 requêtes par seconde (5r/s) depuis chaque adresse IP client ($binary_remote_addr). La directive limit_req applique ensuite cette limite de débit à l'emplacement racine (/), avec une capacité de rafale de 10 requêtes, offrant un équilibre entre une limitation stricte du débit et une flexibilité pour les pics de trafic légitimes.

Limite de débit dans NGINX : exemples pratiques

Configuration de base de limitation de débit

Cette section explorera une configuration de base de limitation de débit appliquée à l'ensemble du serveur dans NGINX. L'objectif est de limiter les requêtes des utilisateurs au serveur, garantissant des performances stables et atténuant le risque de surcharge.

Exemple : limite de débit à l'échelle du serveur

Considérez la configuration NGINX suivante :

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;
        }
    }
}

Cette configuration définit une limite de 2 requêtes par seconde pour chaque client, telle que définie par son adresse IP ($binary_remote_addr). Décomposons les éléments clés :

  • limite_req_zone: Définit une zone mémoire (mylimit) pour stocker les états limites de débit d'une taille de 10 Mo. Il fixe la limite de débit à 2 requêtes par seconde (2r/s).
  • bloc de serveur: écoute sur le port 80 le trafic entrant vers example.com.
  • bloc de localisation: applique la limite de débit à l'URL racine (/). Le paramètre burst permet une rafale allant jusqu'à 5 requêtes, offrant ainsi une flexibilité pour de courts pics de trafic. La directive proxy_pass transmet la demande au serveur backend spécifié.
  • Paramètre de rafale: Le paramètre burst=5 dans la directive limit_req permet une augmentation à court terme des requêtes, jusqu'à 5 requêtes supplémentaires au-dessus du débit défini. Cette fonctionnalité est cruciale pour gérer les augmentations soudaines et légitimes du trafic sans impacter l’expérience utilisateur.
  • Passe par procuration: Le proxy_pass http://backend; La directive transfère le trafic vers un serveur backend. Ceci est couramment utilisé dans les scénarios d'équilibrage de charge ou lorsque NGINX agit comme proxy inverse.

Exemples de limitation de débit avancée

Différentes limites de taux pour différents emplacements

Vous devrez peut-être appliquer différentes limites de débit à différentes parties de l'application dans des scénarios plus complexes. Ceci est particulièrement utile lorsque des points de terminaison spécifiques sont plus gourmands en ressources ou sujets à des abus.

Considérez la configuration suivante :

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;
        }
    }
}

Cette configuration applique une limite de débit inférieure (1 requête par seconde) à l'emplacement /api/low et une limite de débit plus élevée (10 requêtes par seconde) à l'emplacement /api/high.

Exemples supplémentaires de limitation de débit Nginx

Limitation du débit en fonction des types de demandes

Vous pouvez configurer une limitation de débit en fonction de requêtes spécifiques, telles que les requêtes GET, POST ou PUT. Ceci est particulièrement utile lorsque vous souhaitez protéger des points de terminaison spécifiques qui sont plus vulnérables aux abus ou qui ont un impact plus important sur les ressources de votre serveur.

Vous pouvez utiliser la directive if et la variable $request_method pour appliquer une limitation de débit à des types de requêtes spécifiques. Voici un exemple :

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;
        }
    }
}

Dans cette configuration, nous avons défini deux limites de débit distinctes : une pour les requêtes GET (5 requêtes par seconde) et une pour les requêtes POST (2 requêtes par seconde).

Limitation du débit basée sur l'agent utilisateur

Une autre technique utile consiste à appliquer une limitation de débit basée sur l’en-tête User-Agent envoyé par les clients. Cela peut aider à protéger vos services contre des robots ou des robots d'exploration spécifiques qui causent des problèmes.

Pour implémenter une limitation de débit basée sur User-Agent, vous pouvez utiliser la directive map et la variable $http_user_agent.

Voici un exemple :

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;
        }
    }
}

Dans cet exemple, nous avons défini une directive map qui définit la variable $limit_bots sur 1 si l'en-tête User-Agent correspond à « Googlebot » ou « Bingbot ». Nous appliquons ensuite une limite de débit de 1 requête par seconde aux requêtes de ces robots.

Liste blanche des adresses IP à partir de la limitation de débit

Parfois, vous souhaiterez peut-être exempter des adresses IP spécifiques, telles que des partenaires de confiance ou des services internes, de la limitation de débit. Pour y parvenir, vous pouvez utiliser la directive geo, ainsi que la if directif.

Voici un exemple :

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;
        }
    }
}

Limitation du débit de mise à l'échelle dans un environnement distribué

Lorsque plusieurs instances Nginx s'exécutent dans un environnement distribué, vous souhaiterez peut-être vous assurer que la limitation de débit est cohérente sur toutes les instances. Vous pouvez utiliser un magasin de données centralisé tel que Redis pour gérer les limites de débit afin d'y parvenir. Cela vous permet de maintenir une limite de débit globale partagée entre toutes les instances Nginx.

Pour configurer la limitation de débit avec Redis, vous devez installer et configurer le module nginx-module-redis. Une fois que vous avez installé le module, vous pouvez mettre à jour votre configuration Nginx pour utiliser Redis pour limiter le débit.

Voici un exemple :

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;
        }
    }
}

Dans cet exemple, nous avons défini un bloc en amont pour le serveur Redis et mis à jour le bloc d'emplacement pour utiliser la directive limit_req_redis au lieu de la directive limit_req standard. Cette configuration garantit que les limites de débit sont appliquées à l'aide du magasin de données Redis partagé, fournissant une limitation de débit cohérente sur plusieurs instances Nginx.

Limitation de débit dynamique

Dans certaines situations, vous souhaiterez peut-être ajuster les limites de débit de manière dynamique en fonction de certaines conditions ou de la charge actuelle de votre serveur. Par exemple, vous souhaiterez peut-être appliquer des limites de débit plus strictes pendant les heures de pointe pour mieux gérer les ressources du serveur.

Pour implémenter une limitation de débit dynamique, vous pouvez utiliser le map directive visant à définir des limites de taux en fonction de conditions spécifiques.

Voici un exemple :

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;
        }
    }
}

Dans cette configuration, nous utilisons la variable $http_x_traffic dérivée d'un en-tête personnalisé X-Traffic. Sur la base de la valeur de cet en-tête, nous définissons dynamiquement la limite de débit. Lorsque la valeur de l'en-tête est « élevée », nous appliquons une limite de débit plus stricte de 2 requêtes par seconde. Sinon, nous utilisons le débit par défaut de 5 requêtes par seconde.

Notez que cet exemple suppose que votre serveur backend ou un autre composant de votre infrastructure définit l'en-tête X-Traffic en fonction des conditions souhaitées.

Tester votre limite de débit dans la configuration NGINX

Vérification de la limitation de débit avec curl

Utiliser curl pour les tests de requêtes simples

Pour valider l'efficacité de votre configuration de limitation de débit dans NGINX, curl, un outil de ligne de commande pour envoyer des requêtes HTTP, s'avère très utile. Il peut envoyer rapidement plusieurs requêtes à votre serveur, vous aidant ainsi à évaluer si les limites de débit sont actives.

for i in {1..10}; do curl -I http://example.com; done
  • Cette commande émet 10 requêtes HEAD vers votre serveur, ciblant http://example.com.
  • Analysez les en-têtes de réponse HTTP de ces requêtes pour vérifier la fonctionnalité de limitation de débit.
  • NGINX devrait renvoyer un code d'état 429 Too Many Requests lorsque le taux de requêtes dépasse votre limite spécifiée.

Tests avec Apache Bench (ab)

Analyse comparative des réponses du serveur avec Apache Bench

Apache Bench (ab) est un outil d'analyse comparative efficace, idéal pour tester les limites de débit en simulant des conditions de trafic élevé. Cela permet de comprendre comment votre serveur NGINX se comporte face à une vague de requêtes.

ab -n 100 -c 10 http://example.com/
  • Cette commande demande à ab d'envoyer 100 requêtes à http://example.com avec un niveau de concurrence 10.
  • Le résultat de ab fournit un aperçu de l’efficacité de la limitation du débit.
  • Concentrez-vous sur le nombre de requêtes ayant échoué dans la sortie, qui doit correspondre aux paramètres de votre configuration de limitation de débit NGINX.

L'utilisation des meilleures méthodes pour tester votre configuration NGINX garantit que vos règles de limitation de débit fonctionnent comme prévu.

Conclusion

En configurant la limitation de débit dans NGINX, vous pouvez protéger votre serveur contre le trafic excessif et les abus potentiels. Cela permet de maintenir les performances et la disponibilité de vos services, garantissant une meilleure expérience aux utilisateurs légitimes. Surveillez et ajustez régulièrement vos paramètres de limitation de débit pour équilibrer sécurité et accessibilité. La mise en œuvre de ces contrôles est essentielle pour gérer efficacement les ressources de votre serveur.

Joshua James
Suis-moi
Les derniers articles par Joshua James (tout voir)

Laissez un commentaire