Làm cách nào tôi có thể tạo một vị trí trong nginx hoạt động với AND mà không có dấu gạch chéo?


46

Ngay bây giờ tôi có cấu hình này:

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

Tuy nhiên, nếu tôi truy cập www.mysite.com/phpmyadmin(lưu ý thiếu dấu gạch chéo), nó sẽ không tìm thấy thứ tôi đang tìm kiếm 404. Tôi giả sử vì tôi không bao gồm dấu gạch chéo. Làm thế nào tôi có thể sửa lỗi này?


2
Tôi biết câu hỏi này khá cũ, dù sao tôi cũng muốn nhấn mạnh về sự cần thiết phải thay đổi câu trả lời được chấp nhận. Người dùng chưa có kinh nghiệm (những người sẽ tìm kiếm loại QAs này) có thể tạo lỗ hổng bảo mật bằng cách sử dụng câu trả lời hiện được chấp nhận.
Ngày

Câu trả lời:


34

Nó có thể là trong biểu thức thông thường mà bạn đang sử dụng -

location ~ ^/phpmyadmin/(.*)$

Ở trên sẽ khớp / phpmyadmin /, / phpmyadmin / anything / other / here, nhưng nó sẽ không khớp / phpmyadmin vì biểu thức chính quy bao gồm dấu gạch chéo.

Bạn có thể muốn một cái gì đó như thế này:

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

Dấu hỏi là một bộ định lượng biểu thức chính quy và sẽ cho nginx khớp với 0 hoặc một trong các ký tự trước đó (dấu gạch chéo).

Cảnh báo: Cộng đồng đã xem giải pháp này là một rủi ro bảo mật có thể xảy ra


Cảm ơn bạn! Và cảm ơn bạn đã giải thích, là tốt. Sẽ có ích trong tương lai.
Cướp

15
Mô hình không hoàn toàn chính xác. Nó cũng có thể khớp với đường dẫn như "/ phpmyadmin1234", rõ ràng đó không phải là điều bạn muốn. Giải pháp của @ kbec là đúng.
Meow

3
Tôi xin lỗi vì đã hạ thấp rõ ràng điều này, nhưng bình luận @Meow là cách quan trọng để bỏ bê. Điều này có thể dẫn đến một máy chủ web được định cấu hình sai có thể chứa các lỗ hổng bảo mật.
Daniel F

34

Giải pháp tốt hơn:

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

Đảm bảo rằng máy chủ có quyền /home/phpmyadmintrước.


Giải thích về sự khác biệt với câu trả lời được chấp nhận:

Đó là tất cả về các biểu thức thông thường .

Trước hết, ^char có nghĩa là bạn muốn khớp từ đầu chuỗi chứ không phải ở đâu đó ở giữa. Ở $cuối có nghĩa là khớp với cuối chuỗi.

Nhóm (?:)có nghĩa là không bắt giữ - chúng tôi không muốn nó trong kết quả chụp, nhưng chúng tôi muốn nhóm đơn giản một số ký tự. Chúng tôi nhóm nó như thế này, vì chúng tôi muốn /char là một phần không quan trọng của con đường con, và không phải là một phần quan trọng của con đường cha mẹ.


Tại sao nó tốt hơn?
Meekohi

2
@Meow đã trả lời câu hỏi này trên câu trả lời được chấp nhận
kbec

2
Đây phải là câu trả lời được chấp nhận
Yonn Trimoreau

@Meekohi Tôi đã viết lời giải thích
kbec

8

Tại sao bạn không sử dụng

location /phpmyadmin {
    alias /home/phpmyadmin;
}

?


Bởi vì điều đó đã không làm việc cho tôi. Xem tại đây: serverfault.com/questions/375602/ Mạnh
Cướp

1
@Rob Bạn đã thử nó mà không có dấu gạch chéo trên aliaschỉ thị?
Shane Madden

Đây thực sự là câu trả lời đúng và cách làm đúng. Đơn giản chỉ cần loại trừ dấu gạch chéo và nó hoạt động cho các url được gõ cả có và không có dấu gạch chéo. Không cần phức tạp bất cứ điều gì trên Nginx, hãy giữ cho nó đơn giản, regex phức tạp và những điều thú vị khác sẽ chỉ làm Nginx chậm lại.
Mitchell

4
Vấn đề với điều này là nó cũng sẽ phù hợp với /phpmyadminblahblahblahblahhoặc bất kỳ sự kết hợp nào khác
Gary Green

6

Tôi biết đây là một câu hỏi cũ, nhưng đối với bất kỳ ai kết thúc ở đây thông qua Google, tôi đã giải quyết nó theo cách sau (biến thể của @ kbec, một câu hỏi khá hay):

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

Điều này sẽ nắm bắt bất kỳ biến thể nào /foovà chuyển hướng nó đến /barmột url khác (bao gồm cả các tham số). Tôi đang hiển thị nó với một proxy_passchỉ thị nhưng nó cũng sẽ làm việc với alias.

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

Nó hoạt động vì $1sẽ tùy ý nắm bắt các nguồn con cộng với dấu gạch chéo hàng đầu, vì vậy nó sẽ không nắm bắt được những thứ như thế /fooextra/. Nó cũng sẽ chuyển hướng một dấu gạch chéo kết thúc hiện tại hoặc không hiện tại đúng cách.


1
Cảm ơn bạn đã xem xét trường hợp góc muốn sử dụng proxy_pass và do đó quan tâm đến các đối số. Bạn có upvote của tôi.
Daniel F

2

Chuyển hướng này sẽ chỉ viết lại URL có và không có dấu gạch chéo. Bất cứ điều gì xảy ra sau dấu gạch chéo sẽ không được ghi đè.

domain.com/location => được chuyển hướng đến domain.com/new/location
domain.com/location => được chuyển hướng đến domain.com/new/location
domain.com/location/other => không được chuyển hướng

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


0

Tôi đã làm nó như thế

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

0

Tại sao không đặt hai cách viết đơn giản:

location ~ ^/phpmyadmin
{
    rewrite /phpmyadmin /home/phpmyadmin/ break;
    rewrite /phpmyadmin/(.*) /home/phpmyadmin/$1 break;
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.