Aller au contenu
ecdsa.com
curl (OpenSSL backend)curl

Message d’erreur

curl: (60) SSL certificate problem: unable to get local issuer certificate

Également affiché sous la forme

  • curl: (60) SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)
  • SSL certificate problem: unable to get local issuer certificate

Les builds de curl reposant sur OpenSSL (Linux, Homebrew sous macOS, Git for Windows) affichent ce texte ; les versions plus récentes (8.22.0 dans notre test, alors que 8.14.1 utilisait encore le texte ci-dessus) le formulent « SSL certificate OpenSSL verify result: unable to get local issuer certificate (20) », en ajoutant le code de vérification d’OpenSSL. curl compilé avec Schannel sous Windows signale la même situation par « schannel: SEC_E_UNTRUSTED_ROOT (0x80090325) », et la libcurl reposant sur GnuTLS (utilisée par git sous Debian et Ubuntu) par « server verification failed: certificate signer not trusted ». Les outils construits sur libcurl, comme PHP et git, affichent la partie qui suit « (60) » avec leur propre préfixe.

curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, X509_V_ERR_UNABLE_TO_GET_ISSUER_CERT_LOCALLY (20)

Ce que cela signifie

curl a reçu les certificats du serveur, mais n’a pas trouvé, dans son propre fichier d’AC, le certificat qui a émis le dernier de la chaîne. Le certificat est peut-être parfaitement valide ; curl ne parvient simplement pas à le rattacher à une racine qu’il approuve, et refuse donc la connexion (code de sortie 60). L’élément manquant est soit un certificat intermédiaire que le serveur a oublié d’envoyer, soit une AC racine absente de votre machine.

Pourquoi cela se produit

Comment corriger l’erreur

  1. 1.

    Voir ce que le serveur envoie réellement

    Listez les certificats du handshake. Si un seul apparaît (profondeur 0) et que son émetteur est une AC intermédiaire, la configuration du serveur est incomplète et doit être corrigée sur le serveur. Si la chaîne se termine par une racine d’entreprise ou faite maison, c’est au client qu’il manque cette racine.

    bash
    # Which certificates does the server send, and who issued the last one?
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:'
    #  0 s:CN=api.example.com
    #    i:C=US, O=Example Trust Services, CN=Example TLS Issuing CA   <- leaf only: intermediate missing
  2. 2.

    Corriger le serveur : servir la chaîne complète

    Configurez le serveur web avec un fichier qui contient le certificat feuille suivi de tous les certificats intermédiaires. Cela corrige l’erreur pour tous les clients à la fois, y compris les applications mobiles et les clients d’API que vous ne contrôlez pas.

    bash
    # Leaf first, then each intermediate in order; the root itself is optional
    cat api.example.com.crt intermediate.crt > fullchain.pem
    
    # nginx:   ssl_certificate     /etc/nginx/tls/fullchain.pem;
    # Apache:  SSLCertificateFile  /etc/apache2/tls/fullchain.pem
    # certbot: use live/<name>/fullchain.pem, never cert.pem
  3. 3.

    Installer une AC racine privée dans le magasin du système

    Lorsque la chaîne se termine légitimement par une racine d’entreprise ou interne, ajoutez cette racine au fichier d’AC du système d’exploitation. Procurez-vous la racine auprès de votre équipe informatique ou plateforme, ou auprès de l’AC elle-même ; jamais à partir du certificat présenté par la connexion qui échoue, puisque c’est précisément ce à quoi vous ne pouvez pas encore faire confiance.

    bash
    # Debian, Ubuntu, Alpine (the file must end in .crt)
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt
    sudo update-ca-certificates
    
    # RHEL, Fedora, Amazon Linux
    sudo cp corp-root-ca.pem /etc/pki/ca-trust/source/anchors/
    sudo update-ca-trust
  4. 4.

    Indiquer à curl un fichier d’AC pour une commande ou un shell

    --cacert étend la confiance le temps d’un seul appel, sans toucher au système ; CURL_CA_BUNDLE définit le fichier d’AC de tous les appels curl de l’environnement. Le fichier peut contenir plusieurs certificats PEM.

    bash
    curl --cacert corp-root-ca.pem https://api.example.com/
    
    # or for every curl command in this shell (a file may hold several PEM certificates)
    export CURL_CA_BUNDLE=/opt/certs/corp-and-public-roots.pem
  5. 5.

    Installer le fichier d’AC dans les conteneurs minimaux

    Si même les sites publics échouent dans un conteneur, l’image n’a pas de fichier d’AC. Installez ca-certificates dans l’image (ou copiez /etc/ssl/certs/ca-certificates.crt depuis une étape de build) plutôt que de désactiver la vérification.

    bash
    # Debian/Ubuntu-based images
    apt-get update && apt-get install -y --no-install-recommends ca-certificates
    # Alpine
    apk add --no-cache ca-certificates
  6. 6.

    Diagnostic temporaire : confirmer qu’il s’agit d’un problème de confiance

    -k (--insecure) désactive la vérification des certificats : une réponse réussie prouve donc seulement que le chemin réseau fonctionne et que l’échec tient à la confiance. Ne le laissez jamais dans des scripts : avec -k, n’importe qui sur le chemin peut lire et modifier le trafic, y compris les identifiants et le code téléchargé.

    bash
    # Diagnostic only: if this works, the problem is trust, not the network.
    curl -sS -k -o /dev/null -w '%{http_code}\n' https://api.example.com/

Erreurs associées

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