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

Fehlermeldung

curl: (60) SSL certificate problem: self-signed certificate

Auch ausgegeben als

  • curl: (60) SSL certificate problem: self signed certificate
  • curl: (60) SSL certificate OpenSSL verify result: self-signed certificate (18)

OpenSSL ab 3.0 gibt „self-signed certificate“ aus; OpenSSL 1.1.1 schreibt „self signed certificate“. Neuere curl-Releases (in unserem Test 8.22.0) formulieren es als „SSL certificate OpenSSL verify result: self-signed certificate (18)“. Verwechsle das nicht mit „self-signed certificate in certificate chain“: Dort gibt es eine CA-Kette, die bei einem nicht vertrauenswürdigen Root-Zertifikat endet.

curl (OpenSSL backend) — CURLE_PEER_FAILED_VERIFICATION, X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT (18)

Was der Fehler bedeutet

Der Server hat ein einzelnes Zertifikat präsentiert, das mit seinem eigenen Schlüssel signiert ist (Aussteller gleich Subject), und genau dieses Zertifikat hat curl nicht in seinem Trust Store. Dahinter steht keine CA, die curl nachschlagen könnte, deshalb endet die Prüfung bei Tiefe 0. Das ist bei Entwicklungsservern und Appliances normal und lässt sich nie durch die Installation eines Zwischenzertifikats beheben.

Warum der Fehler auftritt

So behebst du den Fehler

  1. 1.

    Genau diesem Zertifikat vertrauen, nachdem du es geprüft hast

    Speichere für einen einzelnen internen Endpunkt das Zertifikat, bestätige seinen SHA-256-Fingerabdruck über einen vertrauenswürdigen Kanal (die Konsole des Geräts, den Admin, der es erstellt hat) und übergib es mit --cacert. curl akzeptiert dann für diesen Aufruf genau dieses Zertifikat und sonst keines.

    bash
    # Fetch the certificate once, compare its fingerprint out of band, then trust exactly that file
    openssl s_client -connect api.example.com:8443 -servername api.example.com </dev/null 2>/dev/null \
      | openssl x509 -out api.example.com.pem
    openssl x509 -in api.example.com.pem -noout -fingerprint -sha256
    curl --cacert api.example.com.pem https://api.example.com:8443/
  2. 2.

    Entwicklung: Zertifikate von einer lokalen CA ausstellen

    Mit einer lokalen CA (mkcert, step-ca oder einem selbst erstellten Root-Zertifikat) vertraust du einmalig einem einzigen Root-Zertifikat und stellst Zertifikate für beliebig viele Entwicklungshosts aus. Die Zertifikate sind dann nicht mehr selbstsigniert, deshalb verschwindet der Fehler überall, wo das Root-Zertifikat installiert ist.

    bash
    # mkcert creates a local CA, installs it into the system and browser stores,
    # and issues certificates signed by it (no longer self-signed)
    mkcert -install
    mkcert api.example.test localhost 127.0.0.1
  3. 3.

    Öffentliche Hosts: Zertifikat einer öffentlichen CA installieren

    Alles, was andere Menschen oder Clients von Dritten erreichen, sollte ein Zertifikat einer öffentlich vertrauenswürdigen CA präsentieren; ACME-Clients wie certbot, lego oder Caddy beziehen und erneuern es automatisch.

    bash
    # Public names: get a certificate from a public CA, e.g. with certbot (ACME)
    sudo certbot certonly --nginx -d api.example.com
  4. 4.

    Vorübergehende Diagnose: Dienst bei abgeschalteter Prüfung testen

    Mit -k überspringt curl die Zertifikatsprüfung; ein Status 200 bestätigt dann, dass nur das Vertrauen fehlt. Behalte es nicht bei: Ein selbstsigniertes Zertifikat, das ungeprüft akzeptiert wird, kann jederzeit gegen das eines Angreifers ausgetauscht werden, ohne dass curl es bemerkt.

    bash
    # Diagnostic only: confirms the service answers when certificate checks are skipped
    curl -sS -k -o /dev/null -w '%{http_code}\n' https://api.example.com:8443/

Verwandte Fehler

Gesamte Signaturfehler-Datenbank durchsuchen