Pular para o conteúdo
ecdsa.com
nginx error log / OpenSSLCLI do OpenSSL

Mensagem de erro

SSL_do_handshake() failed (SSL: error:0A000418:SSL routines::tlsv1 alert unknown ca:SSL alert number 48)

Também aparece como

  • SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
  • error:0A000418:SSL routines::tlsv1 alert unknown ca

O nginx o registra no nível info como “SSL_do_handshake() failed (SSL: error:0A000418:SSL routines::tlsv1 alert unknown ca:SSL alert number 48) while SSL handshaking, client: …”. A CLI do openssl imprime “…:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:…”. Clientes OpenSSL enviam esse mesmo alerta para cadeias não confiáveis, autoassinadas e incompletas.

nginx error log / OpenSSL — TLS alert 48 (unknown_ca) received from the peer

O que significa

O outro lado da conexão abortou o handshake com o alerta TLS 48 (unknown_ca): não conseguiu ligar o certificado que recebeu a uma CA em que confia. No log de um servidor (como aqui, do nginx), isso significa que um cliente recusou o certificado do servidor. Em um cliente, significa que o servidor recusou o certificado de cliente no TLS mútuo. O lado que registra o alerta nunca é o lado que tem o problema: a causa está no certificado enviado ao peer.

Por que acontece

Como corrigir

  1. 1.

    Descobrir qual certificado foi rejeitado

    Se o alerta está no log do servidor, teste a cadeia do servidor de fora; em um cliente com TLS mútuo, verifique o certificado de cliente com a CA que o servidor espera.

    bash
    # In a SERVER log: a client rejected the server's certificate (e.g. missing intermediate)
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:|Verify return code'
    # On a CLIENT: the server rejected your client certificate (mutual TLS)
  2. 2.

    Servidor: servir uma cadeia completa e publicamente confiável

    Para endpoints públicos, use um certificado de uma CA pública e configure a cadeia completa. Para endpoints internos, garanta que todos os clientes tenham a raiz interna.

    text
    # nginx: the chain clients need, leaf first
    ssl_certificate     /etc/nginx/tls/fullchain.pem;
    ssl_certificate_key /etc/nginx/tls/privkey.pem;
  3. 3.

    TLS mútuo: emitir os certificados de cliente pela CA confiável

    Verifique o certificado de cliente com a CA configurada no servidor (ssl_client_certificate no nginx) e envie o intermediário do cliente junto com o certificado dele.

    bash
    # Mutual TLS: is the client certificate issued by the CA the server trusts?
    openssl verify -CAfile server-trusted-client-ca.pem -untrusted client-intermediate.pem client.pem
    # Send the client's intermediate too, if it has one
    cat client.pem client-intermediate.pem > client-chain.pem
    curl --cert client-chain.pem --key client.key https://mtls.example.com/

Erros relacionados

Ver toda a base de erros de assinatura