使用Go如何创建与Cloud SQL数据库的TLS连接?

5

我正在尝试创建与Cloud SQL数据库的TLS连接,但是当我尝试准备语句时,出现了以下错误:

x509: cannot validate certificate for <cloud sql instance ip>
      because it doesn't contain any IP SANs

这是我的设置代码:

rootCertPool := x509.NewCertPool()

pem, err := ioutil.ReadFile("/path/server-ca.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("/path/client-cert.pem",
                                  "/path/client-key.pem")
if err != nil {
    log.Fatal(err)
}

clientCert = append(clientCert, certs)
mysql.RegisterTLSConfig("custom", &tls.Config{
    RootCAs: rootCertPool,
    Certificates: clientCert,
})

db, err := sql.Open("mysql",
        "<user>:<password>@tcp(<cloud sql ip>:3306)/<db_name>?tls=custom")
1个回答

8
我所缺少的关键是我使用的Go版本已经过时了数月,没有包含一个特定的修复程序,并且我没有指定与我的Cloud SQL实例相关联的主机名。我无法在任何地方找到这个问题的答案,通过逐步分析TLS握手代码来找出问题出在哪里以及为什么,我自己找到了解决方案。
在2018年9月之前发布的Go版本将无法正确验证Cloud SQL在TLS服务器证书中使用的主机名。 Cloud SQL主机名包含“:”字符,这导致主机名和因此服务器证书被视为无效。这已得到修复。
使用TLS连接到Cloud SQL实例的正确方法如下:
1. 更新您的Go,以便您拥有允许验证服务器证书中的Cloud SQL主机名的更改。 2. 使用Cloud SQL控制台创建客户端证书。 3. 创建TLS连接,如下所示:
import (
    "crypto/tls"
    "crypto/x509"
    "database/sql"
    "github.com/go-sql-driver/mysql"
    "io/ioutil"
)

rootCertPool := x509.NewCertPool()

pem, err := ioutil.ReadFile("/path/server-ca.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("/path/client-cert.pem",
                                  "/path/client-key.pem")
if err != nil {
    log.Fatal(err)
}

clientCert = append(clientCert, certs)
mysql.RegisterTLSConfig("custom", &tls.Config{
    RootCAs: rootCertPool,
    Certificates: clientCert,
    ServerName: "<gcp-project-id>:<cloud-sql-instance>", // hostname
})

db, err := sql.Open("mysql",
        "<user>:<password>@tcp(<cloud sql ip>:3306)/<db_name>?tls=custom")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接