エラー: Go TLS 接続の証明書フィールドの不一致
Go を使用して MongoDB サーバーへの TLS 接続を確立しようとすると、次のような問題が発生する場合があります。次のエラー:
failed to connect: x509: certificate relies on legacy Common Name field, use SANs or temporarily enable Common Name matching with GODEBUG=x509ignoreCN=0
原因:
このエラーは、サーバーの TLS 証明書が識別のために従来の Common Name (CN) フィールドに依存しているが、Go のランタイムのデフォルトでは、TLS 接続にサブジェクト代替名 (SAN) を使用します。
解決策:
この問題を解決するには、主に 2 つのアプローチがあります:
1.サーバー証明書で SAN を利用する:
2. CN マッチングを一時的に無効にする:
サーバー証明書をすぐに再生成できない場合は、環境変数を設定して CN マッチングを一時的に無効にすることができます:
GODEBUG=x509ignoreCN=0
ただし、これは長期的な解決策であり、接続を一時的に確立する場合にのみ使用してください。
コードの実装:
Go コードで問題を修正することを選択した場合は、ロードする証明書には、接続中に使用されたホスト名と一致する SAN が含まれています。提供したコード スニペットの更新バージョンは次のとおりです。
<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>
この更新されたコードは、カスタム VerifyPeerCertificate 関数を使用して、証明書にホスト名と一致する CN またはホスト名と一致する SAN が含まれていることを確認します。適切な証明書が見つかった場合、接続は成功します。
以上が「接続に失敗しました: x509: 証明書はレガシー共通名フィールドに依存しています。SAN を使用するか、GODEBUG=x509ignoreCN=0 で共通名一致を一時的に有効にしてください」エラーが発生するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。