Heim >Backend-Entwicklung >Golang >Warum erhalte ich den Fehler „Verbindung konnte nicht hergestellt werden:
Fehler: Zertifikatfelddiskrepanz in der Go-TLS-Verbindung
Beim Versuch, mit Go eine TLS-Verbindung zu einem MongoDB-Server herzustellen, kann es zu folgendem Fehler kommen: der folgende Fehler:
failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
Ursache:
Dieser Fehler tritt auf, wenn das TLS-Zertifikat des Servers zur Identifizierung auf das alte Common Name (CN)-Feld, aber auf Go's angewiesen ist Die Laufzeit verwendet standardmäßig Subject Alternative Names (SANs) für TLS-Verbindungen.
Lösung:
Es gibt zwei Hauptansätze zur Lösung dieses Problems:
1. Nutzen Sie SANs im Serverzertifikat:
2. CN-Matching vorübergehend deaktivieren:
Wenn Sie das Serverzertifikat nicht sofort neu generieren können, können Sie den CN-Matching vorübergehend deaktivieren, indem Sie die Umgebungsvariable festlegen:
GODEBUG=x509ignoreCN=0
Dies ist jedoch kein Problem langfristige Lösung und sollte nur zum vorübergehenden Herstellen von Verbindungen verwendet werden.
Code-Implementierung:
Wenn Sie das Problem in Ihrem Go-Code beheben möchten, stellen Sie sicher, dass die Das von Ihnen geladene Zertifikat enthält SANs, die mit den während der Verbindung verwendeten Hostnamen übereinstimmen. Hier ist eine aktualisierte Version des von Ihnen bereitgestellten Codeausschnitts:
<code class="go">const CONFIG_DB_CA = "/etc/ca-files/new-mongo.ca.crt" func main() { cer, err := tls.LoadX509KeyPair("/mongo-server.crt", "/mongo-server.key") if err != nil { log.Println(err) return } roots := x509.NewCertPool() ca, err := ioutil.ReadFile(CONFIG_DB_CA) if err != nil { fmt.Printf("Failed to read or open CA File: %s.\n", CONFIG_DB_CA) return } roots.AppendCertsFromPEM(ca) tlsConfig := &tls.Config{ Certificates: []tls.Certificate{cer}, RootCAs: roots, VerifyPeerCertificate: func(rawCerts [][]*x509.Certificate) error { for _, certs := range rawCerts { for _, cert := range certs { if len(cert.Subject.CommonName) > 0 { continue } for _, dns := range cert.DNSNames { if dns == "customhost" || dns == "customhost:port" { return nil } } return errors.New("certificate does not contain a SAN for the host") } } return errors.New("no valid certificate found") }, } conn, err := tls.Dial("tcp", "customhost:port", tlsConfig) if err != nil { fmt.Printf("failed to connect: %v.\n", err) return } err = conn.VerifyHostname("customhost") if err != nil { panic("Hostname doesn't match with certificate: " + err.Error()) } for i, cert := range conn.ConnectionState().PeerCertificates { prefix := fmt.Sprintf("CERT%d::", i+1) fmt.Printf("%sIssuer: %s\n", prefix, cert.Issuer) fmt.Printf("%sExpiry: %v\n", prefix, cert.NotAfter.Format(time.RFC850)) fmt.Printf("%sDNSNames: %v\n\n", prefix, cert.DNSNames) } fmt.Printf("Success!") }</code>
Dieser aktualisierte Code verwendet eine benutzerdefinierte VerifyPeerCertificate-Funktion, um zu überprüfen, ob das Zertifikat entweder einen CN enthält, der dem Hostnamen entspricht, oder ein SAN, das dem Hostnamen entspricht. Wenn ein passendes Zertifikat gefunden wird, gelingt die Verbindung.
Das obige ist der detaillierte Inhalt vonWarum erhalte ich den Fehler „Verbindung konnte nicht hergestellt werden:. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!