Wie führt Apache mehrere übereinstimmende Speicherortabschnitte zusammen?

34

Ich arbeite an einer grundlegenden Apache-Konfiguration, verstehe aber nicht genau, wie Apache verschiedene <Location>Abschnitte zusammenführt, wenn mehrere mit einer URL für eingehende Anfragen übereinstimmen. Die Apache-Dokumentation in ihrem Kapitel "Wie die Abschnitte zusammengeführt werden" ist etwas verwirrend, wenn es um die Reihenfolge / Priorität mehrerer übereinstimmender Abschnitte desselben Typs geht.

Stellen Sie sich zum Beispiel die folgende Apache-Konfiguration vor (ignorieren Sie, ob der tatsächliche Inhalt sinnvoll ist oder nicht, ich interessiere mich nur für die Anwendungsreihenfolge der einzelnen Regeln / Abschnitte):

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

Wenn nun ein Client eine Anfrage an stellt /sub/foobar, welche endgültige Konfiguration wird auf diese Anfrage angewendet?

Entspricht die angewendete Konfiguration:

# 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

oder vielleicht

# 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

oder etwas ganz anderes.

Vielen Dank für Ihre Hilfe, ich bin wirklich verwirrend.

LordOfThePigs
quelle

Antworten:

43

Die Reihenfolge des Zusammenführens ist ziemlich kompliziert und es ist leicht, von Ausnahmen erfasst zu werden ... Das Apache-Dokument lautet " So werden die Abschnitte zusammengeführt ".

Gemäß dieser Dokumentation wird die Reihenfolge des Zusammenführens von Abschnitten dadurch festgelegt, dass alle übereinstimmenden Einträge für jeden Übereinstimmungstyp in der Reihenfolge verarbeitet werden, in der sie in den Konfigurationsdateien enthalten sind, und dann zum nächsten Typ übergegangen wird (mit Ausnahme von <Directory >, die in der Reihenfolge der Pfadspezifität behandelt wird).

Die Reihenfolge der Arten ist Directory, DirectoryMatch, Filesund schließlich Location. Spätere Übereinstimmungen überschreiben frühere Übereinstimmungen. (* ProxyPass und Alias ​​werden wieder unterschiedlich behandelt, siehe Hinweis am Ende)

Es gibt einige wichtige Ausnahmen zu diesen Regeln, die für die Verwendung von ProxyPass und ProxyPass in einem Abschnitt <Location> gelten. (siehe unten)

Also fordern Sie in Ihrem obigen Beispiel http://somehost.com/sub/foobar mit der folgenden Konfiguration an:

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

Es würden sich folgende Richtlinien ansammeln ....

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

Bei den späteren Übereinstimmungen werden die vorherigen Duplikate entfernt.

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

Erläuterung
Spätere Übereinstimmungen überschreiben frühere Übereinstimmungen, mit der Ausnahme, <Directory>dass Übereinstimmungen in der Reihenfolge verarbeitet werden: kürzeste Verzeichniskomponente bis längste.

So
<Directory /var/web/dir>
wird beispielsweise vorher abgearbeitet,
<Directory /var/web/dir/subdir>
in welcher Reihenfolge diese Anweisungen in der Konfiguration angegeben wurden, und das spezifischere Match gewinnt.

Jede übereinstimmende LocationAnweisung überschreibt immer eine zuvor übereinstimmende DirectoryAnweisung.

Die Grundidee ist, dass für eine Anfrage wie GET /some/http/request.htmlintern über eine in einen Speicherort im Dateisystem übersetzt wird Alias, ScriptAliasoder für einen normalen Speicherort unter dem DocumentRootfür den VirtualHost, mit dem sie übereinstimmt.

Eine Anfrage hat also die folgenden Eigenschaften, die sie für den Abgleich verwendet:
Location: /some/http/request.html File: /var/www/html/mysite/some/http/request.html Directory: /var/www/html/mysite/some/http

Apache gilt dann in alle die Wende DirectoryStreichhölzer, in der Reihenfolge des Verzeichnis Spezifität, aus der Config und dann wiederum gelten DirectoryMatch, Filesund schließlich Locationentspricht in der Reihenfolge , in der sie auftreten.

So Locationüberschreibt Files, die Überschreibungen DirectoryMatch, mit Pfaden passend Directoryauf der niedrigsten Priorität. Daher würde in Ihrem obigen Beispiel eine Anfrage nach /sub/foobarder Reihenfolge nach der ersten 3 Position entsprechen, daher gewinnt die letzte für widersprüchliche Anweisungen.

(Sie haben Recht, dass aus den Dokumenten nicht klar hervorgeht, wie einige der Randfälle gelöst werden. Es ist möglich, dass allow from *Direktiven jeglicher Art mit den dazugehörigen verbunden sind Order allow,deny, aber ich habe das nicht getestet. Auch was passiert, wenn Sie, Satisfy Anyaber Sie, übereinstimmen habe vorher ein gesammelt Allow from *...)

interessanter Hinweis zu ProxyPass und Alias

Nur um nervig zu sein ProxyPassund Aliasin die andere Richtung zu wirken .... ;-) Es trifft im Grunde das erste Match, hört dann auf und benutzt das!

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.

Grundsätzlich müssen Alias- und ProxyPass-Anweisungen angegeben werden, die genauesten zuerst.

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

und

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

Allerdings hat @orev darauf hingewiesen. Sie können eine ProxyPass-Direktive in einer Location-Direktive haben, und so schlägt ein spezifischerer ProxyPass in einem Location jeden zuvor gefundenen ProxyPass aus.

Tom H
quelle
3
Vielen Dank, dass Sie die Warnung zum Bestellen von ProxyPass-Richtlinien gemeldet haben. Ich habe mir viel Kopfschmerzen erspart
Jeremy French
2
In Bezug auf ProxyPass "Arbeiten in die andere Richtung" gilt dies nur, wenn sie sich außerhalb von a befinden <Location>. Innerhalb von a <Location>werden die Regeln für das Zusammenführen <Location>befolgt, dh Sie möchten, dass Ihre am wenigsten spezifischen <Location>Anweisungen vor den spezifischeren Anweisungen stehen . Dies ermöglicht es den spezifischeren, die weniger spezifischen Anweisungen zu überschreiben. Sie können nur eine ProxyPasspro haben <Location>.
Orev