PostgreSQL pq打开失败:x509:证书由未知机构签名。

huangapple go评论94阅读模式
英文:

PostgreSQL pq Open not successful: x509: certificate signed by unknown authority

问题

这段代码有一个错误,错误信息是x509: certificate signed by unknown authority。这个错误通常是由于SSL证书的问题引起的。

在连接PostgreSQL时,你使用了sslmode=verify-full参数来启用SSL连接。然而,你的代码中没有提供正确的SSL证书,导致连接失败。

要解决这个问题,你可以尝试以下几种方法:

  1. 确保你的代码中提供了正确的SSL证书路径。你可以通过设置sslrootcert参数来指定SSL证书的路径。

  2. 如果你不需要使用SSL连接,可以将sslmode参数设置为disable,这样就可以禁用SSL连接。

  3. 如果你使用的是自签名的SSL证书,你可以将sslmode参数设置为allow,这样就可以允许连接到未知颁发机构的证书。

你可以根据你的具体情况选择适合的解决方案来修复这个问题。

英文:

What is wrong with this code?

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.

So I just type the following and expected to see the successful connection with the PostgreSQL connection but seems to not work. Is there anything wrong with the syntax, since the syntax for sql.Open is different than the one that I used for MySQL.

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

And the error message from this code is 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
}

答案1

得分: 2

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

如果您可以接受启用InsecureSkipVerify,那么请将sslmode设置为require。这将阻止客户端验证服务器的证书链和主机名(但仍将使用SSL)。

如果这不是一个选项,您需要将CA添加到主机的受信任CA列表中。这取决于您的操作系统。在Linux上,如果您将其添加到/etc/ssl/cert.pem中,有很大的机会成功。

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

英文:

As the error message tells your host is not trusting the certificate authority (CA) which signed the certificate of your database server.

If you can afford to enable InsecureSkipVerify then set sslmode=require. This will prevent the client to verify the server's certificate chain and host name (but SSL will still be used).

If this is not an option you need to add the CA to your hosts trusted CAs. This depends on your OS. On Linux you have good chances when you add it to /etc/ssl/cert.pem.

Obviously the PostgreSQL driver does not allow to specify a custom tls.Config which would make things more flexible. In the source code you can see that it always uses tls.Config{}. It does not provide an option to set custom RootCAs.

答案2

得分: 1

你需要传递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"

你可以在这里找到更多信息和下载证书的链接。

英文:

You need to pass sslrootcert parameter. Your code will become

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,
))

where AWS_SSL_CERT_PATH="/path/to/the/certificate"

You can find more information and the link to download the certificate here.

huangapple
  • 本文由 发表于 2014年5月13日 01:38:01
  • 转载请务必保留本文链接:https://go.coder-hub.com/23615411.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定