Como o Apache mescla várias seções de localização correspondentes

35

Estou trabalhando em algumas configurações básicas do apache, mas não entendo exatamente como o apache mescla <Location>seções diferentes quando várias delas correspondem a uma URL de solicitações recebidas. A documentação do apache no capítulo "Como as seções são mescladas" é um pouco confusa quando se trata da ordem / prioridade de várias seções correspondentes do mesmo tipo.

Por exemplo, imagine a seguinte configuração do apache (ignore se o conteúdo real faz sentido ou não, estou interessado apenas na ordem dos aplicativos de cada regra / seção):

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

Agora, se um cliente fizer uma solicitação para /sub/foobar, qual é a configuração final que será aplicada a essa solicitação?

A configuração aplicada é equivalente a:

# 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

ou talvez

# 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

ou algo completamente diferente.

Obrigado pela ajuda, estou realmente confuso.

LordOfThePigs
fonte

Respostas:

44

A ordem da mesclagem é bastante complicada e é fácil ser detectada por exceções ... O documento do apache é " Como as seções são mescladas "

De acordo com essa documentação, a ordem de mesclagem das seções é feita processando todas as entradas correspondentes para cada tipo de correspondência na ordem em que são encontradas nos arquivos de configuração e, em seguida, movendo-se para o próximo tipo (com a exceção de <Diretório >, que é tratado em ordem de especificidade do caminho).

A ordem dos tipos é Directory, DirectoryMatch, Files, e, finalmente Location. As correspondências posteriores substituem as correspondências anteriores. (* ProxyPass e Alias ​​são tratados de forma diferente novamente, veja a nota no final)

E há várias exceções importantes a essas regras que se aplicam ao uso do ProxyPass e ProxyPass em uma seção <Location>. (ver abaixo)

Portanto, a partir do seu exemplo acima, solicite http://somehost.com/sub/foobar com a seguinte configuração;

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

Acumularia as seguintes diretrizes ....

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

Com as correspondências posteriores, eliminando as duplicatas anteriores, resultando em;

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

Explicação
As correspondências posteriores substituem as correspondências anteriores, com exceção de <Directory>onde as correspondências são processadas na ordem: do componente de diretório mais curto ao mais longo.

Por exemplo,
<Directory /var/web/dir>
serão processados ​​antes,
<Directory /var/web/dir/subdir>
independentemente da ordem em que essas diretivas foram especificadas na configuração e a correspondência mais específica vencer.

Qualquer Locationdiretiva correspondente sempre substituirá uma Directorydiretiva correspondente anteriormente .

A idéia básica é que para um pedido como GET /some/http/request.htmlinternamente ele será traduzido para um local no sistema de arquivos por meio de um Alias, ScriptAliasou para uma localização de arquivo normal sob o DocumentRootpara o VirtualHost que combinava.

Portanto, uma solicitação terá as seguintes propriedades usadas para correspondência:
Location: /some/http/request.html File: /var/www/html/mysite/some/http/request.html Directory: /var/www/html/mysite/some/http

O Apache aplicará, por sua vez, todas as Directorycorrespondências, na ordem da especificidade do diretório, a partir da configuração e, por sua vez DirectoryMatch, aplicará Files, e finalmente Locationcorresponderá na ordem em que elas forem encontradas.

Assim , Locationsubstitui Files, que substitui DirectoryMatch, com caminhos correspondentes Directoryna prioridade mais baixa. Portanto, em seu exemplo acima, uma solicitação para /sub/foobarcorresponder aos 3 primeiros locais em ordem, portanto, o último vence por diretivas conflitantes.

(Você está certo de que não está claro nos documentos como alguns casos extremos são resolvidos, é possível que qualquer allow from *diretiva de tipo esteja conectada ao associado Order allow,deny, mas eu não testei isso. Além disso, o que acontece se você corresponder, Satisfy Anymas você já coletaram um Allow from *...)

nota interessante sobre ProxyPass e Alias

Só para ser chato, ProxyPasse Aliasparece funcionar na outra direção .... ;-) Basicamente, atinge a primeira partida, depois para e a 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.

portanto, basicamente, as diretivas Alias ​​e ProxyPass precisam ser especificadas, mais específicas primeiro;

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

No entanto, como @orev apontou. Você pode ter uma diretiva ProxyPass em uma diretiva Location e, portanto, um ProxyPass mais específico em um Location superará qualquer ProxyPass encontrado anteriormente.

Tom H
fonte
3
Obrigado por sinalizar o aviso sobre como solicitar diretivas ProxyPass. Salvei-me muita dor de cabeça
Jeremy French
2
Em relação a ProxyPass "trabalhar na outra direção" , isso só é verdade se eles estiverem fora de a <Location>. Dentro de a <Location>, as regras de mesclagem <Location>são seguidas, o que significa que você deseja que suas <Location>diretivas menos específicas venham antes das mais específicas. Isso permite que os mais específicos substituam as diretivas menos específicas. Você pode ter apenas um ProxyPasspor <Location>.
orev 14/09/18