如何解决TLS连接K8s Crunchy PostgreSQL集群的SCRAM认证报错问题
错误根因分析
你遇到的pg: SASL: got "SCRAM-SHA-256-PLUS", wanted "SCRAM-SHA-256"报错,核心是两个配置错误叠加导致:
- 误用了PostgreSQL服务端的证书作为客户端证书
- 你使用的go-pg v10版本默认不支持带通道绑定的SCRAM-SHA-256-PLUS认证方式,当 PostgreSQL 检测到客户端携带TLS证书时,会优先返回SCRAM-SHA-256-PLUS认证方式,和客户端支持的认证方式不匹配。
分步修复方案
1 修正凭证引用
你当前引用的hippo-tls是PostgreSQL集群的服务端证书,不能作为客户端证书使用。正确的客户端凭证存放在Crunchy Operator自动生成的hippo-pguser-hippo Secret中,修改Deployment的env配置如下:
env: - name: CA_CERT valueFrom: {secretKeyRef: {name: hippo-pguser-hippo, key: ca.crt}} - name: CLIENT_TLS_CERT valueFrom: {secretKeyRef: {name: hippo-pguser-hippo, key: tls.crt}} - name: CLIENT_TLS_KEY valueFrom: {secretKeyRef: {name: hippo-pguser-hippo, key: tls.key}}
如果该Secret中没有ca.crt,再改为引用pgo-root-cacert的root.crt即可。
2 修正TLS参数配置
删除不必要的InsecureSkipVerify: true配置,ServerName字段填写你连接的PostgreSQL服务域名,也就是Addr参数里的hippo-primary.postgres-operator.svc,修改后的TLS配置如下:
func ConnectTls(ctx context.Context) *pg.DB { cert, err := tls.X509KeyPair([]byte(os.Getenv("CLIENT_TLS_CERT")), []byte(os.Getenv("CLIENT_TLS_KEY"))) if err != nil { log.Printf("failed to load client certificate: %v", err) panic(err) } CACertPool := x509.NewCertPool() CACertPool.AppendCertsFromPEM([]byte(os.Getenv("CA_CERT"))) tlsConfig := &tls.Config{ Certificates: []tls.Certificate{cert}, RootCAs: CACertPool, InsecureSkipVerify: false, ServerName: "hippo-primary.postgres-operator.svc", } opt := &pg.Options{ Addr: "hippo-primary.postgres-operator.svc:5432", User: "hippo", Password: "1XNrN1H-AF)=S(U_9*6(A0V7", Database: "hippo", TLSConfig: tlsConfig, } DB := pg.Connect(opt) if err := DB.Ping(ctx); err != nil { log.Print("failed to connect") log.Print(err) } return DB }
3 解决SCRAM认证不匹配问题
二选一即可:
- 方案一:升级依赖:将go-pg升级到v10.10.0及以上版本,该版本已原生支持SCRAM-SHA-256-PLUS认证方式,无需修改其他代码。
- 方案二:关闭双向TLS认证:如果你只需要TLS加密链路、不需要客户端证书身份校验,可以直接删除加载客户端证书的逻辑以及
TLSConfig中的Certificates字段,PostgreSQL就不会返回SCRAM-SHA-256-PLUS认证方式,直接走普通的SCRAM-SHA-256密码认证。
修改完成后重新部署应用即可正常连接PostgreSQL集群。
内容的提问来源于stack exchange,提问作者Corbin Kristek
相关产品推荐
相关产品推荐

