ホームページ >バックエンド開発 >Golang >「接続に失敗しました: x509: 証明書はレガシー共通名フィールドに依存しています。SAN を使用するか、GODEBUG=x509ignoreCN=0 で共通名一致を一時的に有効にしてください」エラーが発生するのはなぜですか?

「接続に失敗しました: x509: 証明書はレガシー共通名フィールドに依存しています。SAN を使用するか、GODEBUG=x509ignoreCN=0 で共通名一致を一時的に有効にしてください」エラーが発生するのはなぜですか?

Barbara Streisand
Barbara Streisandオリジナル
2024-10-28 12:10:30714ブラウズ

Why am I encountering the

エラー: 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 を利用する:

  • サーバーへの接続に使用されるホスト名または IP アドレスと一致する SAN を使用してサーバー証明書を再生成します。
  • これは次の方法で実現できます。 OpenSSL やサードパーティの認証局などのツール。

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。