Home  >  Article  >  Backend Development  >  Why am I encountering the \"failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0\" error w

Why am I encountering the \"failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0\" error w

Barbara Streisand
Barbara StreisandOriginal
2024-10-28 12:10:30609browse

Why am I encountering the

Error: Certificate Field Discrepancy in Go TLS Connection

When attempting to establish a TLS connection to a MongoDB server with Go, you may encounter the following error:

failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0

Cause:

This error occurs when the server's TLS certificate relies on the legacy Common Name (CN) field for identification, but Go's runtime defaults to using Subject Alternative Names (SANs) for TLS connections.

Solution:

There are two main approaches to resolving this issue:

1. Utilize SANs in the Server Certificate:

  • Regenerate the server certificate with SANs that match the hostnames or IP addresses used to connect to the server.
  • This can be achieved using tools like OpenSSL or third-party certificate authorities.

2. Disable CN Matching Temporarily:

If you cannot regenerate the server certificate immediately, you can temporarily disable CN matching by setting the environment variable:

GODEBUG=x509ignoreCN=0

However, this is not a long-term solution and should be used only to establish connections temporarily.

Code Implementation:

If you choose to fix the issue in your Go code, ensure that the certificate you load contains SANs that match the hostnames used during the connection. Here's an updated version of the code snippet you provided:

<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>

This updated code uses a custom VerifyPeerCertificate function to verify that the certificate contains either a CN that matches the hostname or a SAN that matches the hostname. If a suitable certificate is found, the connection will succeed.

The above is the detailed content of Why am I encountering the \"failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0\" error w. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn