Bagaimana cara Apache menggabungkan beberapa bagian Lokasi yang cocok

35

Saya sedang mengerjakan beberapa konfigurasi dasar apache, tetapi saya tidak mengerti persis bagaimana apache menggabungkan <Location>bagian yang berbeda ketika beberapa dari mereka cocok dengan URL permintaan yang masuk. The dokumentasi apache dalam "Bagaimana bagian digabung" bab adalah sedikit membingungkan ketika datang ke urutan / prioritas dari beberapa bagian pencocokan dari jenis yang sama.

Misalnya, bayangkan konfigurasi apache berikut (abaikan apakah konten yang sebenarnya masuk akal atau tidak, saya hanya tertarik dengan urutan aplikasi setiap aturan / bagian):

<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>

Sekarang jika klien mengajukan permintaan /sub/foobar, konfigurasi akhir apa yang akan diterapkan pada permintaan ini?

Apakah konfigurasi yang diterapkan setara dengan:

# 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

atau mungkin

# 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

atau sesuatu yang sama sekali berbeda.

Terima kasih atas bantuan Anda, saya benar-benar membingungkan.

Bangsawan
sumber

Jawaban:

44

Urutan penggabungan cukup rumit, dan mudah untuk dikecualikan dengan pengecualian ... Doc apache adalah " Bagaimana bagian digabung "

Menurut dokumentasi itu, urutan penggabungan bagian dilakukan dengan memproses semua entri yang cocok untuk setiap jenis pencocokan dalam urutan yang mereka temui dalam file konfigurasi, dan kemudian pindah ke tipe berikutnya (dengan pengecualian dari <Directory >, yang diperlakukan dalam urutan spesifisitas jalur).

Urutan jenis ini Directory, DirectoryMatch, Files, dan akhirnya Location. Pertandingan selanjutnya menimpa pertandingan sebelumnya. (* ProxyPass dan Alias ​​diperlakukan berbeda lagi, lihat catatan di akhir)

Dan ada beberapa pengecualian penting untuk aturan ini yang berlaku untuk menggunakan ProxyPass, dan ProxyPass di bagian <Lokasi>. (Lihat di bawah)

Jadi dari contoh Anda di atas, minta http://somehost.com/sub/foobar dengan konfigurasi 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>

Itu akan mengumpulkan arahan berikut ....

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

Dengan pertandingan selanjutnya menghilangkan duplikat sebelumnya, menghasilkan;

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

Penjelasan
Nanti pencocokan menimpa pencocokan sebelumnya dengan pengecualian <Directory>pencocokan tempat diproses dalam urutan: komponen direktori terpendek hingga terpanjang.

Jadi misalnya,
<Directory /var/web/dir>
akan diproses sebelum
<Directory /var/web/dir/subdir>
terlepas dari urutan apa arahan itu ditentukan dalam konfigurasi, dan pertandingan yang lebih spesifik menang.

LocationArahan yang cocok akan selalu menimpa Directoryarahan yang cocok sebelumnya .

Ide dasarnya adalah bahwa untuk permintaan seperti GET /some/http/request.htmlinternal itu akan diterjemahkan ke lokasi di sistem file melalui Alias, ScriptAliasatau untuk lokasi file normal di bawah DocumentRootuntuk VirtualHost yang cocok.

Jadi permintaan akan memiliki properti berikut yang digunakannya untuk mencocokkan:
Location: /some/http/request.html File: /var/www/html/mysite/some/http/request.html Directory: /var/www/html/mysite/some/http

Apache maka akan berlaku pada gilirannya semua Directorypertandingan, di urutan direktori spesifisitas, dari konfigurasi, dan kemudian pada gilirannya berlaku DirectoryMatch, Files, dan akhirnya Locationpertandingan dalam urutan di mana mereka ditemui.

Jadi Locationmenimpa Files, yang menimpa DirectoryMatch, dengan jalur yang cocok Directorydengan prioritas terendah. Karenanya dalam contoh Anda di atas, permintaan untuk /sub/foobarakan mencocokkan 3 Lokasi pertama secara berurutan, maka yang terakhir menang untuk arahan yang bertentangan.

(Anda benar bahwa dari dokumen tidak jelas bagaimana beberapa kasus tepi diselesaikan, kemungkinan bahwa allow from *arahan jenis apa pun akan terhubung ke yang terkait Order allow,deny, tetapi saya tidak mengujinya. Juga apa yang terjadi jika Anda cocok Satisfy Anytetapi Anda sebelumnya telah mengumpulkan Allow from *...)

catatan menarik tentang ProxyPass dan Alias

Hanya untuk menjengkelkan, ProxyPassdan Aliastampaknya bekerja ke arah lain .... ;-) Ini pada dasarnya hits pertandingan pertama, lalu berhenti dan gunakan itu!

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.

jadi pada dasarnya, arahan Alias ​​dan ProxyPass harus ditentukan, paling spesifik terlebih dahulu;

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

dan

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

Namun, seperti yang ditunjukkan @orev. Anda dapat memiliki arahan ProxyPass di arahan Lokasi, sehingga ProxyPass yang lebih spesifik di suatu Lokasi akan mengalahkan ProxyPass yang ditemukan sebelumnya.

Tom H
sumber
3
Terima kasih telah menandai peringatan tentang Pemesanan Arahan ProxyPass. Menyelamatkan saya sakit kepala yang hebat
Jeremy French
2
Mengenai ProxyPass "bekerja di arah lain" , ini hanya berlaku jika mereka berada di luar a <Location>. Di dalam a <Location>, aturan penggabungan <Location>dipatuhi, artinya Anda ingin <Location>arahan paling spesifik datang sebelum arahan yang lebih spesifik. Ini memungkinkan yang lebih spesifik untuk menggantikan arahan yang kurang spesifik. Anda hanya dapat memiliki satu ProxyPassper <Location>.
orev