In che modo Apache unisce più sezioni Posizione corrispondenti


35

Sto lavorando su alcune configurazioni di base di Apache, ma non capisco esattamente come apache unisce diverse <Location>sezioni quando molte di esse corrispondono a un URL di richieste in arrivo. La documentazione di Apache nel capitolo "Come si uniscono le sezioni" è un po 'confusa quando si tratta dell'ordine / priorità di diverse sezioni corrispondenti dello stesso tipo.

Ad esempio, immagina la seguente configurazione di apache (ignora se il contenuto effettivo ha senso o no, sono interessato solo all'ordine di applicazione di ciascuna regola / sezione):

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

Ora se un client effettua una richiesta /sub/foobar, qual è la configurazione finale che verrà applicata a questa richiesta?

La configurazione applicata è l'equivalente di:

# 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

o forse

# 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

o qualcosa di completamente diverso.

Grazie per il tuo aiuto, sono davvero confuso.

Risposte:


44

L'ordine di fusione è piuttosto complicato, ed è facile essere colto da eccezioni ... Il documento apache è " Come si uniscono le sezioni "

In base a tale documentazione, l'ordine di fusione delle sezioni viene elaborato elaborando tutte le voci corrispondenti per ciascun tipo di corrispondenza nell'ordine in cui vengono rilevate nei file di configurazione e quindi passando al tipo successivo (ad eccezione di <Directory >, che viene trattato in ordine di specificità del percorso).

L'ordine dei tipi è Directory, DirectoryMatch, Files, e, infine Location. Le partite successive sovrascrivono le partite precedenti. (* ProxyPass e Alias ​​vengono nuovamente trattati in modo diverso, vedere la nota alla fine)

E ci sono diverse importanti eccezioni a queste regole che si applicano all'uso di ProxyPass e ProxyPass in una sezione <Location>. (vedi sotto)

Quindi, dal tuo esempio precedente, richiedi http://somehost.com/sub/foobar con la seguente configurazione;

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

Accumulerebbe le seguenti direttive ....

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

Con le partite successive eliminando i duplicati precedenti, con conseguente;

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

Spiegazione
Le corrispondenze successive sovrascrivono le corrispondenze precedenti, ad eccezione del punto in <Directory>cui le corrispondenze vengono elaborate nell'ordine: dal componente di directory più corto al più lungo.

Quindi, ad esempio,
<Directory /var/web/dir>
verrà elaborato prima
<Directory /var/web/dir/subdir>
indipendentemente dall'ordine in cui quelle direttive sono state specificate nella configurazione e la partita più specifica vince.

Qualsiasi Locationdirettiva corrispondente corrisponderà sempre a una Directorydirettiva precedentemente corrispondente .

L'idea di base è che per una richiesta come GET /some/http/request.htmlinternamente verrà tradotta in una posizione nel filesystem tramite un Alias, ScriptAliaso per una normale posizione del file in DocumentRootper il VirtualHost a cui corrispondeva.

Quindi una richiesta avrà le seguenti proprietà che usa per la corrispondenza:
Location: /some/http/request.html File: /var/www/html/mysite/some/http/request.html Directory: /var/www/html/mysite/some/http

Apache quindi applicare a sua volta tutte le Directorypartite, in ordine di directory specificità, dalla configurazione, e poi a sua volta applicare DirectoryMatch, Filese, infine, Locationcorrisponde nell'ordine in cui essi vengono rilevati.

Quindi Locationesegue l'override Files, che esegue l'override DirectoryMatch, con i percorsi che corrispondono Directoryalla priorità più bassa. Quindi nel tuo esempio sopra, una richiesta per /sub/foobarabbinare le prime 3 posizioni in ordine, quindi l'ultima vince per le direttive in conflitto.

(Hai ragione dal dire che non è chiaro dai documenti come vengano risolti alcuni casi limite, è possibile che qualsiasi allow from *tipo di direttiva sia collegata agli associati Order allow,deny, ma non l'ho verificato. Inoltre, cosa succede se si abbina Satisfy Anyma tu hanno precedentemente raccolto un Allow from *...)

nota interessante su ProxyPass e Alias

Solo per essere fastidioso, ProxyPasse Aliassembra funzionare nell'altra direzione .... ;-) Praticamente colpisce la prima partita, poi si ferma e la usa!

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.

quindi in sostanza devono essere specificate le direttive Alias ​​e ProxyPass, prima le più specifiche;

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

e

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

Tuttavia, come ha sottolineato @orev. Puoi avere una direttiva ProxyPass in una direttiva Location, quindi un ProxyPass più specifico in una Location eliminerà qualsiasi ProxyPass precedentemente trovato.


3
Grazie per aver segnalato l'avvertimento sull'ordinazione delle direttive ProxyPass. Mi ha fatto risparmiare un sacco di mal di testa
Jeremy French,

2
Per quanto riguarda ProxyPass "lavorare nella direzione opposta" , questo è vero solo se sono al di fuori di a <Location>. All'interno di a <Location>, <Location>vengono seguite le regole di fusione , il che significa che vuoi che le tue <Location>direttive meno specifiche vengano prima di quelle più specifiche. Ciò consente a quelli più specifici di ignorare le direttive meno specifiche. Puoi averne solo uno ProxyPassper <Location>.
orev,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.