Logbuch#docker#security#selfhosting
Passwort raus aus der compose.yaml — und Docker Compose baute die Container trotzdem neu
Von Niclas Hennrich
Selbst gebaut und in Betrieb genommen.
Was mir aufgefallen ist: Bei der
Nextcloud-Untersuchung fiel
nebenbei etwas auf, das nichts mit Nextcloud zu tun hat: Das
Datenbank-Passwort stand an zwei Stellen im Klartext in der
compose.yaml — und die Datei war für alle Benutzer des Systems lesbar. Eine
.env gab es nicht.
Warum das mehr stört, als es klingt: Die compose.yaml ist genau die
Datei, die man kopiert. Die man in eine Dokumentation übernimmt, in einen
Notizeintrag zitiert, auf einem Screenshot zeigt, in ein Repository legt oder
jemandem schickt, wenn man um Hilfe bittet. Die .env ist dagegen die Datei,
die man konventionell nicht anfasst — sie steht in praktisch jeder
.gitignore und wird beim Zeigen automatisch mitgedacht.
Es geht also nicht darum, dass eine Datei sicherer ist als die andere. Es geht darum, welche Datei man versehentlich weitergibt.
Was ich gemacht habe — bewusst ohne Passwortwechsel. Der Wert bleibt derselbe, nur sein Ort ändert sich. Ein Wechsel wäre ein eigener, riskanterer Eingriff, weil er die Datenbankrolle und die Anwendungskonfiguration gleichzeitig treffen muss. Zwei Dinge auf einmal ändern ist der Klassiker, nach dem man nicht mehr weiß, welches davon kaputt war.
- Sicherung der
compose.yamlangelegt - Wert per Skript in eine
.envgezogen, ohne ihn dabei je auszugeben - Beide Vorkommen durch einen Verweis ersetzt
- Aufgelöste Konfiguration vorher/nachher über eine Prüfsumme verglichen
- Stack neu gestartet, Funktion und Daten geprüft
- Sicherungsdatei sicher gelöscht — sie war der letzte Klartext-Rest
- Rechte gesetzt:
.envnur für den Eigentümer lesbar
Ein Detail, das ich mir gemerkt habe: Die richtige Schreibweise ist
${VARIABLE:?}, nicht ${VARIABLE}. Mit dem Fragezeichen bricht Compose ab,
wenn die Variable fehlt. Ohne startet der Stack fröhlich mit einem leeren
Passwort und tut irgendetwas Unerwartetes — im schlimmsten Fall legt die
Datenbank beim ersten Start eine Rolle ohne Passwort an.
Wo ich falsch lag: Ich war sicher, dass Compose die Container stehen
lässt. Die aufgelöste Konfiguration war schließlich byte-identisch — die
Prüfsumme vorher und nachher stimmte überein. Trotzdem meldete docker compose up -d „Recreated" und startete beide Container neu.
Warum, habe ich nicht abschließend geklärt. Compose entscheidet über den Neuaufbau offenbar nicht allein anhand der aufgelösten Konfiguration; die Container waren zuvor mit einer älteren Compose-Version erzeugt worden. Der Ausfall betrug wenige Sekunden und war harmlos, weil alle Daten in Volumes liegen.
Was ich mitnehme: Ein identischer Fingerabdruck von docker compose config garantiert nicht, dass die Container stehen bleiben. Bei Diensten,
deren Ausfall wehtut, plant man so einen Umbau entsprechend ein — statt auf
Null Ausfall zu setzen und dann überrascht zu sein.
Nebenbefund, der mich mehr geärgert hat als der Neustart: Im selben Verzeichnis lag ein älterer Datenbank-Dump, ebenfalls für alle lesbar. Der enthält keine Datenbankrollen — was ein eigenes Problem ist — aber sämtliche Anwendungsdaten samt der Passwort-Hashes aller Benutzer. Ein Dump ist kein Konfigurationsartefakt, sondern eine Kopie der Datenbank. Rechte gesetzt.
Offen geblieben: Der Wert selbst ist unverändert. Er war über längere Zeit in einer weltlesbaren Datei — ein Wechsel bleibt sinnvoll und steht als eigener Schritt an.