Zum Inhalt springen
ecdsa.com
curl (OpenSSL backend)curl

Fehlermeldung

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

Auch ausgegeben als

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

curl auf OpenSSL-Basis (Linux, macOS Homebrew, Git for Windows) gibt diesen Text aus; neuere Releases (in unserem Test 8.22.0, während 8.14.1 noch den Text oben verwendete) formulieren ihn als „SSL certificate OpenSSL verify result: unable to get local issuer certificate (20)“ und hängen den Prüfcode von OpenSSL an. Mit Schannel gebautes curl unter Windows meldet dieselbe Situation als „schannel: SEC_E_UNTRUSTED_ROOT (0x80090325)“, libcurl auf GnuTLS-Basis (von git unter Debian und Ubuntu verwendet) als „server verification failed: certificate signer not trusted“. Tools auf Basis von libcurl, etwa PHP und git, geben den Teil nach „(60) “ mit ihrem eigenen Präfix aus.

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

Was der Fehler bedeutet

curl hat die Zertifikate des Servers erhalten, aber in seinem eigenen CA-Bundle nicht das Zertifikat gefunden, das das letzte Zertifikat der Kette ausgestellt hat. Das Zertifikat kann völlig gültig sein; curl kann es nur nicht mit einem Root-Zertifikat verketten, dem es vertraut, und verweigert deshalb die Verbindung (Exit-Code 60). Das fehlende Stück ist entweder ein Zwischenzertifikat, das der Server nicht mitgesendet hat, oder eine Root-CA, die dein Rechner nicht hat.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Nachsehen, was der Server tatsächlich sendet

    Liste die Zertifikate im Handshake auf. Erscheint nur eines (Tiefe 0) und ist sein Aussteller eine Zwischen-CA, ist die Konfiguration des Servers unvollständig und muss auf dem Server korrigiert werden. Endet die Kette bei einem firmeneigenen oder selbst erstellten Root-Zertifikat, fehlt dem Client dieses Root-Zertifikat.

    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.

    Server korrigieren: vollständige Kette ausliefern

    Konfiguriere den Webserver mit einem Bundle, das das Leaf-Zertifikat und danach jedes Zwischenzertifikat enthält. Das behebt den Fehler für alle Clients auf einmal, auch für mobile Apps und API-Clients, auf die du keinen Einfluss hast.

    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.

    Private Root-CA im Zertifikatsspeicher des Systems installieren

    Endet die Kette legitimerweise bei einem firmeneigenen oder internen Root-Zertifikat, füge dieses Root-Zertifikat dem Bundle des Betriebssystems hinzu. Hol es dir von deinem IT- oder Plattformteam oder direkt von der CA – niemals aus dem Zertifikat, das die fehlschlagende Verbindung präsentiert hat, denn genau dem kannst du noch nicht vertrauen.

    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.

    curl für einen Befehl oder eine Shell ein Bundle vorgeben

    --cacert fügt Vertrauen für einen einzelnen Aufruf hinzu, ohne das System anzufassen; CURL_CA_BUNDLE legt das Bundle für jeden curl-Aufruf in der Umgebung fest. Die Datei kann mehrere PEM-Zertifikate enthalten.

    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.

    CA-Bundle in minimalen Containern installieren

    Scheitern in einem Container sogar öffentliche Websites, hat das Image kein Bundle. Installiere ca-certificates im Image (oder kopiere /etc/ssl/certs/ca-certificates.crt aus einer Build-Stage), statt die Prüfung abzuschalten.

    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.

    Vorübergehende Diagnose: bestätigen, dass es ein Vertrauensproblem ist

    -k (--insecure) schaltet die Zertifikatsprüfung ab; eine erfolgreiche Antwort beweist also nur, dass der Netzwerkpfad funktioniert und es beim Fehler um Vertrauen geht. Lass es nie in Skripten stehen: Mit -k kann jeder auf dem Übertragungsweg den Traffic lesen und verändern, einschließlich Zugangsdaten und heruntergeladenem Code.

    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/

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen