Nginx - root czy alias, do obsługi pojedynczych plików?


66

Po wielu godzinach dostarczania nginxpojedynczych plików, takich jak robots.txt(wskazówka: wyczyść pamięć podręczną przeglądarki za każdym razem), skończyłem na dwa różne sposoby, jeden przy użyciu dyrektywy aliasowej i jeden przy użyciu dyrektywy root , tak jak:

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

Czy jest jakaś funkcjonalna różnica między nimi? Czy problemy z bezpieczeństwem? Jakieś konflikty z innymi dyrektywami? (Oba wydawały się w porządku z inną / statyczną lokalizacją). Czy jest jakiś powód, aby wybierać jeden nad drugim?

Uwaga - nie korzystałem z obu jednocześnie :) Raczej spróbowałem każdego z osobna i oba działały. Nie pytam, w jaki sposób oba działają razem w tym samym pliku, ale który z nich byłby lepszy w użyciu.

Odpowiedzi:


71

Te dwie dyrektywy różnią się nieco funkcjonalnie, ponieważ w drugim przypadku nie używasz dopasowania ścisłego. Dopasuje więc /robots.txt1111również Twoją drugą lokalizację.
location =/robots.txt { root /home/www/static/; }jest dokładnym funkcjonalnym odpowiednikiem pierwszej dyrektywy.


Dobra uwaga, dzięki. Ale możesz użyć =w obu przypadkach, prawda? Czy dotyczy to tylko root? Zobacz też moją edycję - nie chciałem używać obu naraz. :)
Cyclops

@Cyclops tak, możesz użyć =w obu przypadkach.
Alexander Azarov,

Byłyby więc takie same - czy jest jakiś powód, aby wybierać jedną dyrektywę nad drugą? To moje główne pytanie.
Cyclops,

@Cyclops Zasadniczo nie ma takiego powodu.
Alex

41

Tak, jest różnica: za pomocą „aliasu” możesz… no dobrze alias do innej nazwy pliku, na przykład

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

natomiast

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

zmusza cię do nazwania pliku na serwerze również robots.txt. Korzystam z pierwszej opcji, ponieważ lubię nazywać moje pliki robotów na moim serwerze jako tld.domain.subdomain-robots.txt; na przykład

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

1

Myślę, że warto wyraźnie określić, że nginx działa na prefiksach, a nie na plikach jako takich. W pierwszym przypadku,

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

nginx zastępuje przedrostek łańcucha /robots.txtw ścieżce adresu URL, /home/www/static/robots.txta następnie wykorzystuje wynik jako ścieżkę systemu plików. Reprezentowany jako pseudokod, mógłby wyglądać mniej więcej tak:

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

/robots.txtJest więc obsługiwany, /home/www/static/robots.txtponieważ /robots.txtpozbawiony /robots.txtprefiksu jest pusty ciąg, a dodanie pustego ciągu powoduje /home/www/static/robots.txtpozostawienie go bez zmian. Ale /robots.txt1będą podawane z /home/www/static/robots.txt1i /robots.txt/foobarbędą podawane z /home/www/static/robots.txt/foobar. Te pliki mogą nie istnieć, co powoduje, że nginx wysyła odpowiedź 404, i prawdopodobnie robots.txtnie jest to katalog, ale nginx nie wie o tym z góry, a wszystko to opiera się na prefiksach ciągów, a nie na tym, co wydaje się być plikiem lub katalog przez brak lub obecność końcowego ukośnika.

Podczas gdy w drugim przypadku

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

nginx wstawia ciąg /home/www/static/na początku ścieżki URL, a następnie wykorzystuje wynik jako ścieżkę do systemu plików. W pseudokodzie byłoby to coś takiego:

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

Ma to dokładnie taki sam wynik jak pierwszy przypadek, ale z innego powodu. Nie ma możliwości usuwania prefiksu, ale ponieważ każda ścieżka URI musi zawierać prefiks /robots.txt, ścieżki systemu plików zawsze zaczynają się od tego, /home/www/static//robots.txtco jest równoważne /home/www/static/robots.txt .

Oczywiście pseudokod nie do końca opowiada całą historię, ponieważ np. Nginx nie będzie ślepo używać surowych ścieżek URL, np /../../../etc/passwd. try_filesDyrektywa zmienia zachowanie root/ aliasi istnieją ograniczenia dotyczące tego, gdzie aliasmożna go użyć.


0

Różnica polega na tym, że alias dotyczy całego katalogu.

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

będzie działać, podczas gdy

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

nie zrobię. To musiałoby być

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

(Łatwo pomylić)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.