Recently, a few PostgreSQL users reported that they got connection failures after switching to PostgreSQL 14.
“Why do I get the error FATAL: password authentication failed for a user in the new server?” has become one of the most intriguing questions.
At least in one case, it was a bit of a surprise that the application message was as follows:
FATAL: Connection to database failed: connection to server at “localhost” (::1), port 5432 failed: fe_sendauth: no password supplied
The reason for these errors is the defaults for password encryption are changed in new versions of PostgreSQL to SCRAM authentication. Even though the last one appears nothing directly related to SCRAM, oh yes, some post-installation script failed which was looking for “md5”.
SCRAM authentication is not something new in PostgreSQL. It was there from PostgreSQL 10 onwards but never affected DBA life in general because that has never been the default. It was an opt-in feature by explicitly changing the default settings. Those who do an opt-in generally understand and do it intentionally, and it’s never been known to cause any problem. The PostgreSQL community was reluctant to make it a prime method for years because many of the client/application libraries were not ready for SCRAM authentication.
But that is changing in PostgreSQL 14. With PostgreSQL 9.6 going out of support, the landscape is changing. Now we expect all old client libraries to get upgraded and SCRAM authentication is becoming the prime password authentication method. But, those who are completely unaware are going to be greeted with a surprise one day or another. The purpose of this post is to create a quick awareness for those who are not yet, and address some of the commonly asked questions.
Percona and PostgreSQL work better together. Try Percona Distribution for PostgreSQL today.
In simple words, the database client and the server prove and convince each other that they know the password without exchanging the password or the password hash. Yes, it is possible by doing a Salted Challenge and Responses, SCRAM-SHA-256, as specified by RFC 7677. This way of storing, communicating, and verifying passwords makes it very hard to break a password.
This method is more resistant to:
Overall it becomes very hard to break a password-based authentication.
Authentication is only one part of secured communication. After authentication, a rogue server in the middle can potentially take over and fool the client connection. PostgreSQL 11 introduced SCRAM-SHA-256-PLUS which supports the channel binding. This is to make sure that there is no rogue server acting as a real server OR doing a man-in-middle attack.
From PostgreSQL 13 onwards, a client can request and even insist on channel binding.
For example:
|
1 |
psql -U postgres -h c76pri channel_binding=prefer<br>or<br>psql -U postgres -h c76pri channel_binding=require |
The channel binding works over SSL/TLS, so SSL/TLS configuration is mandatory to get the channel binding work.
The md5 was the only available option for password encryption before PostgreSQL 10, so PostgreSQL allows settings to indicate that “password encryption is required” which is defaulted to md5.
|
1 |
–Upto PG 13<br>postgres=# set password_encryption TO ON;<br>SET |
Due to the same reason, the above statement was effectively the same as:
|
1 |
postgres=# set password_encryption TO MD5;<br>SET |
We could even use “true”, “1”,”yes” instead of “on” as an equivalent value.
But now we have multiple encryption methods and “ON” doesn’t really convey what we really want. So from PostgreSQL 14 onwards, the system expects us to specify the encryption method.
|
1 |
postgres=# set password_encryption TO 'scram-sha-256';<br>SET |
|
1 |
postgres=# set password_encryption TO 'md5';<br>SET |
Any attempt to use “on”/”true”, “yes” will be rejected with an error.
|
1 |
–-From PG 14<br>postgres=# set password_encryption TO 'on';<br>ERROR: invalid value for parameter "password_encryption": "on"<br>HINT: Available values: md5, scram-sha-256. |
So please check your scripts and make sure that they don’t have the old way of “enabling” encryption.
postgres=# ALTER USER jobin1 RENAME TO jobin;
NOTICE: MD5 password cleared because of role rename
ALTER ROLE
postgres=# ALTER USER jobin RENAME TO jobin1;
ALTER ROLE
Anything starting from automation/deployment scripts, tools, application connections, and connection poolers could potentially break. One of the major arguments for delaying this change till PostgreSQL 14 is that the oldest supported version (9.6) is going out of support soon. So this is the right time to inspect your environments to see if any of those environments have old PostgreSQL libraries (9.6 or older) and have a plan for the upgrade, as the old version PostgreSQL libraries cannot handle SCRAM negotiations.
In summary, having a good plan to migrate will help, even though it is not urgent.
By changing the default authentication, the PostgreSQL community is showing a clear direction about the future.
Percona Distribution for PostgreSQL provides the best and most critical enterprise components from the open-source community, in a single distribution, designed and tested to work together.