dongsui5464 2018-12-12 22:31
浏览 112

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

I'm trying to create a TLS connection to a Cloud SQL database but I'm getting the following error when trying to prepare a statement:

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

Here is my setup code:

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条回答 默认 最新

  • dqdes60666 2018-12-12 22:34
    关注

    They key things I was missing was that the version of Go I was using was several months old and did not contain a specific fix and I did not specify the hostname associated with my Cloud SQL instance. I could not find an answer for this problem anywhere and found the solution myself by stepping through the TLS handshake code to see what went wrong and why.

    Versions of Go released before September 2018 would not correctly validate the hostnames that Cloud SQL uses in the TLS server certificate. Cloud SQL hostnames contain a ':' character and that caused the hostname and therefore the server certificate to be considered invalid. That has been fixed.

    The correct way to connect to a Cloud SQL instance using TLS is to follow these steps:

    1. Update your Go so that you have the change that allows validation of Cloud SQL hostnames that are in the server certificate.

    2. Create client certificates using the Cloud SQL console.

    3. Create the TLS connection as follows:

    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")
    
    评论

报告相同问题?

悬赏问题

  • ¥15 如何实现H5在QQ平台上的二次分享卡片效果?
  • ¥15 python爬取bilibili校园招聘网站
  • ¥30 求解达问题(有红包)
  • ¥15 请解包一个pak文件
  • ¥15 不同系统编译兼容问题
  • ¥100 三相直流充电模块对数字电源芯片在物理上它必须具备哪些功能和性能?
  • ¥30 数字电源对DSP芯片的具体要求
  • ¥20 antv g6 折线边如何变为钝角
  • ¥30 如何在Matlab或Python中 设置饼图的高度
  • ¥15 nginx中的CORS策略应该如何配置