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

28

Estou trabalhando em algumas configurações básicas do apache, mas não entendo precisamente como o apache mescla diferentes <Location> seções quando várias delas correspondem a uma URL de solicitações de entrada. A documentação do apache em seu capítulo "Como as seções são mescladas" é um pouco confusa quando se trata de a 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 de aplicação 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 sua ajuda, estou realmente confuso.

    
por LordOfThePigs 22.05.2012 / 16:42

1 resposta

34

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

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

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

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

Assim, a partir do seu exemplo acima, solicitando o link com a configuração 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>

Ele acumularia as seguintes diretivas ...

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

Com os últimos jogos eliminando as duplicatas anteriores, resultando em:

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

Explicação
As correspondências posteriores sobrescrevem correspondências anteriores, com a exceção de <Directory> , em que as correspondências são processadas na ordem: o componente de diretório mais curto para o mais longo.

So for example,
<Directory /var/web/dir>
will be processed before
<Directory /var/web/dir/subdir>
regardless of what order those directives were specified in the config, and the more specific match wins.

Qualquer diretiva Location correspondente sempre substituirá uma diretiva Directory correspondente anteriormente.

A ideia básica é que, para uma solicitação como GET /some/http/request.html internamente, ela será traduzida para um local no sistema de arquivos por meio de Alias , ScriptAlias ou para um local de arquivo normal sob DocumentRoot para o VirtualHost combinou.

Assim, uma solicitação terá as seguintes propriedades que ela usa 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 Directory correspondências, na ordem de especificidade de diretório, da configuração e, em seguida, aplicará DirectoryMatch , Files e finalmente Location na ordem. em que eles são encontrados.

Portanto, Location substitui Files , que substitui DirectoryMatch , por caminhos que correspondem a Directory na prioridade mais baixa. Portanto, em seu exemplo acima, uma solicitação para /sub/foobar corresponderia aos 3 primeiros locais em ordem, portanto, o último ganha por diretivas conflitantes.

(Você está certo de que não está claro nos documentos como alguns dos casos de borda foram resolvidos, é possível que qualquer diretiva de allow from * esteja conectada ao Order allow,deny associado, mas eu não testei isso Além disso, o que acontece se você corresponder a Satisfy Any , mas tiver coletado anteriormente um Allow from * ...)

nota interessante sobre o ProxyPass e o Alias

Apenas para ser chato, ProxyPass e Alias parecem funcionar na outra direção .... ;-) Basicamente, ele atinge a primeira correspondência, depois para e usa isso!

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.

Então, basicamente, as diretivas Alias e ProxyPass precisam ser especificadas, as 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 local superará qualquer ProxyPass encontrado anteriormente.

    
por 22.05.2012 / 17:58