Zum Inhalt springen
labkompass

Logbuch#docker#security#selfhosting

Passwort raus aus der compose.yaml — und Docker Compose baute die Container trotzdem neu

Von Niclas Hennrich


BuildIm Einsatz

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.

  1. Sicherung der compose.yaml angelegt
  2. Wert per Skript in eine .env gezogen, ohne ihn dabei je auszugeben
  3. Beide Vorkommen durch einen Verweis ersetzt
  4. Aufgelöste Konfiguration vorher/nachher über eine Prüfsumme verglichen
  5. Stack neu gestartet, Funktion und Daten geprüft
  6. Sicherungsdatei sicher gelöscht — sie war der letzte Klartext-Rest
  7. Rechte gesetzt: .env nur 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.

Daraus entstanden