Как создать соединение TLS с базой данных Cloud SQL с помощью Go? - PullRequest
0 голосов
/ 13 декабря 2018

Я пытаюсь создать соединение TLS с базой данных Cloud SQL, но получаю следующую ошибку при попытке подготовить оператор:

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 Ответ

0 голосов
/ 13 декабря 2018

Ключевыми вещами, которые мне не хватало, было то, что используемая мной версия Go была несколько месяцев назад и не содержала определенного исправления, и я не указал имя хоста, связанное с моим экземпляром Cloud SQL.Я нигде не смог найти ответ на эту проблему и сам нашел решение, пройдя по коду рукопожатия TLS, чтобы увидеть, что пошло не так и почему.

Версии Go, выпущенные до сентября 2018 года, не будут правильно проверять имена хостов, которыеОблачный SQL использует в сертификате сервера TLS.Имена хостов облачного SQL содержат символ «:», в результате чего имя хоста и, следовательно, сертификат сервера считаются недействительными.Это было исправлено.

Правильный способ подключения к экземпляру Cloud SQL с использованием TLS заключается в следующем:

  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")
...