postgresql - 与 Google Cloud Postgres 的 SSL 连接

标签 postgresql go ssl pgx

我已将我的 postgres 数据库迁移到 Google Cloud SQL。
如果没有启用 SSL,我可以毫无问题地连接。
但是我正在努力让 SSL 连接正常工作。
我正在使用 pgx 池驱动程序。
我已经下载了服务器、客户端和私钥 pem 文件。
我得到的错误信息是

failed to write startup message (x509: certificate signed by unknown authority)

    serverCert, err := ioutil.ReadFile("server-ca.pem")
    if err != nil {
        log.Fatal(err)
    }

    clientCert, err := ioutil.ReadFile("client-cert.pem")
    if err != nil {
        log.Fatal(err)
    }

    caCertPool := x509.NewCertPool()
    ok := caCertPool.AppendCertsFromPEM(serverCert)
    ok = caCertPool.AppendCertsFromPEM(clientCert)
    fmt.Println(ok)

    keypair, err := tls.LoadX509KeyPair("server-client-certs.pem", "client-key.pem")
    if err != nil {
        log.Fatal(err)
    }

    tlsConfig := &tls.Config{
        Certificates: []tls.Certificate{keypair},
        ServerName:   s.Host,
        ClientCAs:    caCertPool,
        ClientAuth:   tls.RequestClientCert,
        GetClientCertificate: func(*tls.CertificateRequestInfo) (*tls.Certificate, error) {
            return &keypair, nil
        },
    }

    connectionString := fmt.Sprintf("host=%s port=%d user=%s password=%s dbname=%s connect_timeout=%d sslmode=require",
        s.Host, s.Port, s.User, s.Password, s.Name, s.ConnectTimeout)

    connConfig, err := pgxpool.ParseConfig(connectionString)
    if connConfig != nil {
        connConfig.ConnConfig.TLSConfig = tlsConfig
    }

    var pool *pgxpool.Pool

    pool, err = pgxpool.ConnectConfig(context.Background(), connConfig)

最佳答案

您的 tls.Config 有很多问题。 , 我推荐你阅读 the docs了解每个字段的作用。
构建 CA 池:CertPool应该包含用于签署服务器证书的 CA 证书,这是 server-ca.pem .它不需要客户端证书。
指定 CA 池:ClientCAs是服务器用来验证客户端证书的 CA 池,它只在服务器端使用。您需要在 RootCAs 中指定您的 CA 池.
这是您的问题的原因,您的客户端正在尝试验证服务器证书但不知道其 CA。
其他领域:ClientAuth是用于强制执行特定客户端证书行为的服务器端字段,在客户端设置时无效。GetClientCertificate不需要,只要 Certificates已设置,您可以摆脱它。
您还应该仔细检查您的客户证书。您正在加载 key 对 server-client-certs.pem/client-key.pem .如果这些确实是客户端证书和 key ,那么您应该没问题。
假设您可以连接到数据库主机(在防火墙中列入白名单),您的证书都是正确的(服务器的 CA 证书、客户端证书和客户端 key ),此处列出的更正将使您能够连接。
毕竟,您的代码变为:

    caCertPool := x509.NewCertPool()
    ok := caCertPool.AppendCertsFromPEM(serverCert)
    fmt.Println(ok)

    keypair, err := tls.LoadX509KeyPair("server-client-certs.pem", "client-key.pem")
    if err != nil {
        log.Fatal(err)
    }

    tlsConfig := &tls.Config{
        Certificates: []tls.Certificate{keypair},
        ServerName:   s.Host,
        RootCAs:      caCertPool,
    }
最后注:server-ca.pem不是服务器证书,它是用于签署服务器证书的 CA 证书。客户端不会提前知道服务器证书,它会在 TLS 握手期间接收它。

关于postgresql - 与 Google Cloud Postgres 的 SSL 连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63131383/

相关文章:

mongodb - Mongodb collection.Find()返回过滤后的数据

arrays - 如何将 JSON 数组建模为 protobuf 定义

string - 是否可以针对反引号键入断言?

ssl - 没有让我们加密的Traefik SSL

iphone - 在 iPhone 的钥匙串(keychain)中存储和访问 x509 证书

postgresql - 如何在 postgresql 中使用 jsonb_set 更新空的 jsonb 列?

postgresql - 使用游标执行函数时出错

sql - 高级查询日期分组困境

ruby-on-rails - 不同本地数据库配置 Rails

python - python SMTP 服务器中的 AUTH LOGIN 问题