Estou usando o apache2 (2.2.3) para servir um site em que gostaria de ter clientes autenticados com certificados. Como só preciso verificar se um usuário que apresenta um certificado específico é o mesmo usuário que apresentou esse certificado no passado, a CA que assina o certificado é irrelevante. Parece, no entanto, que o uso SSLVerifyClient require
exige SSLCACertificateFile ...
(ou SSLCACertificatePath ...
) e o apache aceita apenas certificados assinados por uma CA nesse arquivo / caminho. Existe uma maneira de o apache aceitar qualquer certificado de cliente, independentemente da CA de emissão / canto? (ou seja, verifique se o cliente possui a chave privada correspondente à chave pública apresentada, mas não se preocupe em verificar a CA de emissão / assinatura)
9
mod_ssl
foi projetado para autenticar usuários com base em um relacionamento de assinatura de certificado; se você preferir desconsiderar isso por algum motivo, precisará implementar a autenticação de certificado em seu próprio código, que também trata do mapeamento de certificado para usuário.mod_ssl
maquinário lá, eu esperava que ele pudesse cuidar de parte do trabalho para mim.optional_no_ca
é que pode ser melhor para a interface do usuário, pois você pode exibir uma mensagem de erro HTTP se algo estiver errado com o certificado (você não poderia, caso contrário, uma certificação de cliente ruim interromperia a conexão antes da camada HTTP ) Também é útil se você quiser tentar maneiras alternativas de verificar um certificado (por exemplo, WebID ). Você está certo de que deseja algo para fazer a verificação, e isso só funcionaria realmente quando a solicitação for tratada por código (por exemplo, dentro de PHP / CGI / Java), não tanto com arquivos.Respostas:
Como você descobriu, é possível desativar a verificação do certificado no nível do handshake SSL / TLS no Apache Httpd usando
SSLVerifyCLient optional_no_ca
.O segundo problema que você vai enfrentar com o que está tentando fazer é fazer com que o cliente envie o certificado. Como o seu certificado não se destina a estar dentro de uma PKI, ele pode ser autoassinado e ter vários emissores.
Ao solicitar um certificado de cliente, o servidor envia uma
CertificateRequest
mensagem TLS ao cliente durante o handhsake. Esta mensagem contém acertificate_authorities
lista:Os navegadores usam isso para escolher qual certificado de cliente enviar (se houver).
(Observe que a parte sobre a lista vazia está apenas na especificação do TLS 1.1 em diante. O SSL 3.0 e o TLS 1.0 são omissos e, na prática, também funcionará.)
Você tem duas opções para isso.
Se os certificados de cliente que você espera serão autoassinados, todos terão emissores diferentes. Como você não sabe o que esperar, o servidor precisará enviar uma lista vazia. Para fazer isso, use a
SSLCADNRequestFile
diretiva e aponte-a para um arquivo que contenha apenas uma linha vazia (se bem me lembro, ela não funciona com um arquivo completamente vazio).A segunda opção (menos limpa). É concordar com um DN de emissor comum a todos os certificados de cliente que você espera, independentemente de eles terem sido realmente emitidos por esse certificado de CA (ou se essa CA existe ou não). Ao fazer isso, você quebraria o modelo de PKI consideravelmente (mais).
Se você concorda com um DN do emissor como
CN=Dummy CA
(por exemplo). Qualquer pessoa pode criar um certificado autoassinado usandoCN=Dummy CA
como DN do Assunto (e DN do emissor), possivelmente com chaves diferentes. Embora aSSLCADNRequestFile
diretiva espere ser configurada com certificados para criar a lista, eles não são usados para verificar o certificado do cliente, é apenas uma maneira complicada (mas natural no contexto das outras diretivas) de configurar acertificate_authorities
lista. Se você, como serviço, colocar um certificado autoassinado com esses nomesSSLCADNRequestFile
, isso fará com que aCertificateRequest
mensagem TLS seja usadaCN=Dummy CA
nacertificate_authorities
lista (estes são apenas nomes, não certs neste estágio). O cliente poderá então pegar seu próprio certificado com o DN do emissorCN=Dummy CA
, se sua assinatura pode ou não ser verificada por esse certificado (mesmas chaves) ou não, pois nenhuma verificação de assinatura está envolvida nessas etapas.Dito isto, lembre-se de que
SSLVerifyCLient optional_no_ca
, com , nenhuma verificação real do certificado é feita (suponho que você possa verificar aSSL_CLIENT_VERIFY
variável se a verificação manual for apenas uma solução de fallback para uma PKI que você configurou de qualquer maneira). Tudo o que você saberá nesse estágio é que o cliente possui a chave privada para o certificado de chave pública que ele apresentou (garantido pelaCertificateVerify
mensagem TLS ): você precisará executar alguma forma de verificação se desejar que haja autenticação de alguns ordenar. (Você não pode confiar em nenhum conteúdo do certificado, que é uma ligação entre sua chave pública e os nomes / atributos que ela contém.)Isso não funcionará bem para arquivos, mas você pode fazer isso para um aplicativo (por exemplo, PHP / CGI / ... até Java, se você passar o certificado para o servidor Java em proxy). Uma maneira básica seria ter uma lista pré-conhecida de chaves públicas, ou você poderia examinar as idéias em FOAF + SSL / WebID .
fonte
Usar
SSLVerifyCLient optional_no_ca
(em vez derequire
) faz com que o apache não verifique a CA de emissão (e, portanto, não precisa de um arquivo ou caminho de certificado de CA). Ele permite que o cliente / usuário não envie um certificado, portanto, a verificação de que um certificado foi usado deve ser feita separadamente.(Aparentemente, não consegui ler completamente a
mod_ssl
documentação.)fonte