【问题标题】:Golang x509: Certificate is valid for *.<DNS> not <DB_hostname>Golang x509:证书对 *.<DNS> 而不是 <DB_hostname> 有效
【发布时间】:2022-10-24 19:39:54
【问题描述】:

我正在尝试通过 Golang 使用 SSL 连接到 MySQL DB,并且收到此错误消息

x509:证书对 *. 有效,而不是 <DB_hostname>

我已经使用本教程创建了证书 https://www.devdungeon.com/content/creating-self-signed-ssl-certificates-openssl

创建 TLSConf 的函数:

func createTLSConf() tls.Config {

    rootCertPool := x509.NewCertPool()
    pem, err := ioutil.ReadFile("certificate.pem")
    if err != nil {
        log.Fatal(err)
    }
    if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
        log.Fatal("Failed to append PEM.")
    }
    clientCert := make([]tls.Certificate, 0, 1)

    certs, err := tls.LoadX509KeyPair("certificate.pem", "privkey.pem")
    if err != nil {
        log.Fatal(err)
    }

    clientCert = append(clientCert, certs)

    return tls.Config{
        RootCAs:            rootCertPool,
        Certificates:       clientCert,
        InsecureSkipVerify: false,
    }
}

连接到数据库

    tlsConf := createTLSConf()  
    err := mysql.RegisterTLSConfig("custom", &tlsConf)

    if err != nil {
        log.Printf("Error %s when RegisterTLSConfig\n", err)
        return
    }

    dsn := fmt.Sprintf("%s:%s@tcp(%s)/%s?tls=custom", "user", "pass", "db_host", "db_name")
    db, err := sql.Open("mysql", dsn)

    if err != nil {
        log.Printf("Error %s when opening DB\n", err)
        log.Printf("%s", dsn)
        return
    }

使用连接

    defer db.Close()

    e := db.Ping()
    fmt.Println(dsn, e)

    db.Close()

输出:

<user>:<pass>@tcp(<db_host>)/<db_name>?tls=custom x509: certificate is valid for *.abc-xy-pxc, not <db_host>

abc-xy 是 db_host 的一部分,abc_xy 也是 db_name,确定它是否重要

将 InsecureSkipVerify 更改为 true 时,输出如下所示:

[mysql] 2022/10/21 22:31:27 packets.go:37: remote error: tls: unknown certificate authority

知道我怎样才能让它工作吗?

编辑:

Sooo,我不知道为什么,但是使用客户端证书删除部分代码并将 InsecureSkipVerify 更改为 true 解决了这个问题:

func createTLSConf() tls.Config {

    rootCertPool := x509.NewCertPool()
    pem, err := ioutil.ReadFile("certificate.pem")
    if err != nil {
        log.Fatal(err)
    }
    if ok := rootCertPool.AppendCertsFromPEM(pem); !ok {
        log.Fatal("Failed to append PEM.")
    }

    return tls.Config{
        RootCAs:            rootCertPool,
        InsecureSkipVerify: true, // needed for self signed certs
    }
}

【问题讨论】:

  • 听起来您的 MySQL 客户端库不允许/支持通配符证书。证书最初是如何生成的?
  • 我对 SSL 证书很陌生,所以我不确定这是否是您问题的答案,但它就像那样 1. openssl genrsa -out privkey.pem 2048 2. openssl req -new -key privkey.pem -输出signreq.csr 3.openssl x509 -req -days 365 -in signreq.csr -signkey privkey.pem -out certificate.pem

标签: go ssl ssl-certificate


【解决方案1】:

嘿,我也是 Go 新手,但您可以尝试一下。考虑到我的回答可能不是最好的,但我试图通过帮助和询问来更加积极。您可以在终端中生成证书然后使用它们。

在项目目录的终端中运行它。 (你的 main.go 所在的位置)和 /usr/local/go/src/crypto/tls/generate_cert.go 应该是安装 Go 标准库的目录。

go run /usr/local/go/src/crypto/tls/generate_cert.go --rsa-bits=2048 --host=localhost

打开数据库连接返回错误(如果有):

func openDB(dsn string) (*sql.DB, error){
   db, err := sql.Open("mysql",dsn)
   if err!= nil{
      return nil,err
   }
   if err = db.Ping();err!=nil{
      return nil,err
   }
}

然后你必须配置你的服务器设置。您将拥有一个带有 pem 文件的 http.Server。

声明一个 crypto/tls.Config 变量,其中仅使用具有装配实现的椭圆曲线。

tlsConfig := &tls.Config{
   CurvePreferences:[]tls.CurveID{tls.X25519,tls.CurveP256}
}

然后声明你的服务器。

yourServer := &http.Server{
   //Your configs
   TLSConfig : tlsConfig,
   //Your other configs if any
}

现在我们已经创建了具有特定 TLS 配置的服务器。您所要做的就是现在运行您的服务器。但是,您必须使用 ListenAndServeTLS(first arg = cert,second arg = key) 更新服务器的方法

err = srv.ListenAndServeTLS(<Location of your cert.pem>, <Location of your key.pem>)

【讨论】:

  • 我使用您的提示创建了一些东西,我不确定我是否做对了所有事情,但我收到了以下错误消息:listen tcp x.y.z.a:443: bind: cannot assign requested address
猜你喜欢
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
  • 2019-06-15
  • 2021-03-05
  • 2021-11-21
  • 2020-12-06
  • 2016-12-31
  • 2019-05-10
相关资源
最近更新 更多