Làm thế nào để Apache hợp nhất nhiều phần Vị trí phù hợp


35

Tôi đang làm việc trên một số cấu hình apache cơ bản, nhưng tôi không hiểu chính xác làm thế nào apache hợp nhất các <Location>phần khác nhau khi một vài trong số chúng khớp với một URL yêu cầu đến. Các tài liệu apache trong "Làm thế nào các phần được sáp nhập" chương của nó là một chút bối rối khi nói đến thứ tự / ưu tiên của một số phần kết hợp của các loại tương tự.

Ví dụ: hãy tưởng tượng cấu hình apache sau (bỏ qua xem nội dung thực tế có ý nghĩa hay không, tôi chỉ quan tâm đến thứ tự ứng dụng của từng quy tắc / phần):

<Location / >
  ProxyPass http://backend.com/
  Order allow,deny
  Satisfy any
</Location>

<Location /sub/foo>
  Order allow,deny
</Location>

<Location /sub >
  Order deny,allow
  Require valid-user
  Satisfy all
</Location>

<Location /doesnt/match >
  ProxyPass !
</Location>

Bây giờ nếu khách hàng đưa ra yêu cầu /sub/foobar, cấu hình cuối cùng sẽ được áp dụng cho yêu cầu này là gì?

Là cấu hình được áp dụng tương đương với:

# All the directives contained in all the matchin Locations in declaration order
ProxyPass http://backend.com/
Order allow,deny
Satisfy any
Order allow,deny
Order deny,allow
Require valid-user
Satisfy all

hoặc có thể

# same as above, but with longest matching path last
ProxyPass http://backend.com/
Order allow,deny
Satisfy any
Order deny,allow
Require valid-user
Satisfy all
Order allow,deny

hoặc một cái gì đó hoàn toàn khác nhau.

Cảm ơn sự giúp đỡ của bạn, tôi thực sự bối rối.

Câu trả lời:


44

Thứ tự hợp nhất khá phức tạp và rất dễ bị ngoại lệ bắt gặp ... Tài liệu apache là " Cách các phần được hợp nhất "

Theo tài liệu đó, thứ tự hợp nhất các phần được thực hiện bằng cách xử lý tất cả các mục khớp cho từng loại khớp theo thứ tự chúng gặp trong các tệp cấu hình, sau đó chuyển sang loại tiếp theo (ngoại trừ <Thư mục >, được xử lý theo thứ tự độ đặc hiệu của đường dẫn).

Trình tự của các loại là Directory, DirectoryMatch, Files, và cuối cùng Location. Các trận đấu sau đó ghi đè lên các trận đấu trước đó. (* ProxyPass và Bí danh được xử lý khác nhau một lần nữa, xem ghi chú ở cuối)

Và có một số ngoại lệ quan trọng đối với các quy tắc này áp dụng cho việc sử dụng ProxyPass và ProxyPass trong phần <Location>. (xem bên dưới)

Vì vậy, từ ví dụ của bạn ở trên yêu cầu http://somehost.com/sub/foobar với cấu hình follwing;

<Location / >
  ProxyPass http://backend.com/
  Order allow,deny
  Satisfy any
</Location>

<Location /sub/foo>
  Order allow,deny
</Location>

<Location /sub >
  Order deny,allow
  Require valid-user
  Satisfy all
</Location>

<Location /doesnt/match >
  ProxyPass !
</Location>

Nó sẽ tích lũy các chỉ thị sau ....

  ProxyPass http://backend.com/
  Order allow,deny
  Satisfy any
  Order allow,deny
  Order deny,allow
  Require valid-user
  Satisfy all   

Với các trận đấu sau đó loại bỏ các bản sao trước đó, dẫn đến;

  ProxyPass http://backend.com/
  Order deny,allow
  Require valid-user
  Satisfy all   

Giải thích Các
kết quả khớp sau ghi đè lên các kết quả khớp trước đó ngoại trừ <Directory>nơi các kết quả khớp được xử lý theo thứ tự: thành phần thư mục ngắn nhất đến dài nhất.

Vì vậy, ví dụ,
<Directory /var/web/dir>
sẽ được xử lý trước
<Directory /var/web/dir/subdir>
bất kể lệnh nào được chỉ định trong cấu hình và trận đấu cụ thể hơn sẽ thắng.

Bất kỳ Locationchỉ thị phù hợp nào cũng sẽ luôn ghi đè Directorychỉ thị phù hợp trước đó .

Ý tưởng cơ bản là đối với một yêu cầu như GET /some/http/request.htmlnội nó sẽ được dịch sang một địa điểm trong hệ thống file thông qua một Alias, ScriptAliashoặc cho một vị trí tập tin bình thường dưới sự DocumentRootcho VirtualHost rằng nó phù hợp.

Vì vậy, một yêu cầu sẽ có các thuộc tính sau mà nó sử dụng để khớp:
Location: /some/http/request.html File: /var/www/html/mysite/some/http/request.html Directory: /var/www/html/mysite/some/http

Apache sau đó sẽ được áp dụng trong lần lượt tất cả các Directorytrận đấu, theo thứ tự đặc thư mục, từ cấu hình, và sau đó lần lượt áp dụng DirectoryMatch, Filesvà cuối cùng là Locationphù hợp theo thứ tự mà họ đang gặp phải.

Vì vậy, Locationghi đè Files, ghi đè DirectoryMatch, với các đường dẫn khớp Directoryở mức ưu tiên thấp nhất. Do đó, trong ví dụ của bạn ở trên, một yêu cầu /sub/foobarsẽ khớp với 3 Vị trí đầu tiên theo thứ tự, do đó , yêu cầu cuối cùng sẽ giành chiến thắng cho các chỉ thị mâu thuẫn.

(Bạn có phải là nó không phải là rõ ràng từ các tài liệu như thế nào một số trường hợp cạnh được giải quyết, có thể của nó mà bất kỳ allow from *chỉ thị loại sẽ được kết nối với các liên Order allow,deny, nhưng tôi đã không kiểm tra đó. Ngoài ra những gì sẽ xảy ra nếu bạn kết hợp Satisfy Anynhưng bạn trước đây đã thu thập một Allow from *...)

lưu ý thú vị về ProxyPass và Bí danh

Chỉ để gây phiền nhiễu, ProxyPassAliasdường như hoạt động theo hướng khác .... ;-) Về cơ bản, nó đánh trận đấu đầu tiên, sau đó dừng lại và sử dụng nó!

Ordering ProxyPass Directives

The configured ProxyPass and ProxyPassMatch rules are 
checked in the order of configuration. 
The first rule that matches wins. So
usually you should sort conflicting ProxyPass rules starting with the
longest URLs first. Otherwise later rules for longer URLS will be
hidden by any earlier rule which uses a leading substring of the URL.
Note that there is some relation with worker sharing.

For the same reasons exclusions must come before the general 
ProxyPass directives.

về cơ bản, các chỉ thị Bí danh và ProxyPass phải được chỉ định, cụ thể nhất trước tiên;

Alias "/foo/bar" "/srv/www/uncommon/bar"
Alias "/foo"     "/srv/www/common/foo"

ProxyPass "/special-area" "http://special.example.com" smax=5 max=10
ProxyPass "/" "balancer://mycluster/" stickysession=JSESSIONID|jsessionid nofailover=On

Tuy nhiên, như @orev đã chỉ ra. Bạn có thể có một lệnh ProxyPass trong một lệnh Vị trí và do đó, một ProxyPass cụ thể hơn trong một Vị trí sẽ đánh bại mọi ProxyPass được tìm thấy trước đó.


3
Cảm ơn bạn đã gắn cờ cảnh báo về Đặt hàng Chỉ thị ProxyPass. Cứu tôi rất nhiều đau đầu
Jeremy Pháp

2
Về ProxyPass "làm việc theo hướng khác" , điều này chỉ đúng nếu chúng nằm ngoài a <Location>. Bên trong a <Location>, các quy tắc hợp nhất <Location>được tuân theo, có nghĩa là bạn muốn các <Location>chỉ thị ít cụ thể nhất của bạn được đưa ra trước các quy tắc cụ thể hơn. Điều này cho phép những cái cụ thể hơn ghi đè lên các chỉ thị ít cụ thể hơn. Bạn chỉ có thể có một ProxyPasscho mỗi <Location>.
orev
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.