PostgreSQL 14和SCRAM认证的改变--应该迁移到SCRAM?

最近,一些PG使用者反馈他们切换到PG14后,遇到了一些连接错误。

FATAL:  password authentication failed for a user in the new server?”就是一个有趣的问题。至少在一个案例中,应用程序如下消息令人有点惊讶:

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

这些错误的原因是,新版本的PG将密码加密的默认设置改成了SCRAM认证。尽快最后一个似乎与SCRAM没有之间关系,是的,一些按照脚本识别了,他在寻找“md5”。SCRAM认证在PG中并不是什么新鲜事。从PG10开始就存在,但不影响DBA的日常,因为他不是默认设置。通过显式更改默认设置,作为可选项。那些选择使用的人知道如何使用,但PG社区多年来一直不愿将其作为主要方法,因为许多客户端/应用程序还没准备好进行SCRAM身份认证。但这在PG14中发生变化。随着PG9.6不再支持,情况正在发生变化。限制我们希望所有旧的客户端库都得到升级。SCRAM认证者成为主要密码身份认证方法。但是,那些全部不知道的人总会有一天会收到惊喜。本文就是让那些未了解的人快速理解并解决一些常见的问题。

什么是SCRAM认证?

简而言之,数据库客户端和服务端互相证明和说服对方他们知道密码,而无需交换密码和密码hash。是的,可以按照RFC7677的规定执行加盐挑战和响应SCRAM-SHA-256。这种存储、通信和密码验证的方式使得破解密码变得非常困难。这种方法更能抵抗:字典攻击、回放攻击、Stollen hashes。总的来说,破解基于密码的身份验证变得非常困难。

随着时间推移,改变了什么

Channel Binding

身份验证只是安全通信的一部分。身份验证后,中间的恶意服务器可能会接管并欺骗客户端连接。PG11引入了支持channel binding的SCRAM-SHA-256-PLUS。这是为了确保没有恶意服务器充当真实服务器或进行中间人攻击。从PG13开始,客户端可以请求甚至坚持channel binding。例如:

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

通道绑定通过SSL/TLS工作,因此SSL/TLS配置对于通道绑定工作是必需的。

配置Password Encryption

md5是PG10之前唯一可用的密码加密选项,因此PG允许设置指示“需要密码加密”,默认是md5:

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

由于同样的原因,上述陈述实际上与以下内容相同:

postgres=# set password_encryption TO MD5;
SET

我们甚至可以使用“true”、“1”、“yes”而不是“on”作为等效值。

但是现在我们有多种加密方法,“on”并不能真正表示我们想要的东西。所以从PG14开始,系统期望我们指定加密方法:

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、我的逻辑备份和恢复是否受到影响

(pg_dumpall)逻辑备份和重储PG的globals不会影响SCRAM认证,相同的密码在恢复后工作。事实上,回想下SCRAM身份认证对更改更据弹性会很有趣。例如,如果我们重命名USER,旧的md5密码不再起作用,因为PG生成md5的方式也使用用户名。

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

NOTICE中表明,pg_authid中的密码被清除了,因为旧的Hash不再有效。但SCRAM验证不会出现这种情况,因为我们可以在不影响密码的情况下重命名用户:

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

2、现有/旧的加密方法(md5)是一个很大的漏洞,有没有很大的风险?

这种担心主要来自“MD5”这个名字,这对现代硬件来说太傻了。PG使用md5的方式不同,不仅仅是密码的hash值,它还考虑用户名。此外,它在使用服务器提供的随机盐准备hash后通过线路进行通信。有效地传达的内容将与密码hash不同,因此它不太容易受到攻击。但容易出现字典攻击和泄露用户名密码hash问题。

3、新的scram认证是否带来了复杂性?连接是否需要更长时间?

Scram的有线协议非常有效,并且不知道会导致连接时间下降。而且,与服务器端连接管理的其他开销相比,SCRAM产生的开销将变得非常微不足道。

4、是否必须使用PG14的SCRAM认证并强制其他用户账户切换到它?

绝对不是,只是更改了默认值。旧的Md5仍然是有效的方法,效果很好。如果访问PG环境受到了防火墙/hba规则的限制,使用md5的风险已经很小。

5、为什么切换PG14时收到“FATAL: password authentication failed for user”错误?

最大可能原因是pg_hba.conf条目。如果我们指定“md5”作为认证方法,PG也将允许SCRAM认证。但反过来是行不通的。当创建PG14环境时,很可能将“scram-sha-256”作为认证方法。在某些PG软件包中,安装脚本会自动执行认证,如果认证来自PG客户端而不是应用程序 ,请检查驱动版本以及升级的范围。

6、为什么会收到其他类型的身份认证错误?

最有可能的是后置安装脚本。在许多组织中,使用DevOps工具(Ansible/Chef)甚至shell脚本进行安装后自定义是一种常规做法。其中许多人将做一系列涉及密码加密设置为on的的事情;甚至使用sed修改pg_hba.conf。如果它试图修改不再存在的条目,则预计会失败。

应该关注什么以及如何做

从自动化/部署脚本、工具、应用程序连接和连接池开始的任何东西都可能会中断。将此更改延迟到PG14的主要论据之一是,最旧的支持版本9.6即将停止支持。因此,这是检查您环境以查看是否任何环境具有旧PG库并指定升级计划的合适时机。因为旧版本的PG库无法处理SCRAM。

总之,制定一个好的迁移计划总是好的,即使它并不紧急。

1)请检查环境和应用程序驱动以查看他们是否仍在使用旧版本的PG客户端库,并在需要时升级,参考:https://wiki.postgresql.org/wiki/List_of_drivers

2)如果现在有环境使用md5,鼓励用户切换到SCRAM认证。pg_hba.conf中提到的md5也将适用于PG14的SCRAM和MD5身份认证

3)抓住一切机会测试自动化、连接池、其他基础架构并将其迁移到SCRAM认证。

通过更改默认的认证方式,PG社区为未来指明了方向。