Aller au contenu
ecdsa.com
nginx error log / OpenSSLCLI OpenSSL

Message d’erreur

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

Également affiché sous la forme

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

nginx la consigne au niveau info sous la forme « SSL_do_handshake() failed (SSL: error:0A000418:SSL routines::tlsv1 alert unknown ca:SSL alert number 48) while SSL handshaking, client: … ». La CLI openssl affiche « …:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:… ». Les clients OpenSSL envoient cette alerte aussi bien pour les chaînes non approuvées que pour les chaînes auto-signées ou incomplètes.

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

Ce que cela signifie

L’autre extrémité de la connexion a interrompu le handshake avec l’alerte TLS 48 (unknown_ca) : elle n’a pas pu rattacher le certificat reçu à une AC qu’elle approuve. Dans un journal de serveur (comme ici, avec nginx), cela signifie qu’un client a refusé le certificat du serveur. Sur un client, cela signifie que le serveur a refusé le certificat client en TLS mutuel. Le côté qui consigne l’alerte n’est jamais celui qui a le problème : la cause tient au certificat envoyé au pair.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Déterminer quel certificat a été rejeté

    Si l’alerte figure dans un journal de serveur, testez la chaîne du serveur depuis l’extérieur ; sur un client en TLS mutuel, vérifiez le certificat client par rapport à l’AC attendue par le serveur.

    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.

    Serveur : servir une chaîne complète et approuvée publiquement

    Pour les points de terminaison publics, utilisez un certificat émis par une AC publique et configurez la chaîne complète. Pour les points de terminaison internes, assurez-vous que chaque client dispose de la racine interne.

    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 mutuel : émettre les certificats clients depuis l’AC approuvée

    Vérifiez le certificat client par rapport à l’AC configurée sur le serveur (ssl_client_certificate dans nginx), et envoyez le certificat intermédiaire du client avec son certificat.

    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/

Erreurs associées

Parcourir toute la base de données des erreurs de signature