Aller au contenu
English
Compte : non connecté, synchronisation possible Mon apprentissage
Selectionner le thème
English

Protéger et observer Nginx : limit_req, authentification, en-têtes, journaux JSON et stub_status

Par mis à jour le

Améliorer cette page

Logo NGINX

Protéger un Nginx qui publie une application consiste à fermer ce qui n'a pas à être joignable, à limiter ce qui l'est, puis à rendre visible ce qui passe : authentification sur l'administration, refus des fichiers cachés et des méthodes inutiles, limitation de débit, en-têtes de sécurité, journaux JSON et compteurs. Cette leçon prolonge la publication avec Nginx : elle reprend les gestes de protection de la formation dans la syntaxe de Nginx, et ne pose que le minimum pour la limitation de débit et l'observation. Le dimensionnement des limites, l'observation complète et le diagnostic ont chacun leur leçon, citée à l'endroit où elle prend le relais.

La leçon va du plus restrictif au plus informatif : refuser, limiter, annoncer, puis observer.

  • Authentifier l'accès à une route d'administration.
  • Refuser les fichiers cachés et les méthodes d'écriture inutiles.
  • Limiter le débit avec limit_req.
  • Ajouter des en-têtes de sécurité aux réponses.
  • Produire des journaux JSON et exposer stub_status en local.

Cette leçon suppose que vous savez publier une application avec Nginx.

Exigez une authentification sur la route, et ne l'exposez que si elle doit l'être. Une route /admin laissée sans protection figure parmi les chemins que les scanners essaient d'abord. Nginx propose deux mécanismes : auth_basic, qui compare des identifiants à un fichier de mots de passe hachés, et auth_request, qui délègue la décision à un service d'authentification par une sous-requête.

location /admin {
auth_basic "Administration";
auth_basic_user_file /etc/nginx/.htpasswd;
proxy_pass http://127.0.0.1:8080;
}

auth_basic suffit pour un accès simple, à condition de passer par HTTPS : les identifiants circulent encodés, pas chiffrés. auth_request convient quand l'authentification est déjà portée par un autre service ; le service répond 2xx pour autoriser et 401 ou 403 pour refuser. Le module correspondant est présent dans les paquets officiels, mais pas dans toute compilation : vérifiez avec nginx -V.

Refusez les fichiers cachés et les méthodes dont l'application n'a pas besoin. Un fichier dont le nom commence par un point (.git, .env) peut contenir des secrets, et un proxy qui le sert transmet la fuite. Une méthode d'écriture sur une application en lecture seule n'a aucune raison de passer.

location ~ /\. {
deny all;
}
if ($request_method !~ ^(GET|HEAD|POST)$) {
return 405;
}

Le premier bloc répond 403 à tout chemin contenant un fichier caché. Le second refuse par 405 les méthodes qui ne sont pas listées. Adaptez la liste à l'application : un refus trop large casse les requêtes normales, et c'est précisément ce que vous devez vérifier avec curl après le changement. Le motif /\. bloque aussi /.well-known/, où les autorités ACME viennent lire le défi HTTP-01 : si ce serveur obtient ses certificats par ce défi, ajoutez un location ^~ /.well-known/ qui l'autorise, car le préfixe ^~ passe avant l'expression régulière.

limit_req ralentit ou refuse les clients qui dépassent un débit fixé, par adresse. Elle se règle en deux temps : limit_req_zone, au niveau http, déclare la zone mémoire, la clé de comptage et le débit ; limit_req, dans un location, applique la zone avec une tolérance de rafale.

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
server {
location / {
limit_req zone=api burst=20 nodelay;
limit_req_status 429;
proxy_pass http://127.0.0.1:8080;
}
}

Ici, chaque adresse peut envoyer dix requêtes par seconde, avec une rafale de vingt acceptée sans délai ; au-delà, Nginx répond 429. Par défaut le code de refus est 503 : limit_req_status le rend lisible pour les clients et pour les journaux. Derrière un autre relais, la clé $binary_remote_addr désigne l'adresse du relais, pas celle du client : la clé doit correspondre à ce que vous voulez réellement limiter.

Ceci est le cas minimal. Le dimensionnement de rate et de burst, la limitation des connexions simultanées, la taille des corps et le choix d'une clé qu'un client ne peut pas forger sont traités dans Nginx limites.

Ajoutez des en-têtes qui réduisent la surface d'attaque côté navigateur, avec le paramètre always pour qu'ils figurent aussi sur les réponses d'erreur. Sans always, Nginx n'ajoute l'en-tête que sur les codes de succès et de redirection.

add_header X-Content-Type-Options "nosniff" always;
add_header X-Frame-Options "DENY" always;
add_header Referrer-Policy "no-referrer" always;
add_header Strict-Transport-Security "max-age=31536000" always;

Un point de piège : add_header n'est pas hérité d'un niveau à l'autre dès qu'un niveau inférieur en déclare un. Si un location ajoute son propre en-tête, il perd ceux du server. Vérifiez donc les en-têtes réellement reçus avec curl -I, pas ceux que vous croyez avoir configurés.

Deux sources suffisent pour commencer : un journal d'accès structuré et les compteurs de stub_status. Un journal en JSON se filtre et s'agrège sans analyse de texte, et les compteurs donnent la charge instantanée.

log_format json_acces escape=json
'{"heure":"$time_iso8601","client":"$remote_addr",'
'"methode":"$request_method","uri":"$uri","code":$status,'
'"duree":$request_time}';
access_log /var/log/nginx/acces.json json_acces;
server {
listen 127.0.0.1:8081;
location /stub_status {
stub_status;
}
}

escape=json protège le format contre les caractères spéciaux d'une adresse. stub_status n'expose que des compteurs globaux : connexions actives, requêtes acceptées et traitées. Il ne détaille ni les codes de réponse ni les temps par route, qu'il faut lire dans le journal. Gardez ce point d'accès sur l'interface locale, comme ci-dessus : il révèle le volume de trafic et n'a pas à être joignable de l'extérieur.

Ce cas minimal s'arrête là. Les champs de temps qui séparent la lenteur de Nginx de celle de l'application, l'exportateur de métriques et les alertes sont l'objet de Observer Nginx. Quand une réponse 403, 502 ou 504 surgit malgré tout, la démarche de diagnostic est dans Diagnostiquer Nginx.

Mettre en pratique : protéger une application avec Nginx

Section intitulée « Mettre en pratique : protéger une application avec Nginx »

Le lab part d'un Nginx qui publie déjà l'application, mais qui accepte les requêtes d'administration sans protection, sert les fichiers cachés et transmet des méthodes dont l'application n'a pas besoin. Il vous demande d'ajouter les en-têtes de sécurité, d'exiger les identifiants fournis sur /admin, de refuser les fichiers cachés et de bloquer les méthodes d'écriture inutiles sans casser les requêtes normales de l'application. La validation est un contrôle automatisé qui vérifie ces refus et le maintien des requêtes légitimes. La mise en pratique de l'observation (journal JSON, stub_status, corrélation avec l'amont) se fait dans la leçon Observer Nginx.

Protéger, c'est refuser le superflu puis prouver le résultat avec curl.

  • auth_basic ou auth_request protègent l'administration.
  • Refusez les fichiers cachés et les méthodes inutiles.
  • limit_req limite par clé, et limit_req_status choisit le code.
  • add_header ... always couvre aussi les erreurs, mais n'est pas hérité librement.
  • Un journal JSON et stub_status local rendent Nginx observable.

Contrôle de connaissances

Validez vos connaissances avec ce quiz interactif

8 questions
8 min.
70% requis

Informations

  • Le chronomètre démarre au clic sur Démarrer
  • Questions à choix multiples, vrai/faux et réponses courtes
  • Vous pouvez naviguer entre les questions
  • Les résultats détaillés sont affichés à la fin

Lance le quiz et démarre le chronomètre

Ce projet vous est utile ?

Les guides, formations, quiz et labs restent gratuits. Si vous les utilisez régulièrement, vous pouvez contribuer à leur maintenance et à leur développement.

Devenir membre de soutien (nouvel onglet) Soutenir une fois (nouvel onglet) En savoir plus

Suivez aussi le projet sur LinkedIn