Blocs de localisation Nginx expliqués : routage du trafic web

Les blocs de localisation Nginx sont la colonne vertébrale d'un routage efficace du trafic web. Ce guide complet détaille les cinq différents modificateurs de correspondance (préfixe, exact, préfixe le plus long, regex) et explique l'ordre de traitement strict que Nginx suit. Apprenez à router avec précision les ressources statiques, à proxyfier les appels API et à implémenter des règles de sécurité à l'aide d'exemples de configuration pratiques. Maîtriser les blocs de localisation est essentiel pour un contrôle précis du trafic, garantissant des performances serveur rapides et une gestion de configuration robuste.

Blocs de localisation Nginx expliqués : routage du trafic web

Les blocs de localisation Nginx décident de ce qui se passe après qu'une requête arrive dans le bon bloc server. Ils sont la raison pour laquelle /static/app.css peut être servi depuis le disque, /api/users peut être proxyfié vers une application, et /.git/config peut être refusé avant de divulguer quelque chose de sensible.

La plupart des erreurs avec les blocs de localisation ne sont pas des erreurs de syntaxe. Ce sont des erreurs de priorité. Une regex intercepte une requête que vous attendiez d'un bloc de préfixe. Un chemin root ajoute plus d'URI que vous ne le pensiez. Un proxy_pass avec une barre oblique finale réécrit l'URI amont différemment que la même directive sans celle-ci. Les exemples ci-dessous se concentrent sur ces points de défaillance réels.

Le rôle et l'anatomie d'un bloc de localisation

Un bloc location définit comment Nginx doit répondre aux requêtes en fonction de l'URI de requête (Uniform Resource Identifier). Ces blocs sont toujours imbriqués dans un bloc server.

Lorsqu'un client effectue une requête (par exemple, GET /images/logo.png), Nginx vérifie l'URI de la requête par rapport à tous les blocs de localisation définis dans le bloc server d'écoute pour déterminer le traitement approprié, comme servir un fichier, rediriger le client ou proxyfier la requête vers un serveur d'application.

Syntaxe de base

La syntaxe nécessite un modificateur (ou son absence) suivi d'un motif (URI) :

location [modifier] [pattern] {
    # Directives de configuration (par exemple, root, index, proxy_pass)
}

Comprendre les types de correspondance de localisation (les modificateurs)

Nginx propose un petit ensemble de styles de correspondance de localisation. Le choix affecte à la fois la précision du routage et la quantité de travail que Nginx effectue avant de choisir un gestionnaire.

1. Correspondance de préfixe (aucun modificateur)

C'est le type de correspondance par défaut. Nginx recherche la chaîne de départ la plus longue qui correspond à l'URI de la requête.

Modificateur Exemple Comportement Meilleur cas d'utilisation
(aucun) location /blog/ Correspond aux URI commençant par /blog/ (par exemple, /blog/post/1). Usage général, définition de grandes sections d'un site.

Exemple :

location /docs/ {
    root /var/www/html/public;
    # Si l'URI est /docs/manual.pdf, Nginx cherche /var/www/html/public/docs/manual.pdf
}

2. Correspondance exacte (=)

Ce modificateur force une correspondance exacte entre l'URI et le motif. Si elle correspond, Nginx arrête immédiatement de chercher d'autres localisations. C'est le type de correspondance le plus rapide.

Modificateur Exemple Comportement Meilleur cas d'utilisation
= location = /favicon.ico Correspond uniquement à l'URI /favicon.ico exactement. Gestion de fichiers spécifiques fréquemment demandés ou de pages par défaut.

3. Préfixe le plus long, non-regex (^~)

C'est une correspondance de préfixe spécialisée. Si Nginx trouve la correspondance de préfixe la plus longue en utilisant ^~, il arrête immédiatement de vérifier tout bloc de localisation d'expression régulière (regex), les remplaçant effectivement.

Modificateur Exemple Comportement Meilleur cas d'utilisation
^~ location ^~ /assets/ Correspond aux URI commençant par /assets/ et empêche les correspondances regex plus lentes d'être vérifiées. Servir rapidement les ressources statiques et garantir que les répertoires de ressources sont gérés de manière prévisible.

4. Expression régulière sensible à la casse (~)

Cela utilise les expressions régulières compatibles Perl (PCRE) pour la correspondance. C'est puissant mais plus lent que les correspondances de préfixe. Le premier bloc regex correspondant gagne.

Modificateur Exemple Comportement Meilleur cas d'utilisation
~ location ~ \.php$ Correspond à toute URI se terminant par .php. Traitement spécifique de type de fichier (par exemple, passer les scripts PHP à PHP-FPM).

5. Expression régulière insensible à la casse (~*)

Identique à ~, mais la correspondance ignore la casse de l'URI.

Modificateur Exemple Comportement Meilleur cas d'utilisation
~* `location ~* .(jpg gif png)$`

L'ordre critique de traitement des localisations

Comprendre l'ordre dans lequel Nginx traite les blocs de localisation est essentiel pour éviter un comportement inattendu. Nginx ne lit pas simplement les fichiers de configuration de haut en bas. Il utilise une hiérarchie stricte :

  1. Correspondance exacte (=) : Nginx vérifie d'abord tous les blocs de correspondance exacte. Si une correspondance est trouvée, le traitement s'arrête immédiatement et la requête est gérée par ce bloc.
  2. Candidat de préfixe le plus long : Nginx trouve la localisation de préfixe correspondante la plus longue, y compris les localisations de préfixe simples et les localisations ^~.
  3. Saut de regex pour ^~ : Si cette meilleure correspondance de préfixe utilise ^~, Nginx l'utilise et ignore les vérifications regex.
  4. Expressions régulières (~ et ~*) : Si le meilleur préfixe n'était pas ^~, Nginx vérifie les localisations regex dans l'ordre où elles apparaissent dans le fichier de configuration. Le premier bloc regex correspondant gagne.
  5. Correspondance de préfixe standard la plus longue : Si aucune correspondance regex ne gagne, Nginx utilise le candidat de préfixe le plus long qu'il a déjà trouvé. Dans de nombreuses configurations, location / est le repli final.

C'est pourquoi ^~ /static/ est courant. Sans ^~, une regex ultérieure comme location ~* \.(css|js)$ peut encore gagner pour /static/app.css. Parfois, c'est acceptable. Parfois, cela contourne les en-têtes de cache, le chemin racine ou les règles d'accès que vous attendiez pour tout le répertoire /static/.

Scénarios de configuration pratiques

1. Prioriser les ressources statiques pour la performance

Pour garantir que Nginx sert les fichiers statiques directement et rapidement, empêchant les vérifications regex plus lentes et le traitement inutile par le serveur d'application, utilisez le modificateur ^~.

server {
    listen 80;
    server_name myapp.com;

    # 1. Correspondance exacte pour la page principale (priorité la plus élevée)
    location = / {
        proxy_pass http://backend_app_server;
    }

    # 2. Gestion rapide des ressources statiques, contournant les vérifications regex
    location ^~ /static/ {
        root /var/www/site;
        expires 30d;
    }

    # 3. Expression régulière pour les fichiers médias courants
    location ~* \.(gif|ico|css|js)$ {
        root /var/www/site;
        expires 7d;
    }

    # 4. Repli pour toutes les autres requêtes dynamiques
    location / {
        proxy_pass http://backend_app_server;
    }
}

2. Routage et proxyfication du trafic API

Lorsque vous utilisez Nginx comme proxy inverse, les blocs de localisation dirigent le trafic vers le serveur d'application amont correct.

location /api/v1/ {
    # Assurez-vous que Nginx respecte les paramètres de connexion client
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;

    # Achemine tout le trafic commençant par /api/v1/ vers le service backend
    proxy_pass http://api_backend_service/v1/;

    # Avec un URI dans proxy_pass, Nginx remplace le préfixe correspondant.
    # /api/v1/users devient /v1/users en amont.
}

Ce comportement de barre oblique finale mérite d'être testé. Ces deux exemples sont différents :

location /api/ {
    proxy_pass http://api_backend;
}

location /api/ {
    proxy_pass http://api_backend/;
}

La première forme transmet l'URI d'origine, y compris /api/..., à l'amont. La deuxième forme remplace le préfixe /api/ correspondant par /. Si votre amont commence soudainement à renvoyer des 404 après une petite modification de configuration, vérifiez cela avant de blâmer l'application.

3. Protéger les répertoires sensibles

Les blocs de localisation peuvent être utilisés pour refuser l'accès externe aux répertoires internes sensibles, tels que les fichiers de configuration ou les répertoires cachés comme .git.

# Refuser l'accès aux fichiers commençant par un point (fichiers cachés)
location ~ /\.(ht|svn|git) {
    deny all;
    return 404; # Renvoyer 404 au lieu de 403 pour éviter de révéler leur existence
}

# Refuser l'accès aux répertoires de configuration spécifiques
location /app/config/ {
    deny all;
}

Pour les fichiers cachés, de nombreuses équipes utilisent une règle de refus plus large :

location ~ /\.(?!well-known/) {
    deny all;
    return 404;
}

L'exception maintient /.well-known/ disponible pour des choses comme les défis de certificat ACME HTTP-01 tout en bloquant la plupart des dotfiles. Testez cela attentivement si votre site sert d'autres chemins légitimes préfixés par un point.

Avertissement de sécurité : Utilisation de alias vs. root

Lors de la configuration des chemins de fichiers dans un bloc de localisation, soyez conscient de la différence entre root et alias.

  • root : Ajoute l'URI de requête complet au chemin défini. (par exemple, location /images/ + root /data/ conduit à /data/images/filename.jpg)
  • alias : Remplace la partie correspondante de l'URI par le chemin défini. Cela est souvent nécessaire lorsque le bloc de localisation utilise une regex ou doit supprimer une partie du chemin avant de servir le fichier. (par exemple, location /static/ + alias /opt/app/files/ conduit à /opt/app/files/filename.jpg)

4. Gestion des barres obliques finales et des redirections

Il est souvent souhaitable d'appliquer une structure d'URL cohérente, par exemple en s'assurant que les répertoires se terminent toujours par une barre oblique (/).

# Forcer une barre oblique finale pour les chemins de répertoire si manquante
location ~* /[a-z0-9\-_]+$ {
    # Si l'URI correspond à un fichier, Nginx essaiera de le servir. Sinon, traitez-le comme un répertoire.
    # Vérifiez si l'URI demandée correspond à un répertoire sur le disque :
    if (-d $request_filename) {
        return 301 $uri/;
    }
}

Une bonne façon de déboguer le routage des localisations

Lorsqu'une requête arrive au mauvais endroit, réduisez le problème à une URL et un bloc server. Exécutez nginx -T pour voir la configuration complète rendue, y compris les fichiers inclus, puis recherchez chaque localisation qui pourrait correspondre à cette URI. Portez une attention particulière aux blocs regex car leur ordre dans le fichier est important.

Pour les fichiers statiques, confirmez le chemin du système de fichiers que Nginx construira à partir de root ou alias. Pour les requêtes proxyfiées, confirmez si proxy_pass inclut une partie URI après le nom amont. Rechargez ensuite uniquement après que nginx -t réussisse.

Les blocs de localisation sont prévisibles une fois que vous internalisez les règles de priorité, mais ils sont impitoyables lorsqu'une configuration grandit par copier-coller. Utilisez des correspondances exactes pour les petits chemins chauds, ^~ pour les répertoires qui doivent contourner le traitement regex, regex uniquement là où la correspondance de motif est réellement nécessaire, et un simple location / comme repli clair.