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!