Wie kann ich in nginx einen Speicherort erstellen, der mit UND ohne abschließenden Schrägstrich funktioniert?

46

Im Moment habe ich diese Konfiguration:

location ~ ^/phpmyadmin/(.*)$
{
        alias /home/phpmyadmin/$1;
}

Wenn ich jedoch besuche www.mysite.com/phpmyadmin(beachte das Fehlen eines abschließenden Schrägstrichs), wird nicht gefunden, wonach ich bei einem 404 suche. Ich gehe davon aus, dass ich den abschließenden Schrägstrich nicht einbeziehe. Wie kann ich das beheben?

rauben
quelle
2
Ich weiß, dass diese Frage ziemlich alt ist, dennoch möchte ich betonen, dass die akzeptierte Antwort geändert werden muss. Unerfahrene Benutzer (diejenigen, die nach dieser Art von QAs suchen) können Sicherheitslücken schaffen, indem sie die aktuell akzeptierte Antwort verwenden.
Bozzy

Antworten:

34

Es könnte sich um den regulären Ausdruck handeln, den Sie verwenden.

location ~ ^/phpmyadmin/(.*)$

Die obigen Angaben stimmen mit / phpmyadmin /, / phpmyadmin / anything / else / here überein, stimmen jedoch nicht mit / phpmyadmin überein, da der reguläre Ausdruck den abschließenden Schrägstrich enthält.

Sie möchten wahrscheinlich so etwas:

location ~ /phpmyadmin/?(.*)$ {
    alias /home/phpmyadmin/$1;
}

Das Fragezeichen ist ein Quantifizierer für reguläre Ausdrücke und sollte Nginx anweisen, mit Null oder einem der vorherigen Zeichen (dem Schrägstrich) übereinzustimmen.

Warnung: Die Community hat diese Lösung als mögliches Sicherheitsrisiko eingestuft

Heumacher
quelle
Danke! Und danke auch für die Erklärung. Wird sich in Zukunft als nützlich erweisen.
Rob
15
Das Muster ist nicht ganz richtig. Es kann auch mit einem Pfad wie "/ phpmyadmin1234" übereinstimmen, offensichtlich ist das nicht das, was Sie wollen. @ kbecs Lösung ist die richtige.
Miau
3
Es tut mir leid, dass ich dies ausdrücklich abgelehnt habe, aber der @Meow-Kommentar ist viel zu wichtig, um ihn zu vernachlässigen. Dies kann zu einem falsch konfigurierten Webserver führen, der Sicherheitslücken enthalten kann.
Daniel F
34

Die bessere Lösung:

location ~ ^/phpmyadmin(?:/(.*))?$ {
    alias /home/phpmyadmin/$1;
}

Stellen Sie sicher, dass der Server zuerst über die Berechtigungen verfügt /home/phpmyadmin.


Erklärung des Unterschieds mit akzeptierter Antwort:

Es dreht sich alles um reguläre Ausdrücke .

Zunächst einmal ^bedeutet das Zeichen, dass Sie vom Anfang der Zeichenfolge und nicht irgendwo in der Mitte übereinstimmen möchten. Das $am Ende bedeutet, dass es mit dem Ende der Zeichenfolge übereinstimmt.

Das (?:)bedeutet nicht-erfassende Gruppe - wir wollen es nicht in den Erfassungsergebnissen, aber wir wollen einige Zeichen einfach gruppieren. Wir gruppieren es so, weil wir möchten /, dass das Zeichen ein nicht wesentlicher Teil des untergeordneten Pfads und kein wesentlicher Teil des übergeordneten Pfads ist.

kbec
quelle
Warum ist es besser?
Meekohi
2
@Meow antwortete auf die akzeptierte Antwort
kbec
2
Dies sollte die akzeptierte Antwort sein
Yonn Trimoreau
@ Meekohi schrieb ich Erklärung
kbec
8

Warum würdest du nicht einfach benutzen?

location /phpmyadmin {
    alias /home/phpmyadmin;
}

?

womble
quelle
Weil das bei mir nicht funktioniert hat. Siehe hier: serverfault.com/questions/375602/…
Rob
1
@Rob Hast du es ohne den abschließenden Schrägstrich in der aliasDirektive versucht ?
Shane Madden
Dies ist tatsächlich die richtige Antwort und die richtige Vorgehensweise. Schließen Sie einfach den abschließenden Schrägstrich aus und es funktioniert für URLs, die sowohl mit als auch ohne den abschließenden Schrägstrich eingegeben wurden. Nginx muss nicht kompliziert werden. Halten Sie es einfach, kompliziertes Regex und andere lustige Dinge verlangsamen Nginx nur.
MitchellK
4
Das Problem dabei ist, dass es auch auf /phpmyadminblahblahblahblahoder eine andere Kombination passen wird
Gary Green
6

Ich weiß, dass dies eine alte Frage ist, aber für alle, die hier über Google landen, habe ich sie folgendermaßen gelöst (Variation von @ kbecs, die ziemlich gut war):

location ~ ^/foo(/.*)?$ {
  proxy_pass http://$backend$1$is_args$args
}

Dadurch werden alle Variationen erfasst /foound /barauf eine andere URL (einschließlich Parameter) umgeleitet . Ich zeige es mit einer proxy_passDirektive, aber es würde auch mit funktionieren alias.

  • /foo -> /bar
  • /foo/ -> /bar/
  • /foo/sub -> /bar/sub
  • /foo/sub1/sub2/?param=value -> /bar/sub1/sub2/?param=value

Es funktioniert, weil $1optional die Subressourcen plus den führenden Schrägstrich erfasst werden, so dass Dinge wie nicht erfasst werden /fooextra/. Außerdem wird ein vorhandener oder nicht vorhandener End-Schrägstrich ordnungsgemäß umgeleitet.

dlouzan
quelle
1
Vielen Dank, dass Sie sich über den Eckfall Gedanken gemacht haben, proxy_pass zu verwenden und sich daher um die Argumente zu kümmern. Du hast meine Zustimmung.
Daniel F
2

Diese Umleitung schreibt nur URLs mit und ohne den abschließenden Schrägstrich neu. Alles, was nach dem Schrägstrich kommt, wird nicht überschrieben.

domain.com/location => umgeleitet zu domain.com/new/location
domain.com/location => umgeleitet zu domain.com/new/location
domain.com/location/other => nicht umgeleitet

server {
  # 301 URL Redirect
  rewrite ^/location/?$ /new/location permanent;
}
Oriol
quelle
1

Haben Sie versucht, die try_filesDirektive zu verwenden?

try_files $uri $uri/ =404;
Prasanth
quelle
0

Ich habe es so gemacht

rewrite ^/promo/?$     http://example.com/promo/page43902.html;
location /promo/ {
    root /var/www;
}
user3132194
quelle
0

Warum nicht einfach zwei Umschreibungen machen:

location ~ ^/phpmyadmin
{
    rewrite /phpmyadmin /home/phpmyadmin/ break;
    rewrite /phpmyadmin/(.*) /home/phpmyadmin/$1 break;
}
千 千 木
quelle