Come posso creare una posizione in nginx che funziona con AND senza una barra finale?


46

In questo momento ho questa configurazione:

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

Tuttavia, se visito www.mysite.com/phpmyadmin(nota la mancanza di barra finale), non troverà ciò che cerco un 404. Presumo perché non includo la barra finale. Come posso risolvere questo problema?


2
So che questa domanda è piuttosto vecchia, tuttavia vorrei sottolineare la necessità di cambiare la risposta accettata. Gli utenti inesperti (quelli che cercheranno questo tipo di QA) potrebbero creare falle di sicurezza utilizzando la risposta attualmente accettata.
Bozzy

Risposte:


34

Potrebbe essere nell'espressione regolare che stai utilizzando -

location ~ ^/phpmyadmin/(.*)$

Quanto sopra corrisponderà a / phpmyadmin /, / phpmyadmin / qualunque / altro / qui, ma non corrisponderà a / phpmyadmin perché l'espressione regolare include la barra finale.

Probabilmente vuoi qualcosa del genere:

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

Il punto interrogativo è un quantificatore di espressioni regolari e dovrebbe indicare a nginx di corrispondere a zero o a uno dei caratteri precedenti (la barra).

Avvertenza: la comunità ha visto questa soluzione, così com'è, come un possibile rischio per la sicurezza


Grazie! E grazie anche per la spiegazione. Ti tornerà utile in futuro.
Rob

15
Il modello non è del tutto corretto. Può anche abbinare un percorso come "/ phpmyadmin1234", ovviamente non è quello che vuoi. La soluzione di @ kbec è quella giusta.
Meow,

3
Mi dispiace per il downgrade esplicito di questo, ma il commento di @Meow è molto importante da trascurare. Ciò può portare a un server Web non configurato correttamente che potrebbe contenere falle di sicurezza.
Daniel F,

34

La soluzione migliore:

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

Assicurarsi che prima il server disponga delle autorizzazioni /home/phpmyadmin.


Spiegazione della differenza con la risposta accettata:

Si tratta di espressioni regolari .

Prima di tutto, il ^carattere significa che vuoi abbinare dall'inizio della stringa e non da qualche parte nel mezzo. Alla $fine significa che corrisponde alla fine della stringa.

I (?:)mezzi non-gruppo di cattura - non vogliamo che nei risultati di cattura, ma vogliamo semplice gruppo di alcuni caratteri. Lo raggruppiamo in questo modo, perché vogliamo che il /carattere sia una parte non significativa del percorso figlio e non una parte significativa del percorso principale.


Perché è meglio?
Meekohi,

2
@Meow ha risposto a questa risposta accettata
kbec,

2
Questa dovrebbe essere la risposta accettata
Yonn Trimoreau,

@Meekohi Ho scritto una spiegazione
Kbec,

8

Perché non dovresti semplicemente usare

location /phpmyadmin {
    alias /home/phpmyadmin;
}

?


Perché non funzionava per me. Vedi qui: serverfault.com/questions/375602/…
Rob

1
@Rob L'hai provato senza la barra finale della aliasdirettiva?
Shane Madden

Questa è in realtà la risposta corretta e il modo corretto di farlo. Basta escludere la barra finale e funziona per gli URL digitati sia con che senza barra finale. Non c'è bisogno di complicare nulla su Nginx, mantenerlo semplice, complicato regex e altre cose divertenti rallenteranno Nginx.
MitchellK,

4
Il problema è che corrisponderà anche a /phpmyadminblahblahblahblahqualsiasi altra combinazione
Gary Green,

6

So che questa è una vecchia domanda, ma per chiunque finisca qui tramite Google, l'ho risolto nel modo seguente (variazione di quella di @ kbec, che era abbastanza buona):

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

Ciò acquisirà qualsiasi variazione /fooe la reindirizzerà /barsu un altro URL (compresi i parametri). Lo sto mostrando con una proxy_passdirettiva ma funzionerebbe anche con alias.

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

Funziona perché $1acquisirà facoltativamente le risorse secondarie più la barra iniziale, quindi non catturerà cose come /fooextra/. Reindirizzerà anche una barra finale presente o non presente correttamente.


1
Grazie per aver considerato il caso in cui si desidera utilizzare proxy_pass e quindi preoccuparsi degli argomenti. Hai il mio voto.
Daniel F

2

Questo reindirizzamento riscriverà solo gli URL con e senza la barra finale. Tutto ciò che viene dopo la barra non verrà sovrascritto.

domain.com/location => reindirizzato a domain.com/new/location
domain.com/location => reindirizzato a domain.com/new/location
domain.com/location/other => non reindirizzato

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


0

L'ho fatto così

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

0

Perché non mettere semplicemente due riscritture:

location ~ ^/phpmyadmin
{
    rewrite /phpmyadmin /home/phpmyadmin/ break;
    rewrite /phpmyadmin/(.*) /home/phpmyadmin/$1 break;
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.