Impulsionando a verificação do cliente no Apache apenas para um certificado de cliente específico

2

Eu quero que o meu servidor web Apache aceite conexões SSL SOMENTE SE o cliente se apresentar com um certificado de cliente SSL específico. Em outras palavras, apenas um cliente é permitido e deve usar um certificado de cliente específico (que eu também tenho).

Este certificado de cliente (vamos chamá-lo de "MyClientCertificate") é um certificado PEM normal emitido por uma CA (vamos chamá-lo de "MyCA") para o qual eu também tenho seu certificado.

Foi assim que configurei meu host virtual Apache para essa finalidade (estou relatando apenas as opções relacionadas à verificação do cliente SSL):

SSLVerifyClient require
SSLCACertificatePath /etc/ssl/certs
SSLCACertificateFile /etc/ssl/client/MyClientCertificate.pem
SSLCADNRequestFile /etc/ssl/client/MyClientCertificate.pem
SSLVerifyDepth 1

Explicações das opções (ou das minhas intenções, pelo menos ...):

  • com "SSLVerifyClient require" eu imponho o Apache para sempre executar a verificação do cliente e rejeitar a conexão se ela falhar
  • / etc / ssl / certs contém os certificados PEM do MyCA (instalados corretamente no sistema com o processo obrigatório de hashing + symlinking), desde que todos os outros CAs conhecidos do Apache reconheçam
  • com SSLCACertificateFile Estou adicionando o certificado MyClientCertificate à lista de certificados CA em / etc / ssl / certs, como um certificado confiável por si só, e com SSLCADNRequestFile estou dizendo que meu servidor deve solicitar apenas esse certificado (e apenas isso) para o cliente, não a lista completa de certificados de CA em SSLCACertificatePath + SSLCACertificateFile
  • com "SSLVerifyDepth 1" Estou dizendo que o certificado de cliente permitido está assinado por uma autoridade de certificação que está entre as reconhecidas pelo servidor (em SSLCACertificatePath)

Isso pareceu funcionar: o Apache exige o certificado do cliente, recusa a conexão se o certificado do cliente especificado não for fornecido e o aceita se estiver. No entanto, recentemente o cliente (que é um fornecedor para mim) decidiu alterar seu certificado de cliente, com um novo (vamos chamá-lo de MyNewClientCertificate.pem) com criptografia de 2048 bits em vez da profundidade de 1024 bits do antigo. O problema é este:

  • o fornecedor diz que alterou seu certificado de cliente e que agora está usando o novo certificado para autenticar
  • o fornecedor diz com certeza que está se apresentando com JUST o novo certificado e não com o novo e o antigo
  • Ainda não mudei minha configuração do Apache (portanto, meu Apache ainda está configurado para solicitar o certificado antigo)
  • MAS meu Apache está aceitando as conexões do cliente fornecedor sem nenhum problema !! Eu esperava que ele começasse a falhar até que eu alterasse sua configuração para substituir as referências MyClientCertificate.pem por MyNewClientCertificate.pem

O novo certificado é emitido pela mesma CA do antigo. O fornecedor sugere que minha configuração do Apache provavelmente está aceitando todas as conexões de clientes que apresentam um certificado emitido por essa CA, em vez de executar uma correspondência no próprio certificado de cliente.

Se este for o caso, o que estou fazendo errado na minha configuração? Devo diminuir o SSLVerifyDepth para 0? (mas isso não está dizendo que o certificado deve ser auto-assinado?) Ou eu tenho que mudar alguma coisa nas diretivas SSLCACertificateFile / SSLCADNRequestFile?

Como este sistema está em produção, não tenho a capacidade de realizar todos os testes em que posso pensar, mas devo tentar fazer alterações focadas para chegar ao resultado correto o mais rápido possível. É por isso que gostaria de receber ajuda sobre este assunto.

    
por Mauro Molinari 05.01.2016 / 11:30

1 resposta

2

Você pode corresponder um certificado de cliente específico usando a diretiva SSLRequire coincidir com o DN completo do assunto ou apenas com a parte CN do certificado do cliente:

SSLRequire %{SSL_CLIENT_S_DN} eq "C=AU, ST=Some-State, L=Springfield, O=ServerFault.com, OU=Moderators, CN=HBruijn/[email protected]"   

SSLRequire %{SSL_CLIENT_S_DN_CN} eq "HBruijn/[email protected]"

Use openssl x509 -in client.crt -text para exibir a sequência de assunto.

Uma configuração mais completa seria:

SSLVerifyClient      none
SSLCACertificateFile conf/ssl.crt/ca.crt
SSLCACertificatePath conf/ssl.crt

<Directory /usr/local/apache2/htdocs/secure/area>
  SSLVerifyClient      require
  SSLVerifyDepth       5
  SSLOptions           +FakeBasicAuth
  SSLRequireSSL
  SSLRequire           %{SSL_CLIENT_S_DN_CN} eq "HBruijn/[email protected]"
</Directory>
    
por 05.01.2016 / 12:55