Fehlermeldung
SSL_do_handshake() failed (SSL: error:0A000418:SSL routines::tlsv1 alert unknown ca:SSL alert number 48)
Auch ausgegeben als
- SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca
- error:0A000418:SSL routines::tlsv1 alert unknown ca
nginx protokolliert ihn mit dem Log-Level info als „SSL_do_handshake() failed (SSL: error:0A000418:SSL routines::tlsv1 alert unknown ca:SSL alert number 48) while SSL handshaking, client: …“. Die OpenSSL-CLI gibt „…:SSL routines:ssl3_read_bytes:tlsv1 alert unknown ca:…“ aus. OpenSSL-Clients senden diesen Alert gleichermaßen bei nicht vertrauenswürdigen, selbstsignierten und unvollständigen Ketten.
nginx error log / OpenSSL — TLS alert 48 (unknown_ca) received from the peer
Was der Fehler bedeutet
Die andere Seite der Verbindung hat den Handshake mit dem TLS-Alert 48 (unknown_ca) abgebrochen, weil sich das empfangene Zertifikat nicht mit einer CA verketten ließ, der sie vertraut. Im Log eines Servers (wie hier von nginx) bedeutet das, dass ein Client das Zertifikat des Servers abgelehnt hat. Auf einem Client bedeutet es, dass der Server bei Mutual TLS das Client-Zertifikat abgelehnt hat. Die Seite, die den Alert protokolliert, ist nie die Seite mit dem Problem: Die Ursache liegt bei dem Zertifikat, das an die Gegenstelle gesendet wurde.
Warum der Fehler auftritt
Server-Log: Clients vertrauen dem Serverzertifikat nicht
häufigSelbstsignierte Zertifikate oder Zertifikate einer privaten CA, ein fehlendes Zwischenzertifikat oder ein Zertifikat für den internen Gebrauch, das öffentlichen Clients präsentiert wird. Jeder fehlschlagende Client (curl, API-Clients, Monitoring) hinterlässt eine solche Zeile.
Client-Seite: Der Server vertraut deinem Client-Zertifikat nicht
häufigBei Mutual TLS stammt das Client-Zertifikat von einer CA, die der Server laut seiner Konfiguration nicht akzeptiert, oder der Client lässt sein Zwischenzertifikat weg.
Scanner und Probes
gelegentlichScanner, die das ganze Internet absuchen, verbinden sich, ohne irgendetwas zu vertrauen, und brechen mit diesem Alert ab; vereinzelte Zeilen von unbekannten Adressen sind harmlos.
So behebst du den Fehler
- 1.
Herausfinden, welches Zertifikat abgelehnt wurde
Steht die Zeile im Log eines Servers, teste die Kette des Servers von außen; auf einem Client mit Mutual TLS prüfe das Client-Zertifikat gegen die CA, die der Server erwartet.
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.
Server: vollständige, öffentlich vertrauenswürdige Kette ausliefern
Verwende für öffentliche Endpunkte ein Zertifikat einer öffentlichen CA und konfiguriere die vollständige Kette. Stelle bei internen Endpunkten sicher, dass jeder Client das interne Root-Zertifikat hat.
text # nginx: the chain clients need, leaf first ssl_certificate /etc/nginx/tls/fullchain.pem; ssl_certificate_key /etc/nginx/tls/privkey.pem; - 3.
Mutual TLS: Client-Zertifikate von der vertrauenswürdigen CA ausstellen
Prüfe das Client-Zertifikat gegen die CA, die im Server konfiguriert ist (ssl_client_certificate in nginx), und sende das Zwischenzertifikat des Clients zusammen mit seinem Zertifikat.
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/
Verwandte Fehler
SSL routines:ssl3_read_bytes:ssl/tls alert bad certificateOpenSSLSSL routines:ssl3_read_bytes:tlsv13 alert certificate requiredOpenSSL (client side)curl: (60) SSL certificate problem: unable to get local issuer certificatecurl (OpenSSL backend)remote error: tls: unknown certificate authorityGo crypto/tls