Bagaimana saya bisa membuat lokasi di nginx yang berfungsi dengan DAN tanpa garis miring?

46

Sekarang saya punya konfigurasi ini:

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

Namun, jika saya mengunjungi www.mysite.com/phpmyadmin(perhatikan kurangnya garis miring), itu tidak akan menemukan apa yang saya cari 404. Saya berasumsi karena saya tidak memasukkan garis miring. Bagaimana saya bisa memperbaikinya?

rampok
sumber
2
Saya tahu pertanyaan ini sudah cukup lama, namun saya ingin menekankan pada perlunya mengubah jawaban yang diterima. Pengguna yang tidak berpengalaman (mereka yang akan mencari QA semacam ini) dapat membuat celah keamanan dengan menggunakan jawaban yang saat ini diterima.
Bozzy

Jawaban:

34

Mungkin dalam ekspresi reguler yang Anda gunakan -

location ~ ^/phpmyadmin/(.*)$

Di atas akan cocok dengan / phpmyadmin /, / phpmyadmin / anything / else / di sini, tetapi tidak akan cocok dengan / phpmyadmin karena ekspresi reguler termasuk garis miring.

Anda mungkin menginginkan sesuatu seperti ini:

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

Tanda tanya adalah pengukur ekspresi reguler dan harus memberi tahu nginx agar cocok dengan nol atau salah satu karakter sebelumnya (garis miring).

Peringatan: Komunitas melihat solusi ini, sebagaimana adanya, sebagai risiko keamanan yang mungkin

hantaman kuat
sumber
Terima kasih! Dan terima kasih atas penjelasannya juga. Akan berguna di masa depan.
Rob
15
Polanya tidak sepenuhnya benar. Itu juga dapat mencocokkan path seperti "/ phpmyadmin1234", jelas itu bukan yang Anda inginkan. Solusi @ kbec adalah yang tepat.
Meow
3
Saya minta maaf karena secara eksplisit menurunkan ini, tetapi komentar @Meow adalah cara yang penting untuk diabaikan. Ini dapat menyebabkan server web yang tidak terkonfigurasi yang dapat mengandung lubang keamanan.
Daniel F
34

Solusi yang lebih baik:

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

Pastikan server memiliki izin /home/phpmyadminterlebih dahulu.


Penjelasan perbedaan dengan jawaban yang diterima:

Ini semua tentang ekspresi reguler .

Pertama-tama, ^char berarti Anda ingin mencocokkan dari awal string dan bukan di suatu tempat di tengah. Tanda $pada akhirnya berarti cocok dengan ujung tali.

The (?:)berarti non-menangkap kelompok - kita tidak ingin hal itu dalam hasil menangkap, tapi kami ingin kelompok sederhana beberapa karakter. Kami mengelompokkannya seperti ini, karena kami ingin /char menjadi bagian yang tidak signifikan dari jalur anak, dan bukan bagian yang signifikan dari jalur induk.

kbec
sumber
Kenapa lebih baik?
Meekohi
2
@Meow menjawab ini pada jawaban yang diterima
kbec
2
Ini harus menjadi jawaban yang diterima
Yonn Trimoreau
@Meekohi saya menulis penjelasan
kbec
8

Kenapa tidak Anda gunakan saja

location /phpmyadmin {
    alias /home/phpmyadmin;
}

?

womble
sumber
Karena itu tidak berhasil untuk saya. Lihat di sini: serverfault.com/questions/375602/…
Rob
1
@Rob Apakah Anda mencobanya tanpa garis miring pada aliasarahan?
Shane Madden
Ini sebenarnya jawaban yang benar dan cara yang benar untuk melakukannya. Cukup kecualikan trailing slash dan itu berfungsi untuk url yang diketik dengan dan tanpa slash trailing. Tidak perlu menyulitkan apa pun di Nginx, tetap sederhana, rumit regex dan hal-hal lucu lainnya hanya akan memperlambat Nginx.
MitchellK
4
Masalahnya adalah ini juga cocok /phpmyadminblahblahblahblahatau kombinasi lainnya
Gary Green
6

Saya tahu ini adalah pertanyaan lama, tetapi bagi siapa pun yang berakhir di sini melalui Google, saya menyelesaikannya dengan cara berikut (variasi dari @ kbec, yang cukup bagus):

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

Ini akan menangkap variasi apa pun /foodan mengarahkannya ke /barurl lain (termasuk parameter). Saya menunjukkannya dengan proxy_passarahan tetapi itu juga akan berhasil alias.

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

Ini berfungsi karena $1secara opsional akan menangkap sub-sumber daya plus garis miring terkemuka, sehingga tidak akan menangkap hal-hal seperti /fooextra/. Ini juga akan mengarahkan slash akhir yang sekarang atau yang tidak hadir dengan benar.

dlouzan
sumber
1
Terima kasih telah mempertimbangkan kasus sudut ingin menggunakan proxy_pass dan dengan demikian peduli dengan argumen. Anda memiliki upvote saya.
Daniel F
2

Pengalihan ini hanya akan menulis ulang URL dengan dan tanpa garis miring. Apa pun yang datang setelah slash tidak akan ditimpa.

domain.com/location => dialihkan ke domain.com/new/location
domain.com/location => dialihkan ke domain.com/new/location
domain.com/location/other => tidak dialihkan

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

Sudahkah Anda mencoba menggunakan try_filesarahan?

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

Saya melakukannya seperti itu

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

Mengapa tidak menempatkan dua penulisan ulang secara sederhana:

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