Como fazer com que o Apache confie em um certificado de cliente usando uma autoridade de certificação desconhecida, sem validar a autoridade de certificação

3

Estou na seguinte situação. Eu preciso configurar uma integração bidirecional com um sistema externo. O administrador do sistema externo solicitou que eu enviasse dois CSRs, um para ser usado para gerar um certificado de cliente, o outro para gerar um certificado de servidor. Eles me enviaram os certificados correspondentes. Eu configurei o canal para eles com sucesso (isto é: eu posso invocar seu serviço fornecendo meu certificado de cliente), mas não consigo configurar corretamente o canal inverso (isto é: não consigo fazer meu Apache aceitar seu cliente) certificado sem reclamar).

Juntamente com o meu certificado do servidor (vamos chamá-lo my-server.pem) eles também me enviaram seu próprio certificado de cliente (vamos chamá-lo de seu client.pem). Esse certificado (their-client.pem) é emitido por uma CA "auto-assinada", que é uma CA que não está entre as CAs conhecidas já disponíveis no meu sistema Linux. Eu não tenho este certificado e ainda não consegui obtê-lo dos administradores do sistema externo (eles estão relutantes ... vamos deixar de lado qualquer comentário sobre isso, por favor ... > - |)

É assim que eu configuro meu VirtualHost no Apache:

SSLEngine on
SSLCertificateFile /path/to/my-server.pem
SSLCertificateKeyFile /path/to/my-server-secret-key.key
SSLVerifyClient require
SSLCACertificateFile /path/to/their-client.pem
SSLVerifyDepth 0

Como não tenho o certificado de CA e como é perfeitamente correto dizer "confie apenas nesse certificado de cliente, mais ninguém!", coloquei o próprio certificado de cliente como SSLCACertificateFile , como sugerido na resposta para: link

No entanto, isso não parece funcionar. O erro que eles vêem ao seu lado é:

javax.net.ssl.SSLException: Received fatal alert: unknown_ca

Depois de ativar o log SSL e defini-lo para depuração, o que vejo ao meu lado é:

[ssl:debug] [pid 3396] ssl_engine_kernel.c(1381): [client <their-ip>:41474] AH02275: Certificate Verification, depth 1, CRL checking mode: none [subject: CN=Test CA,OU=Foo,O=Bar,C=it / issuer: CN=Test CA,OU=Foo,O=Bar,C=it / serial: 1BFE / notbefore: Dec  6 15:22:45 2010 GMT / notafter: Dec  6 15:21:52 2020 GMT]
[ssl:info] [pid 3396] [client <their-IP>:41474] AH02276: Certificate Verification: Error (19): self signed certificate in certificate chain [subject: CN=Test CA,OU=Foo,O=Bar,C=it / issuer: CN=Test CA,OU=Foo,O=Bar,C=it / serial: 1BFE / notbefore: Dec  6 15:22:45 2010 GMT / notafter: Dec  6 15:21:52 2020 GMT]
[ssl:info] [pid 3396] [client <their-IP>:41474] AH02008: SSL library error 1 in handshake (server my-server.com:443)
[ssl:info] [pid 3396] SSL Library Error: error:140890B2:SSL routines:SSL3_GET_CLIENT_CERTIFICATE:no certificate returned
[ssl:info] [pid 3396] [client <their-IP>:41474] AH01998: Connection closed to child 54 with abortive shutdown (server my-server.com:443)

Em outras palavras, ele ainda está tentando validar a CA fictícia do certificado de cliente. Eu também tentei alterar SSLVerifyDepth para 1, sem sorte (mesmo erro). Se eu desabilitar a solicitação de certificado do cliente (alterando o valor SSLVerifyClient ), a chamada vai bem, mas não acho que seja o caminho correto a seguir.

Uma pergunta muito parecida é: Como posso fazer o apache solicita um certificado SSL do cliente sem precisar verificá-lo em relação a uma CA conhecida?

No entanto, não tenho certeza se entendi a solução aceita. Em primeiro lugar, o certificado do cliente que devo validar não é autoassinado (é emitido por uma CA desconhecida).

Em segundo lugar, pelo que entendi da documentação do Apache / mod_ssl, SSLVerifyCLient optional_no_ca desativa a autenticação de certificado de cliente strong, porque ela é opcional.

Terceiro, a possibilidade de criar um certificado falso com o mesmo DN do certificado de CA raiz ausente parece uma solução alternativa para forçar o cliente a enviar seu certificado de cliente, mas, no meu caso, não acho que meu problema seja o cliente não me enviando o certificado, mas sim a incapacidade do Apache para validá-lo completamente.

Qualquer sugestão sobre este tópico seria muito útil.

    
por Mauro Molinari 10.09.2015 / 18:33

3 respostas

1

Sua mensagem de erro mostra claramente a causa aqui: "profundidade 1". Você definiu SSLVerifyDepth 0 , que por manual significa que:

self-signed client certificates are accepted only

Para verificar se o certificado do cliente é o esperado e sem a validação da cadeia, tente algo assim:

SSLVerify none
SSLRequire (   %{SSL_CLIENT_S_DN_O} eq "Snake Oil, Ltd."  and %{REMOTE_ADDR} =~ m/^192\.76\.162\.[0-9]+$/  )
    
por 04.01.2017 / 19:14
1

Eu realmente odeio respostas que sugiram alternativas que realmente não respondam a pergunta, mas ... se você não quiser (ou não puder, porque elas não irão fornecer), aceite sua CA para seu certificado, então você deve emitir o certificado de sua própria CA. Isso resolveria o problema de não apenas eles não fornecerem o certificado de assinante, mas também impediriam que você tivesse que confiar em uma CA estranha.

    
por 21.10.2017 / 19:11
-1

Não sou especialista em Apache, mas do ponto de vista do certificado, se eles não quiserem fornecer a chave pública de sua CA raiz, simplesmente peça a eles para obterem o certificado de cliente de uma autoridade de certificação bem conhecida, em vez de sua própria CA. Por exemplo, o StartSSL oferece um certificado gratuito de 1 ano. Você está construindo um pesadelo porque o parceiro não entende como funciona. Outra maneira é instalar o seu próprio link do CA (Linux) (Windows) link e peça que forneçam um CSR para substituir (their-client.pem)

    
por 18.09.2015 / 17:40