Docker-Gitea-Postgres Part 5: Posgres MD5- und SCRAM-Passwörter

Teil 5 einer Reihe über Gitea & Postgres im Docker-Container: Postgres MD5- und SCRAM-Passwörter

Hintergrund dieser Reihe ist das notwendige Update einer Docker-Gitea-Instanz und in diesem Rahmen auch das Major-Version-Upgrade der zugehörigen Postgres-Datenbank.

Postgres MD5- und SCRAM-Passwörter

Mit Version 10 hat Postgres Abschied von den alten und potentiell unsicheren MD5-Passwort-Hashes genommen. Ersatz dafür sind die sog. "SCRAM secrets". Das bedeutet aber auch, dass bei einem Major-Upgrade von 9 auf 10 (oder danach) alle Benutzer keine "passend" verschlüsselten Passwörter mehr haben.

Vorgeschichte

Nachdem Gitea nicht mehr starten bzw. dauerhauft laufen wollte, bin ich auf einigen Umwegen auf folgenden Log-Eintrag gestoßen:

root@docker:~ # docker logs gitea_db
[...]
FATAL:  password authentication failed for user "gitea"
DETAIL:  User "gitea" does not have a valid SCRAM secret.
    Connection matched pg_hba.conf line 100: "host all all all scram-sha-256"
[...]

Wenn man dies direkt im Container ausprobiert, kommt auch nur eine (wenig sagende) Fehlermeldung:

root@docker:~ # docker exec -it gitea_db bash
root@bash-5.1# psql -U gitea -h 172.31.3.2
  psql: error: connection to server at "172.31.3.2", port 5432 failed: FATAL:  password authentication failed for user "gitea"

SCRAM als Ersatz für MD5

Wenn man sich im Container umsieht, findet man auch die entsprechenden Stellen, an denen die Postgres-Instanz auf SCRAM konfiguriert wird;

root@bash-5.1# grep password_encryption /var/lib/postgresql/data/postgresql.conf 
#password_encryption = scram-sha-256    # scram-sha-256 or md5

root@bash-5.1# grep -v "^#\|^$" /var/lib/postgresql/data/pg_hba.conf 
local   all             all                                     trust
host    all             all             127.0.0.1/32            trust
host    all             all             ::1/128                 trust
local   replication     all                                     trust
host    replication     all             127.0.0.1/32            trust
host    replication     all             ::1/128                 trust
host all all all scram-sha-256

Natürlich ist das Ersetzen von MD5 durch einen stärkeren Algorithmus notwendig und zu begrüßen, letztendlich war es aber der Aufhänger für diese ganze Reihe von Artikeln ;)

Um jetzt zu sehen, welche Benutzer bereits ein SCRAM-Passwort haben, verbindet man sich mit der Datenbank und stellt eine Anfrage:

root@bash-5.1# psql -U gitea
psql (14.2)
Type "help" for help.

gitea=# SELECT rolname, rolpassword ~ '^SCRAM-SHA-256\$' AS scram_pw FROM pg_authid WHERE rolcanlogin;
 rolname | scram_pw 
---------+--------------
 gitea   | f
(1 row)

Man sieht, der Benutzer "gitea" hat offensichtlich noch kein SCRAM-Passwort ("f"alse).

Da es in diesem (Gitea-Docker-)Fall nur ein Benutzer ist, kann man das Passwort auch schnell von Hand setzen - wie es im .env, Ansible-Playbook, ... gesetzt wurde:

gitea=# \password gitea
Enter new password for user "gitea": 
Enter it again: 

Im Erfolgsfall gibt es keine weitere Ausgabe, stimmen die beiden Versuche nicht überein, kommentiert Postgres dies mit einem Passwords didn't match.. Die Datenbank-Commandline kann man per exit verlassen. Dann kann man auch nochmals kurz an der Commandline kontrollieren, ob der Benutzer nun ein SCRAM-Passwort hat:

root@bash-5.1# echo "SELECT rolname, rolpassword ~ '^SCRAM-SHA-256\$' AS scram_pw FROM pg_authid WHERE rolcanlogin;" | psql -U gitea
 rolname | scram_pw 
---------+--------------
 gitea   | t
(1 row)

Schluss

Nach dem Setzen des Passworts als SCRAM secret konnte sich der Gitea-Container wieder ohne Probleme an die neue Postgres-Instanz verbinden. Seit dem läuft Gitea und Postgres also wieder in aktueller Version!