95 votes

Nginx - racine versus alias, pour servir des fichiers uniques?

Après de nombreuses heures à faire en sorte que nginx serve des fichiers individuels tels que robots.txt (astuce: videz le cache de votre navigateur à chaque fois), j'ai fini par trouver deux méthodes différentes, l'une utilisant la directive alias, et l'autre utilisant la directive root, comme ceci :

location /robots.txt { alias /home/www/static/robots.txt; }
location /robots.txt { root /home/www/static/;  }

Y a-t-il une différence fonctionnelle entre les deux ? Ou des problèmes de sécurité ? Des conflits avec d'autres directives ? (Les deux semblaient fonctionner correctement avec une autre localisation /static). Ou une raison de choisir l'une plutôt que l'autre ?

Remarque - Je n'ai pas utilisé les deux en même temps :) J'ai plutôt essayé chaque méthode, une par une, et les deux ont fonctionné. Je ne demande pas comment elles interagissent ensemble dans le même fichier, mais laquelle serait préférable à utiliser.

95voto

Alex Points 7759

Eh bien, ces deux directives sont légèrement différentes parce que vous n'utilisez pas de correspondance exacte dans le deuxième cas. Ainsi, /robots.txt1111 correspondra également à votre deuxième emplacement.
location =/robots.txt { root /home/www/static/; } est un équivalent fonctionnel exact de votre première directive.

0 votes

Bon point, merci. Mais vous pouvez utiliser un = dans les deux cas, n'est-ce pas? Ou s'applique-t-il uniquement à root? De plus, consultez ma modification - je ne voulais pas utiliser les deux en même temps. :)

0 votes

@Cyclops oui, vous pouvez utiliser = dans les deux cas.

0 votes

Donc ils seraient les mêmes - y a-t-il une raison de choisir une directive plutôt que l'autre ? Est ma question principale.

67voto

Hasan Karahan Points 551

Oui, il y a une différence : Avec "alias" tu peux... eh bien faire un alias vers un autre nom de fichier, comme

location /robots.txt { alias /home/www/static/any-filename.txt; }

tandis que

location /robots.txt { root /home/www/static/; }

vous oblige à nommer également votre fichier sur le serveur robots.txt. J'utilise la première option car j'aime nommer mes fichiers robots sur mon serveur sous la forme tld.domain.subdomain-robots.txt; par exemple

location /robots.txt { alias /home/www/static/ch.notex.static-robots.txt; }

8voto

kbolino Points 302

Je pense qu'il vaut la peine de préciser explicitement que nginx fonctionne sur des préfixes et non pas des fichiers en soi. Dans le premier cas,

location /robots.txt { alias /home/www/static/robots.txt; }

nginx remplace la chaîne préfixe /robots.txt dans le chemin URL par /home/www/static/robots.txt puis utilise le résultat comme un chemin de système de fichiers. Représenté en pseudocode, cela ressemblerait à quelque chose comme :

if urlPath.startsWith("/robots.txt") {
    fsPath := "/home/www/static/robots.txt" + urlPath.stripPrefix("/robots.txt")
    serveFile(fsPath)
}

Ainsi, /robots.txt est servi depuis /home/www/static/robots.txt car /robots.txt dépouillé du préfixe /robots.txt est une chaîne vide, et l'ajout de la chaîne vide à /home/www/static/robots.txt ne le modifie pas. Cependant, /robots.txt1 serait servi depuis /home/www/static/robots.txt1 et /robots.txt/foobar serait servi depuis /home/www/static/robots.txt/foobar. Ces fichiers peuvent ne pas exister, ce qui amène nginx à renvoyer une réponse 404, et il est probable que robots.txt n'est de toute façon pas un répertoire, mais nginx ne le sait pas à l'avance, et tout cela repose sur des préfixes de chaînes et non pas sur ce qui semble être un fichier ou un répertoire par l'absence ou la présence d'un slash final.

Alors que, dans le deuxième cas,

location /robots.txt { root /home/www/static/; }

nginx insère la chaîne /home/www/static/ au début du chemin URL puis utilise le résultat comme un chemin de système de fichiers. En pseudocode, cela ressemblerait à quelque chose comme :

if urlPath.startsWith("/robots.txt") {
    fsPath := "/home/www/static/robots.txt" + urlPath
    serveFile(fsPath)
}

Cela a exactement le même résultat que le premier cas, mais pour une raison différente. Il n'y a pas de dépouillage de préfixe, mais puisque chaque chemin d'URI doit contenir le préfixe /robots.txt, alors les chemins du système de fichiers commenceront toujours par /home/www/static//robots.txt ce qui est équivalent à /home/www/static/robots.txt.

Bien sûr, le pseudocode ne raconte pas tout l'histoire, car par exemple nginx n'utilisera pas aveuglément des chemins d'URL bruts comme /../../../etc/passwd, la directive try_files modifie le comportement de root/alias, et il y a des contraintes sur l'endroit où alias peut être utilisé.

1voto

BurninLeo Points 836

Il y a une différence, lorsque l'alias concerne tout un répertoire.

    location ^~ /data/ { alias /home/www/static/data/; }

fonctionnera, tandis que

    location ^~ /data/ { root /home/www/static/data/; }

ne fonctionnera pas. Il faudrait alors écrire

    location ^~ /data/ { root /home/www/static/; }

(Facile à confondre)

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X