Fehlermeldung
remote error: tls: handshake failure
In HTTP-Clients lautet die Zeile „Get \"https://…\": remote error: tls: handshake failure“. Dieselbe Form „remote error: tls: <alert>“ verwendet Go auch auf Servern, in Logzeilen „http: TLS handshake error from …“, wenn ein Client einen Alert sendet.
Go crypto/tls client — the server sent TLS alert 40 (handshake_failure)
Was der Fehler bedeutet
„remote error“ bedeutet, dass die Gegenseite einen TLS-Alert gesendet hat; hier hat der Server dem Go-Client den Alert 40 (handshake_failure) gesendet. Der Server hat die von Go angebotenen Parameter (Cipher Suites, Gruppen, Signaturalgorithmen) abgelehnt oder ein Client-Zertifikat verlangt, das Go nicht gesendet hat. Go kann nicht erkennen, was davon zutrifft; das Log des Servers schon.
Warum der Fehler auftritt
Keine gemeinsame Cipher Suite
häufigDie Standardliste des Go-Clients enthält keine Suites mit RSA-Schlüsselaustausch, CBC oder 3DES; Server, die auf solche Suites beschränkt sind, haben mit ihr nichts gemeinsam.
Der Server verlangt ein Client-Zertifikat
häufigServer mit TLS 1.2, die Mutual TLS verlangen, beantworten ein fehlendes Zertifikat oft mit handshake_failure.
SNI wird nicht akzeptiert
gelegentlichEine Verbindung per IP ohne ServerName oder mit einem Namen, den der Server nicht bedient, kann bei CDNs und Proxys den Alert auslösen.
So behebst du den Fehler
- 1.
Cipher Suites vergleichen
tls.CipherSuites() listet auf, was Go für sicher hält und anbietet; vergleiche das mit der Konfiguration des Servers.
go // What does this Go client offer by default? for _, s := range tls.CipherSuites() { fmt.Println(s.Name) } - 2.
Client-Zertifikat für Mutual TLS senden
Lade Zertifikat und Schlüssel mit tls.LoadX509KeyPair und setze sie in tls.Config.Certificates.
go // Mutual TLS: present a client certificate cert, err := tls.LoadX509KeyPair("client.pem", "client.key") if err != nil { log.Fatal(err) } client := &http.Client{Transport: &http.Transport{TLSClientConfig: &tls.Config{ Certificates: []tls.Certificate{cert}, }}} - 3.
Eigener Server: Suites modernisieren
TLS 1.3 und Suites für TLS 1.2 auf Basis von ECDHE funktionieren mit jedem aktuellen Go-Release.
text Server side: enable TLS 1.3 and TLS 1.2 ECDHE suites with AES-GCM or ChaCha20-Poly1305.