PostgreSQL pq打开不成功:x509:由未知权限签名的证书

时间:2014-05-12 17:38:01

标签: mysql sql postgresql go postgresql-9.1

此代码有什么问题?

http://godoc.org/github.com/lib/pq

* dbname - The name of the database to connect to
* user - The user to sign in as
* password - The user's password
* host - The host to connect to. Values that start with / are for unix domain sockets. (default is localhost)
* port - The port to bind to. (default is 5432)
* sslmode - Whether or not to use SSL (default is require, this is not the default for libpq)
* fallback_application_name - An application_name to fall back to if one isn't provided.
* connect_timeout - Maximum wait for connection, in seconds. Zero or not specified means wait indefinitely.

所以我只需键入以下内容并期望看到与PostgreSQL连接的成功连接,但似乎无效。语法有什么问题,因为sql.Open的语法与我用于MySQL的语法不同。

"dbname=%s user=%s password=%s host=%s port=%s sslmode=%s connect_timeout=%s"

此代码的错误消息为x509: certificate signed by unknown authority

package main

import (
  "database/sql"
  "fmt"
  "log"
  "os"

  _ "github.com/lib/pq"
)

func main() {
  db := Get()
  defer db.Close()
  err := db.Ping()
  if err == nil {
    log.Fatalln("db.Ping is successful!")
  } else {
    log.Fatalln(err)
  }
}

func Get() *sql.DB {
  const (
    AWS_DB         = "mydb"
    AWS_USER       = "rootuser"
    AWS_PASS       = "1234"
    AWS_HOST       = "redshift.amazonaws.com"
    AWS_PORT       = "5439"
    AWS_SSL        = "verify-full"
    AWS_TIME       = "2"
    AWS_ACCESS_KEY = "abcd"
    AWS_SECRET_KEY = "efgh"
  )
  db, err := sql.Open("postgres",
    fmt.Sprintf("dbname=%s user=%s password=%s host=%s port=%s sslmode=%s connect_timeout=%s",
      AWS_DB,
      AWS_USER,
      AWS_PASS,
      AWS_HOST,
      AWS_PORT,
      AWS_SSL,
      AWS_TIME,
    ))
  if err != nil {
    log.Fatalln("Error:")
    log.Fatalln(err)
    os.Exit(1)
  }
  return db
}

2 个答案:

答案 0 :(得分:1)

由于错误消息告知您的主机不信任签署了数据库服务器证书的证书颁发机构(CA)。

如果您能够启用InsecureSkipVerify,请设置sslmode=require。这将阻止客户端验证服务器的证书链和主机名(但仍将使用SSL)。

如果这不是一个选项,则需要将CA添加到主机可信CA.这取决于您的操作系统。在Linux上,当您将其添加到/etc/ssl/cert.pem时很有可能。

显然,PostgreSQL驱动程序不允许指定自定义tls.Config,这会使事情变得更加灵活。在source code中,您可以看到它始终使用tls.Config{}。它不提供设置自定义RootCAs的选项。

答案 1 :(得分:0)

您需要传递sslrootcert参数。您的代码将成为

db, err := sql.Open("postgres",
fmt.Sprintf("dbname=%s user=%s password=%s host=%s port=%s sslmode=%s sslrootcert=%s connect_timeout=%s",
  AWS_DB,
  AWS_USER,
  AWS_PASS,
  AWS_HOST,
  AWS_PORT,
  AWS_SSL,
  AWS_SSL_CERT_PATH,
  AWS_TIME,
))

其中AWS_SSL_CERT_PATH="/path/to/the/certificate"

您可以找到更多信息以及下载证书here的链接。