为了账号安全,请及时绑定邮箱和手机立即绑定

pgx tls 连接抛出有效证书的客户端证书无效错误

pgx tls 连接抛出有效证书的客户端证书无效错误

Go
aluckdog 2023-02-14 15:37:24
我正在尝试使用 pgx 与 postgres 10 db 建立 TLS 连接。我的连接字符串类似于:"host='my-host.com' port='5432' dbname='my-db' user='my-db-user' sslmode='verify-full' sslcert='/path/to/db_user.crt' sslkey='/path/to/db_user.key' sslrootcert='/path/to/ca_roots.pem'"当我psql在命令行上直接运行它时,它可以工作,因此证书和密钥文件必须有效。db_user.crt并且db_user.key都是 PEM 文件。(命令行也适用于sslmode='verify-full',因此 rootcert 也应该没问题)但是当我pgx用那个连接字符串初始化一个池时,它失败了:FATAL:连接需要有效的客户端证书(SQLSTATE 28000)去期待 PEM 以外的东西吗?还是应该使用 pgx 初始化 ssl 证书和密钥对的不同方式?代码import (    "context"    "fmt"    "os"    "github.com/jackc/pgx/v4"    "github.com/jackc/pgx/v4/pgxpool")type mockLogger struct{}func (ml *mockLogger) Log(ctx context.Context, level pgx.LogLevel, msg string, data map[string]interface{}) {    fmt.Printf("[%s] %s : %+v\n", level.String(), msg, data)}func connect() error {    connStr := "host='my-host.com' port='5432' dbname='my-db' user='my-db-user' sslmode='verify-full' sslcert='/path/to/db_user.crt' sslkey='/path/to/db_user.key' sslrootcert='/path/to/ca_roots.pem'"    poolCfg, err := pgxpool.ParseConfig(connStr)    if err != nil {        return err    }    poolCfg.ConnConfig.Logger = &mockLogger{}    poolCfg.ConnConfig.LogLevel = pgx.LogLevelTrace    fmt.Printf("using connection string: \"%s\"\n", poolCfg.ConnString())    connPool, err := pgxpool.ConnectConfig(context.TODO(), poolCfg)    if err != nil {        return err    }    connPool.Close()    return nil}func main() {    if err := connect(); err != nil {        fmt.Printf("%+v\n", err)        os.Exit(1)    }}
查看完整描述

1 回答

?
千万里不及你

TA贡献1784条经验 获得超9个赞

概括

事实证明,证书指向的证书sslcert需要包含完整的客户端证书链

/path/to/db_user.crt包含客户端证书后跟客户端证书链时,pgx连接有效。

而该psql命令在两种情况下都有效:

  • 什么时候sslcert只是没有链的叶客户端证书

  • sslcert包含客户端证书+链时

不知道为什么 psql 在没有完整链的情况下很好,但它现在可以工作了。

细节

在后台,pgx 使用pgconn模块创建连接。反过来,这只是调用和文件tls.X509KeyPair的内容。sslcertsslkey

pgconn/config.go :

func configTLS(settings map[string]string, thisHost string, parseConfigOptions ParseConfigOptions) ([]*tls.Config, error) {

    [...]

    sslcert := settings["sslcert"]

    sslkey := settings["sslkey"]

    [...]

    if sslcert != "" && sslkey != "" {

        [...]

        certfile, err := ioutil.ReadFile(sslcert)

        if err != nil {

            return nil, fmt.Errorf("unable to read cert: %w", err)

        }

        cert, err := tls.X509KeyPair(certfile, pemKey)

        if err != nil {

            return nil, fmt.Errorf("unable to load cert: %w", err)

        }

        tlsConfig.Certificates = []tls.Certificate{cert}


查看完整回答
反对 回复 2023-02-14
  • 1 回答
  • 0 关注
  • 87 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信