ScriptAlias ​​faz com que as solicitações correspondam a muitos blocos Location. O que está acontecendo?

ScriptAlias ​​faz com que as solicitações correspondam a muitos blocos Location. O que está acontecendo?

Desejamos restringir o acesso em nosso servidor de desenvolvimento aos usuários que possuem um certificado de cliente SSL válido. Estamos executando o Apache 2.2.16 no Debian 6.

No entanto, para algumas seções (principalmente git-http, configuração com gitolite emhttps://meu.servidor/git/), precisamos de uma exceção, pois muitos clientes git não suportam certificados de cliente SSL.

Consegui exigir autenticação de certificado de cliente para o servidor e adicionar exceções para alguns locais. No entanto, parece que isso não funciona para o git.

A configuração atual é a seguinte:

SSLCACertificateFile ssl-certs/client-ca-certs.crt
<Location />
  SSLVerifyClient require
  SSLVerifyDepth 2
</Location>
# this works
<Location /foo>
  SSLVerifyClient none
</Location>
# this does not
<Location /git>
  SSLVerifyClient none
</Location>

Também tentei uma solução alternativa, com os mesmos resultados:

# require authentication everywhere except /git and /foo
<LocationMatch "^/(?!git|foo)">
  SSLVerifyClient require
  SSLVerifyDepth 2
</LocationMatch>

Em ambos os casos, um usuário sem certificado de cliente pode acessar perfeitamente my.server/foo/, mas não my.server/git/ (o acesso é recusado porque nenhum certificado de cliente válido é fornecido). Se eu desabilitar completamente a autenticação do certificado de cliente SSL, my.server/git/ funcionará bem.

O problema do ScriptAlias

Gitolite é configurado usando a diretiva ScriptAlias. Descobri que o problema ocorre com qualquer ScriptAlias ​​semelhante:

# Gitolite
ScriptAlias /git/ /path/to/gitolite-shell/
ScriptAlias /gitmob/ /path/to/gitolite-shell/
# My test
ScriptAlias /test/ /path/to/test/script/

Observe que /path/to/test/script é um arquivo, não um diretório, o mesmo vale para /path/to/gitolite-shell/

Meu script de teste simplesmente imprime o ambiente, super simples:

#!/usr/bin/perl

print "Content-type:text/plain\n\n";
print "TEST\n";
@keys = sort(keys %ENV);
foreach (@keys) {
    print "$_ => $ENV{$_}\n";
}

Parece que se eu forhttps://my.server/test/someLocation, que quaisquer diretivas SSLVerifyClient estão sendo aplicadas e estão em blocos Location que correspondem a /test/someLocationou apenas /someLocation.

Se eu tiver a seguinte configuração:

<LocationMatch "^/f">
        SSLVerifyClient require
        SSLVerifyDepth 2
</LocationMatch>

Então, o seguinte URL requer um certificado de cliente:https://meu.servidor/test/foo. No entanto, o seguinte URL não:https://my.server/test/somethingElse/foo

Observe que isso parece se aplicar apenas à configuração SSL. O seguinte não tem qualquer efeito sobrehttps://meu.servidor/test/foo:

<LocationMatch "^/f">
        Order allow,deny
        Deny from all
</LocationMatch>

No entanto, bloqueia o acesso ahttps://meu.servidor/foo.

Isso representa um grande problema para os casos em que tenho algum projeto em execuçãohttps://meu.servidor/projeto(que precisa exigir autorização de certificado de cliente SSL),eexiste um repositório git para esse projeto emhttps://my.server/git/projectque não pode exigir um certificado de cliente SSL. Como o URL /git/project também corresponde aos Locationblocos /project, tal configuração parece impossível, dadas as minhas descobertas atuais.

Pergunta: Por que isso está acontecendo e como resolvo meu problema?

No final, quero exigir autorização de certificado de cliente SSL para todo o servidor, exceto /git e /someLocation, com a configuração mínima possível (para não precisar modificar a configuração sempre que algo novo for implantado ou um novo repositório git é adicionado).

AtualizarMais informações: Observe que, em alguns casos,https://meu.servidor/projetoé, na verdade, proxy reverso, de modo que uma <Directory /path/to/project>diretiva é impossível. Se eu quiser proteger esse aplicativo com um certificado de cliente SSL, isso deverá necessariamente ser feito com um bloco <Location /project>(ou mais geral ).<Location />

Atualização 2Acabei de testar isso no Apache 2.4.3, com o mesmo resultado. Se isso foi devido a algum bug, pelo menos está presente em duas versões.


Nota: reescrevi minha pergunta (em vez de apenas adicionar mais atualizações na parte inferior) para levar em conta minhas novas descobertas e espero deixar isso mais claro.

Responder1

De acordo com o atualDocumentação do Apacheisso pode ser um problema:

No contexto por servidor, aplica-se ao processo de autenticação do cliente usado no handshake SSL padrão quando uma conexão é estabelecida. No contexto por diretório, ele força uma renegociação SSL com o nível de verificação do cliente reconfigurado após a leitura da solicitação HTTP, mas antes do envio da resposta HTTP.

Que tal usar o contexto <Directory> em vez de <Location>. Uma entrada para o nível raiz e outra para o caminho do Script-Alias: /path/to/gitolite-shell/

Atualizar:

Encontrei alguns conselhos para este caso ->Pergunta/resposta no Stackoverflow

informação relacionada