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

66

Après avoir passé de nombreuses heures nginxà servir des fichiers uniques tels que robots.txt(conseil: effacez le cache de votre navigateur à chaque fois), je me suis retrouvé de deux manières différentes, l'une utilisant la directive alias et l'autre à l'aide de la directive racine , comme suit:

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 bien avec un autre emplacement / statique). Ou une raison de choisir l'un sur l'autre?

Note - Je n'ai pas utilisé les deux en même temps :) J'ai plutôt essayé les uns après les autres, et les deux ont fonctionné. Je ne demande pas comment ils interagissent ensemble dans le même fichier, mais lequel serait-il préférable d'utiliser.

cyclope
la source

Réponses:

71

Eh bien, ces deux directives sont légèrement différentes sur le plan fonctionnel car vous n’utilisez pas la correspondance exacte dans ce dernier cas. Donc, /robots.txt1111correspondra à votre deuxième emplacement aussi.
location =/robots.txt { root /home/www/static/; }est un équivalent fonctionnel exact de votre première directive.

Alex
la source
Bon point, merci. Mais vous pouvez utiliser un =dans les deux cas, correct? Ou est-ce seulement applicable à root? Aussi, voir mon édition - je ne voulais pas utiliser les deux à la fois. :)
Cyclope
@ Cyclops oui, vous pouvez utiliser =dans les deux cas.
Alexander Azarov
Ils seraient donc les mêmes - y a-t-il une raison de choisir une directive plutôt qu'une autre? Est ma principale question.
Cyclope
@Cyclops En gros, il n'y a pas une telle raison.
Alex
41

Oui, il y a une différence: avec "alias" vous pouvez .. ainsi alias pour 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 votre fichier sur le serveur également robots.txt. J'utilise la première option car j'aime nommer mes fichiers robots sur mon serveur comme étant tld.domain.subdomain-robots.txt; par exemple

location /robots.txt { alias /home/www/static/ch.notex.static-robots.txt; }
Hasan Karahan
la source
1

Je pense que cela vaut la peine de préciser explicitement que nginx fonctionne sur des préfixes et non sur des fichiers en tant que tels. Dans le premier cas,

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

nginx remplace le préfixe de chaîne /robots.txtdans le chemin de l'URL par /home/www/static/robots.txt, puis utilise le résultat comme chemin du système de fichiers. Représenté sous forme de pseudocode, ce serait quelque chose comme:

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

Donc /robots.txtest servi depuis /home/www/static/robots.txtparce que /robots.txtle /robots.txtpréfixe dépouillé est la chaîne vide, et en ajoutant la chaîne vide pour la /home/www/static/robots.txtlaisser inchangée. Mais, /robots.txt1serait servi de /home/www/static/robots.txt1et /robots.txt/foobarserait servi de /home/www/static/robots.txt/foobar. Ces fichiers peuvent ne pas exister, ce qui entraîne l'envoi d'une réponse 404 par nginx. Il est probable que ce robots.txtn'est pas un répertoire de toute façon, mais nginx ne le sait pas à l'avance. Tout cela est basé sur les préfixes de chaîne et non sur ce qui semble être un fichier. ou répertoire par l’absence ou la présence d’une barre oblique.

Considérant que, dans le second cas,

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

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

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

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

Bien sûr, le pseudocode ne dit pas tout, par exemple nginx n'utilisera pas aveuglément les chemins d'URL bruts /../../../etc/passwd, la try_filesdirective modifie le comportement de root/ aliaset il existe des contraintes sur le aliaslieu d'utilisation.

kbolino
la source
0

Il y a une différence lorsque l'alias est destiné à un répertoire entier.

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

va travailler, tandis que

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

ne fera pas. Cela devrait être

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

(Facile à confondre)

BurninLeo
la source