Heim >Backend-Entwicklung >Golang >Warum erhalte ich den Fehler „Verbindung konnte nicht hergestellt werden:

Warum erhalte ich den Fehler „Verbindung konnte nicht hergestellt werden:

Barbara Streisand
Barbara StreisandOriginal
2024-10-28 12:10:30716Durchsuche

Why am I encountering the

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:

  • Generieren Sie das Serverzertifikat mit SANs neu, die mit den Hostnamen oder IP-Adressen übereinstimmen, die für die Verbindung zum Server verwendet werden.
  • Dies kann erreicht werden mit Tools wie OpenSSL oder Zertifizierungsstellen von Drittanbietern.

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!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn