Erreur : écart de champ de certificat dans la connexion Go TLS
Lorsque vous essayez d'établir une connexion TLS à un serveur MongoDB avec Go, vous pouvez rencontrer l'erreur suivante :
failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
Cause :
Cette erreur se produit lorsque le certificat TLS du serveur s'appuie sur l'ancien champ Common Name (CN) pour l'identification, mais que celui de Go par défaut, le runtime utilise des noms alternatifs de sujet (SAN) pour les connexions TLS.
Solution :
Il existe deux approches principales pour résoudre ce problème :
1. Utiliser les SAN dans le certificat de serveur :
2. Désactiver temporairement la correspondance CN :
Si vous ne pouvez pas régénérer le certificat du serveur immédiatement, vous pouvez désactiver temporairement la correspondance CN en définissant la variable d'environnement :
GODEBUG=x509ignoreCN=0
Cependant, ce n'est pas un solution à long terme et ne doit être utilisée que pour établir des connexions temporairement.
Mise en œuvre du code :
Si vous choisissez de résoudre le problème dans votre code Go, assurez-vous que le Le certificat que vous chargez contient des SAN qui correspondent aux noms d'hôte utilisés lors de la connexion. Voici une version mise à jour de l'extrait de code que vous avez fourni :
<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>
Ce code mis à jour utilise une fonction VerifyPeerCertificate personnalisée pour vérifier que le certificat contient soit un CN qui correspond au nom d'hôte, soit un SAN qui correspond au nom d'hôte. Si un certificat approprié est trouvé, la connexion réussira.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!