Migration zu Ghost
Sicherheit, Anmeldung und der Ernstfall
Seit einigen Wochen läuft diese Website nicht mehr mit Wordpress, sondern mit dem Publishingsystem Ghost. Meine Erfahrungen beim Umzug lege ich in dieser Artikelreihe dar. Diesmal geht es mir um die Vorkehrungen für den Ernstfall und den Versuch ein paar Security-Best-Practices umzusetzen.
Über Sicherheit zu schreiben, ohne das eigene System zu entblößen, ist ein schmaler Grat. Ich gehe ihn in diesem Artikel bewusst, denn die lehrreichsten Momente der Migration zu Ghost waren nicht die gelungenen Konfigurationen, sondern die Stellen, an denen etwas auf dem Spiel stand. Zwei davon schildere ich. Den Mailserver, der über die bloße Erreichbarkeit des Systems entscheidet, und den Tag, an dem ich beinahe ein Bildarchiv von fünfzehn Jahren verloren hätte. Sicherheit zeigt ihren Wert selten im Alltag, fast immer erst in der Ausnahme.
Der Mailserver entscheidet
Ghost setzt für die Anmeldung im Verwaltungsbereich auf einen per E-Mail zugestellten Link, den Magic Link. Das klingt nach Komfort, ist in der Konsequenz aber eine unterschätzte Abhängigkeit und ich selbst bin kein großer Fan von Seiten, die das machen.
Wer sich einloggen will, braucht einen funktionierenden Zustellweg, und klemmt dieser Weg, steht man vor dem eigenen System wie vor einer verschlossenen Tür, deren Schlüssel im Briefkasten liegt, den man gerade nicht öffnen kann. Aus dem Nebenschauplatz wird so die tragende Säule, und genau darin liegt die Dichotomie dieser Komfortlösung: Sie erleichtert den Alltag und schafft im selben Zug einen einzelnen Punkt, an dem alles hängt.
Genau hier lag mein anfänglicher Widerwille. Lange hatte ich mich gegen einen eigenen Mailbetrieb entschieden, denn der Aufwand für eine saubere Konfiguration ist hoch und für einen reinen Grundbetrieb kaum zu rechtfertigen. Nun führte kein Weg daran vorbei. Postfächer anlegen, die kryptografischen Signaturen für Domain und Versand einrichten, also jene Mechanismen, die einer empfangenden Gegenstelle belegen, dass eine Nachricht wirklich von meiner Domain stammt und nicht gefälscht ist. Die Server-Verwaltung hat mir viel abgenommen, die Verantwortung bleibt. Ein Mailserver, der zur Anmeldevoraussetzung wird, muss dauerhaft sauber laufen, sonst sperrt er im Zweifel den eigenen Betreiber aus. Was ich mir sparen wollte, habe ich mir damit erst recht eingehandelt, und diesmal an der empfindlichsten Stelle.
Aus einem zweiten Grund hadere ich. Die Anmeldung per E-Mail ist nicht die Zwei-Faktor-Methode, die ich bevorzuge. Ich arbeite lieber mit einer modernen Authentifizierungs-App, früher der Google Authenticator, heute der in das Apple-Ökosystem integrierte Passwort App. Ein zweiter Faktor, der über das Postfach läuft, fühlt sich weniger sicher und weniger souverän an, weil die Kette nur so stark ist wie das Postfach, an dem sie hängt. So habe ich am Ende eine zusätzliche Komponente am Hals, die ich nie betreiben wollte, und sie ist nicht einmal jene, die ich für die beste hielte.
Sichern, bevor es brennt
Der zweite Strang ist die Sicherung. Ein verbreiteter Reflex bei Containern lautet, einfach ein Abbild des laufenden Standes festzuhalten, in Docker über den Befehl docker commit. Das ist trügerisch, denn ein solches Abbild erfasst weder die eingehängten Datenverzeichnisse, in denen Inhalte, Themes und Konfiguration liegen, noch die Umgebungsvariablen, die das System zur Laufzeit braucht. Man hält also genau das Falsche fest und wiegt sich in einer Sicherheit, die keine ist. Tragfähig ist ein anderer Dreiklang: ein Archiv des Datenverzeichnisses, ein Datenbankabzug und eine dokumentierte Notiz der Laufzeitkonfiguration, übertragen auf ein getrenntes Ziel.
# Tragfaehige Sicherung statt 'docker commit':
# 1) Datenverzeichnis archivieren
tar -czf ghost-data-$(date +%F).tar.gz /pfad/zu/ghost-data
# 2) Datenbank abziehen
mysqldump --single-transaction ghost_db > ghost-db-$(date +%F).sql
# 3) Auf ein getrenntes Ziel uebertragen
rsync -a ghost-data-*.tar.gz ghost-db-*.sql backup-ziel:/sicherung/
Diese Disziplin klingt nach Pflichtübung, bis der Tag kommt, an dem sie sich auszahlt.
Der Tag des Schreckens
Dieser Tag kam, und der Fehler war meiner. Beim Vorbereiten einer Testumgebung löschte ich über den Dateimanager versehentlich einen Ordner, und plötzlich war das Bildverzeichnis leer, rund zweitausenddreihundert Dateien, etwa zehn Gigabyte, das gesammelte Bildgut vieler Jahre. Der erste Moment ist ein Sturz; oder: ein kurzer, kalter Schreck. Gerettet hat mich nicht Heldenmut, sondern Vorsorge. Auf meinem Rechner im Büro lag noch ein älterer Stand des Dateisystems, und aus dem ursprünglichen WordPress-Pfad ließ sich der Bestand per rsync zurückholen, mit Filtern gegen die alten Größenvarianten, sodass nur die Originale zurückwanderten. Beide Datenbanken waren ohnehin unversehrt. Aus dem Sturz wurde Erleichterung, und aus der Erleichterung eine Lehre.

Denn so gut es ausging, der lokale Bürostand ist keine Strategie, er war Glück, und Glück ist im Betrieb die schlechteste aller Sicherungen. Langfristig führt kein Weg an einer ernsthaften Lösung vorbei, einem eigenen Netzwerkspeicher oder einer gemieteten Storage-Box beim Hoster, für die ich bereit sein muss, etwas mehr zu zahlen, denn Redundanz ist selten kostenlos und ihr pekuniärer Preis fällt immer vor dem Ernstfall an, nie danach. Lange hatte ich ein in den Server integriertes Komplettbackup beim alten Anbieter, und im Grunde steht sogar der Umzug der physischen Maschine im Raum. Dass ich ihn nur zögernd erwäge, liegt an meinen Beharrungskräften, die in solchen Dingen beträchtlich sind.
Das parallel weiterlaufende WordPress gehört in dieses Kapitel, denn es war im Ernstfall mehr als ein nostalgisches Anhängsel. In jenem Pfad lagen die Originaldateien, aus denen ich den Bestand zurückgewann. Was als Versicherung gedacht war, hat sich zwischenzeitlich bewährt – wenn auch bloß kurz.
Was man beachten sollte
Zur Grundsicherung des Servers breite ich hier nichts Konkretes über meine Maschine aus, das wäre unklug und niemandem dienlich, doch ein Verzicht auf Namen ist nicht dasselbe wie Verschleierung. Das Bekannte und zu oft Vernachlässigte gilt weiter: nicht benötigte Dienste und Module abschalten, offene Zugänge schließen, soweit der Betrieb es erlaubt, und Werkzeuge zur Angriffserkennung einsetzen, wie etwa Fail2Ban gegen automatisierte Anmeldeversuche oder eine Endpoint-Lösung von der Art eines CrowdStrike, beide so verbreitet, dass ihre bloße Nennung kein Detail über meine Konfiguration preisgibt. Ein Ghost-spezifischer Punkt verdient ausdrückliche Erwähnung, weil er selten fällt und viel bewirkt: Mit Ghost lässt sich PHP vollständig abschalten, das System braucht es nicht. Damit entfällt ein großer, über Jahre gewachsener Angriffsvektor, den man von WordPress notgedrungen mitschleppt, und dieser eine Verzicht ist ein stiller, aber gewichtiger Sicherheitsgewinn.
