Page MenuHomePhabricator

Updates of passwords of users created with postgresql::user / PostgreSQL change to scram-sha256
Open, MediumPublic

Description

The postgresql::user define is used to create Postgres users. Initially the user is created and then a define runs an ALTER on the user to set the password. To prevent the password being set in every Puppet run, there's an onlyif check for the exec, which runs a "SELECT 1 from pg_authid WHERE rolname = $USER and rolpassword IS DISTINCT FROM $MD5PASSWORD" (with the latter being based on the md5() function from Ruby against the password obtained from Hiera).

This worked fine so far, but starting with Bookworm/PostgreSQL switched away from the known broken md5 to scram-sha-256, so we can't easily reapply the comparison scheme (we'd need to obtain the salt from Postgres and then add custom code to compute the hash, which seems brittle). Continuing to use md5 with Postgres 15 is also not an appealing option (I couldn't find an obvious way to configure it anyway).

One way forward would be to untangle the user creation and password changes:

  • Modify the postgresql::user Puppet code when run on bookworm and later to only check for the presence of the user, but don't compare the hash
  • Create a cookbook which gets run after a user password is changed which removes existing user definitions from pg_hba.conf and forces a puppet run to have it recreate users

I think password changes are quite rare (they are at least for Netbox and Puppetdb), but I'm adding other people involved in managing PostgreSQL-using services for additional proposals/comments/objection.

Event Timeline

Change 877120 had a related patch set uploaded (by Muehlenhoff; author: Muehlenhoff):

[operations/puppet@production] postgresql::user: No longer compare password hashes on Bookworm and later

https://gerrit.wikimedia.org/r/877120

Change 877120 merged by Muehlenhoff:

[operations/puppet@production] postgresql::user: No longer compare password hashes on Bookworm and later

https://gerrit.wikimedia.org/r/877120

Modify the postgresql::user Puppet code when run on bookworm and later to only check for the presence of the user, but don't compare the hash

This scheme is now implemented for Postgres 15 on Bookworm

Leaving a suggestion here for a workaround for the record: while having a native pg facility to detect password changes would be optimal; I think what we could do is write the (hashed, possibly salted with a salt we control) passwords on the filesystem (e.g. one per file). Then use the following logic:

  • if the password file doesn't exist, the user and its password needs to be created in pg and the fs
  • if the password file does exist, compare its value with the current puppet password. If they differ then update pg and the fs. If they don't then there's nothing to do.

The following should be wrapped in an utility script e.g. pg-password onlyif <user> <password> and pg-password set <user> <password>