代码改变世界

PostgreSQL 14的SCRAM身份验证

2022-02-11 02:42  abce  阅读(3463)  评论(0编辑  收藏  举报

升级到PostgreSQL14之后,会遇到以下错误:

FATAL:  password authentication failed for a user
FATAL: Connection to database failed: connection to server at “localhost” (::1), port 5432 failed: fe_sendauth: no password supplied

报这些错误的原因是,PostgreSQL修改了默认的密码加密算法,在新版本中改成了SCRAM验证方式。

SCRAM其实并不是PostgreSQL中的新东西,在版本10中就有了,只是在之前的版本中只是可选的设置,而不是默认设置。PostgreSQL社区多年来一直不愿将其作为主要方法,因为许多客户端/应用程序库还没有准备好进行 SCRAM身份验证。

但在PostgreSQL 14中正在发生变化。随着PostgreSQL 9.6不再支持,情况正在发生变化。现在希望所有旧的客户端库都得到升级,SCRAM 身份验证正在成为主要的密码身份验证方法。但是,那些完全不知道的人总有一天会收到惊喜。 这篇文章的目的是让那些尚未了解的人快速了解并解决一些常见问题。

PostgreSQLv14虽然是默认改成了SCRAM验证方式。但是仍然可以使用以前的验证方式。

SCRAM身份验证

身份验证只是安全通信的一部分。身份验证后,中间的恶意服务器可能会接管并欺骗客户端连接。PostgreSQL 11 引入了支持通道绑定的 SCRAM-SHA-256-PLUS。这是为了确保没有恶意服务器充当真实服务器或进行中间人攻击。

从PostgreSQL 13开始,客户端可以通过通道绑定(channel binding)发起请求。

例如:

psql -U postgres -h c76pri channel_binding=prefer
or
psql -U postgres -h c76pri channel_binding=require

通道绑定(channel binding)必须要开启SSL/TLS配置。

设置密码加密

md5是PostgreSQL 10之前唯一可用的密码加密选项,默认为md5。

–Upto PG 13
postgres=# set password_encryption TO ON;
SET

on也可以替换成:true、1、yes。

该语句的作用和下面的等效:

postgres=# set password_encryption TO MD5;
SET

 

现在我们有了多种密码加密算法,从PostgreSQL14开始,就要指定加密算法了:

postgres=# set password_encryption TO 'scram-sha-256';
SET
postgres=# set password_encryption TO 'md5';
SET

 

如果再尝试使用:on、true、yes。就会报错了:

–-From PG 14
postgres=# set password_encryption TO 'on';
ERROR:  invalid value for parameter "password_encryption": "on"
HINT:  Available values: md5, scram-sha-256.

常被提出的问题

1.逻辑备份和还原是否受影响

PostgreSQL的逻辑备份和恢复不会影响SCRAM身份验证,恢复后相同的密码可以工作。

如果我们重命名USER,旧的MD5密码将不再起作用,因为PostgreSQL生成MD5 的方式也使用到用户名。

postgres=# ALTER USER jobin1 RENAME TO jobin;
NOTICE: MD5 password cleared because of role rename
ALTER ROLE

可以看到,pg_authid中的密码哈希值会被清空,因为老的不再有效。

但是,SCRAM验证就不会出现上面的问题:

postgres=# ALTER USER jobin RENAME TO jobin1;
ALTER ROLE