Procédure

Protéger une API par rate limiting

Déployer un rate limiting API sans bloquer les clients légitimes : métriques de référence, clé pertinente, dry-run NGINX, burst, code 429, tests et observabilité.

⌚ Environ 6 min de lecture
Voir mes favoris
DomaineApplications & APINiveauAvancéDurée45-120 minRisqueMoyen

Objectif

Limiter les abus, boucles clientes et pics de trafic sur une API en choisissant une clé de quota adaptée, en mesurant d’abord le trafic réel, en déployant progressivement la limitation et en distinguant clairement limitation de débit, authentification et protection anti-DDoS.

Prérequis

  • Trafic API mesuré : requêtes/s habituelles, pics, endpoints les plus sollicités et clients critiques.
  • Reverse proxy ou API gateway identifié et configuration versionnée.
  • Clé de quota choisie avec compréhension des proxies/NAT et de l’authentification.
  • Code de réponse attendu, généralement 429 pour Too Many Requests lorsque la plateforme le permet.
  • Plan de test avec client normal, rafale contrôlée et mécanisme de rollback.

Procédure pas à pas

1

Mesurer le trafic avant de fixer un seuil

Collectez au moins plusieurs périodes représentatives. Analysez p50/p95/p99 de requêtes par seconde par client et par endpoint, puis distinguez les appels interactifs des traitements batch. Un seuil raisonnable doit protéger la plateforme sans casser les clients légitimes. Documentez aussi les endpoints coûteux qui méritent un quota différent.

Résultat attendu
  • Le seuil proposé est dérivé de données réelles et non d’une valeur générique.
2

Choisir la bonne clé de limitation

Pour une API publique non authentifiée, l’IP peut être un premier signal. Pour une API authentifiée, une clé API, un tenant ou un identifiant de client est souvent plus juste. Si NGINX limite par IP, $binary_remote_addr économise de l’espace dans la zone. Derrière un load balancer, configurez d’abord l’adresse réelle de manière sûre.

Résultat attendu
  • La clé ne regroupe pas involontairement tous les utilisateurs derrière un même proxy.
3

Créer une zone NGINX en mode observation

Dans NGINX, limit_req_zone définit une zone mémoire et un taux. Commencez avec limit_req_dry_run on afin de compter les requêtes qui auraient été retardées ou rejetées sans les bloquer. Choisissez un nom de zone explicite et placez la directive au niveau http. Testez la configuration avant reload.

limit_req_zone $binary_remote_addr zone=api_per_ip:10m rate=10r/s;
nginx -t
Résultat attendu
  • La configuration est syntaxiquement valide et aucune requête n’est encore bloquée.
4

Appliquer le dry-run à l’endpoint pilote

Ajoutez limit_req sur un endpoint précis, avec un burst correspondant aux rafales légitimes. En dry-run, NGINX expose l’état via $limit_req_status et journalise les excès selon le niveau configuré. Ne commencez pas par toute l’API si les usages sont hétérogènes.

location /api/v1/ {
    limit_req zone=api_per_ip burst=20 nodelay;
    limit_req_dry_run on;
    limit_req_log_level notice;
    proxy_pass http://api_backend;
}
nginx -t && nginx -s reload
Résultat attendu
  • Le trafic continue normalement mais les excès potentiels deviennent mesurables.
5

Analyser les résultats dry-run

Pendant la période pilote, mesurez PASSED, DELAYED_DRY_RUN et REJECTED_DRY_RUN dans vos logs ou métriques. Identifiez les clients légitimes qui dépasseraient le seuil et déterminez pourquoi : batch prévu, retry agressif, client partagé ou bug. Ajustez rate/burst ou créez une classe de quota distincte plutôt que d’augmenter globalement le seuil.

Résultat attendu
  • Les faux positifs sont compris avant activation réelle.
6

Choisir burst, délai et code de rejet

burst autorise une file de requêtes excédentaires ; nodelay permet de consommer la rafale sans les étaler. Pour une API, choisissez selon le comportement du client et la latence acceptable. NGINX renvoie 503 par défaut lors d’un rejet ; définissez limit_req_status 429 si vous voulez un signal API standard et si vos clients savent gérer ce code.

limit_req_status 429;
Résultat attendu
  • La politique de rafale et le code de rejet sont documentés pour les développeurs clients.
7

Activer la limitation sur le périmètre pilote

Passez limit_req_dry_run à off uniquement après analyse. Rechargez NGINX sans arrêt brutal et surveillez immédiatement taux de 429, latence et erreurs backend. Les clients doivent appliquer un backoff raisonnable ; un retry instantané en boucle peut aggraver la saturation.

nginx -t
nginx -s reload
Résultat attendu
  • Le pilote limite réellement les excès sans hausse anormale d’erreurs métier.
8

Tester des scénarios contrôlés

Depuis un environnement de test, envoyez une cadence normale puis une rafale au-dessus du seuil. Vérifiez les codes HTTP et les logs. Testez aussi deux clients distincts afin de confirmer que la clé sépare bien leurs quotas. N’utilisez pas un test de charge massif contre la production.

for i in $(seq 1 40); do curl -s -o /dev/null -w '%{http_code}n' https://api.example.tld/api/v1/health; done
Résultat attendu
  • La cadence normale passe et la rafale produit les rejets attendus.
9

Étendre par endpoint et superviser

Déployez progressivement vers les autres routes. Les endpoints d’authentification, recherche lourde, export ou upload peuvent avoir des limites différentes. Ajoutez un dashboard 429, latence, backend 5xx et top clients limités. Révisez les seuils après changement d’usage ou montée en charge.

Résultat attendu
  • La limitation devient une politique observable et ajustable, pas une règle oubliée.

Validation

La procédure est validée lorsque :

  • Le seuil est basé sur des métriques et la clé de quota correspond à l’identité réelle du client.
  • Le dry-run a été observé avant activation et les clients légitimes critiques ont été testés.
  • Les rafales au-delà du seuil reçoivent le code attendu sans indisponibilité du backend.
  • Les métriques permettent de distinguer trafic normal, limitation et erreur applicative.

Retour arrière

  • Réactiver limit_req_dry_run on pour neutraliser les rejets tout en conservant les mesures.
  • Commenter ou retirer la directive limit_req de l’endpoint puis valider nginx -t avant reload.
  • Restaurer la configuration versionnée précédente si plusieurs zones ou clés ont été modifiées.
  • Conserver les logs des 429 afin d’ajuster le seuil après rollback.

Dépannage / erreurs fréquentes

  • Tous les utilisateurs sont limités ensemble : la clé utilise probablement l’IP du reverse proxy au lieu du client réel.
  • 429 sur un client batch légitime : créer une politique dédiée ou corriger sa cadence plutôt que supprimer toute protection.
  • Pas de logs de limitation : vérifier que la location réellement utilisée hérite de la directive attendue.
  • 503 au lieu de 429 : définir limit_req_status ou vérifier la configuration chargée.
  • La zone se remplit : dimensionner la mémoire et revoir la cardinalité de la clé.

Références officielles

♡ 0