Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/virtual/benny-baumann.de/blog/htdocs/wp-includes/post-template.php on line 310

Warning: count(): Parameter must be an array or an object that implements Countable in /var/www/virtual/benny-baumann.de/blog/htdocs/wp-includes/post-template.php on line 310

BenBE's humble thoughts Thoughts the world doesn't need yet …

16.05.2010

Katastrophen-Recovery mit ispCP

Filed under: Server — Schlagwörter: , , , , , , , , , , , — BenBE @ 20:40:03

Heute gibt es von meiner Seite einmal einen der Beiträge, die man am liebsten nie brauchen wöllte: Wie stelle ich aus minimalen Daten ein ispCP wieder her, falls es am alten Sytem zu Problemen kam. Und auch wenn ich schreibe, Katastrophen-Recovery: Alles, was über einen gewissen Grad an Problemen hinaus geht, wird auch mit dieser Anleitung nicht zu beheben gehen. Von daher eine kurze Checkliste:

  1. Habt ihr ein Backup ALLER Server-Dateien? Wenn ja, reicht im Wesentlichen die Migrationsanleitung von der ispCP-Homepage. Dennoch empfehle ich einen Blick weiter unten zu Hinweisen während man dies erledigt.
  2. Habt ihr ein Backup aller Userdaten UND folgenden Dinge:
    1. die Datenbank ispcp des alten Systems (Binärkopie ausreichend!)
    2. die Datenbank mysql des alten Systems (Binärkopie ausreichend!)
    3. die ispcp.conf des alten Systems
    4. /var/www/ispcp/gui/include/ispcp-db-keys.php
    5. /var/www/ispcp/engine/ispcp-db-keys.pl

    Sollten von den letzten beiden Dateien nur eine verfügbar sein, so kann die jeweils andere aus dieser Datei erzeugt werden. Fehlen beide, kann nur versucht werden, mit Hilfe des Howtos zum Setzen des MySQL-Passwortes für ispCP diese Dateien zu erzeugen. Dies muss nach dem Wiederherstellen der MySQL-Nutzer-Datenbank und vor Aufruf des Setup-Skripts geschehen. DATABASE_USER und DATABASE_PASSWORD müssen für diesen Fall nach Aufruf des Passwort-Skriptes aus der ispcp.conf in die ispcp.old.conf übertragen werden, da ispCP sonst mit den falschen Schlüsseln ein Login probiert.

  3. Habt ihr vom alten System genug Daten, um die im vorigen Punkt nötigen Daten der zweiten Subliste zusammenzukratzen. Wenn nicht, gilt auch hier: Beißt in saure Äpfel, der Todesgott eurer Installation mag die.

Okay: Eines vorweg: Wenn ihr mindestens einen Punkt der obigen Liste bejahen konntet, bestehen berechtigte Hoffnungen, dass ihr um eine vollständige Neuinstallation herumkommt. Eine Garantie gibt es hierbei aber nicht, da die nächsten Schritte mit extrem vielen Möglichkeiten für Fehler verbunden sind und ich es selber beim Erarbeiten dieser Liste geschafft habe, so nahezu JEDE Fehlermeldung, die ispCP bietet auch einmal zu erhalten. Wer also nicht allzu frusttolerant ist, sollte es vor dem Fortfahren mit geeigneten Antidepressiva probieren. Ihr wurdet gewarnt.

Ferner noch eine kleine Anmerkung für Voreilige: Bitte fangt nicht gleich am Anfang an, wild Dateien umherzukopieren. Ich werde an den entsprechenden Stellen darauf hinweisen, wenn Daten zu Kopieren sind. Zusätzlich sollte man während der gesamten Arbeit so fleißig mit Backups arbeiten, um Datenverlust so gut wie möglich vermeiden zu können.

Fangen wir also an. Als ersten Schritt sollte dringend ein gerade neu installiertes, frisches und blankes System derjenigen Distribution installiert werden, die auch auf dem alten System lief. Weder die Neuinstallation noch die gleiche Distribution sind hierbei verpflichtend, vereinfachen aber die spätere Arbeit wesentlich. Wer also von Anfang an auf seinem System Seppuku begehen möchte, darf sich auch eine Fremddistribution aus dem Gebrauchtinstallationsladen holen, sollte sich aber über Nebeneffekte nicht wundern. Keinesfalls darf zu diesem Zeitpunkt aber ispCP installiert sein, da im Zuge dieser Anleitung eine bestehende ispCP-Installation rücksichtslos überschrieben werden wird. Zum Zusammenführen mehrerer Installationen ist diese Anleitung ausdrücklich nicht geeignet.

Der nächste Schritt in dieser Anleitung betrifft eine Vorbereitung, die auch für eine normale Migration von Vorteil ist, da sie eine Eigenheit der Installation des Postfix-Servers behandelt. Dieser ist später für die Installation von ispCP nötig, führt aber unweigerlich zu Datenverlust beim Mailempfang, wenn er zu lange ohne Konfiguration verbleibt. Daher gibt es zwei Möglichkeiten, die je nach Situation unterschiedliche Vorzüge haben:

  1. DNS-Einträge für ALLE Domains, die das neue System zeigen ins Nirvana umleiten/entfernen

    Diese Variante ist, wenn auch die bessere Wahl, die mit wesentlich mehr Aufwand verbundene Umsetzung. Damit diese Variante funktioniert, sollte man bereits im Vorfeld (etwa 24 bis 48 Stunden!) den Umzug der DNS-Records veranlassen. Zu beachten ist hierfür insbesondere, dass hierbei keine Garantie für das korrekte Funktionieren gegeben ist, weil durch widerspänstige DNS-Caches noch veraltete Daten ausgeliefert werden können. In jedem Fall reduziert dieser Schritt aber eindeutig die Last auf dem Mailserver und kann somit unterstützend zum zweiten Schritt in Erwägung gezogen werden.

  2. Postfix bis zur Einrichtung seiner Konfiguration deaktiviert lassen

    Okay, diese Variante ist zwar Quick&Dirty, aber bietet gegenüber der vorigen Variante einen sehr großen Vorteil: Wenn die Last auf dem Mailserver klein genug ist, (<10 Mails/min) hat man sehr gute Chancen mit sehr guter Reaktion die Anzahl verlorener Mails auf 0 zu halten. Zudem sind für diese Vorgehensweise keine externen Vorbereitungen nötig, was das Recovery beschleunigen kann. Dennoch erfordert diese Methode eine gewisse Aufmerksamkeit, um das versehentliche Starten von Postfix schnell abstellen zu können.

Nach dem nun beide Vorgehensweisen aufgeführt worden, eine Reihe von Details zu den Hintergründen. Bei der Auslieferung von Emails wird vom Absender einer Mail (oder besser gesagt dessen Mailserver) nachgeschaut, wohin diese Mail geliefert werden soll. Diese Information findet sich in den sogennannten MX-Resource-Records einer Domain. Fehlen diese, so wird alternativ die Liste der A-Resource-Records zum Versand von Mails herangezogen. Innerhalb eines MX-Records wird nun neben der Adresse eines Mailservers auch eine Priorität definiert. Diese wird genutzt, um eine Reihenfolge für das Anfragen der Mailserver zu definieren. Fällt nun ein Mailserver in dieser Liste aus, so wird ein weiterer Mailserver aus der Liste der Mailserver probiert. Gibt es keinen weiteren, geht es irgendwann einfach wieder beim ersten Mailserver los.

Dieser gut gemeinte Fallback-Mechanismus hat im Falle des Postfix nun einen kleinen Haken, da dieser in seiner Standard-Konfiguration jegliche eintreffende Mails mit einem Hard-Error (554 5.7.1: Relay Access Denied) ablehnt, da Postfix nur Mails für Domains annimmt, für die er beauftragt ist. In der Standard-Konfiguration sind das außer localhost keine, was die Ablehnung zwar korrekt, aber für unseren Fall vollständig kontraproduktiv macht. Denn während bei einem nicht erreichbaren Mailserver ein Softerror generiert wird (Mailserver nicht erreichbar; Mailversand wird später nochmals probiert), besagt ein Hard-Error, dass die Mail verworfen werden soll UND an den Absender eine unzustellbarkeitsmitteilung (DSN = Delivery Status Notification) gesendet werden soll.

Daher sollte die Lösung sein: Solange Postfix noch nicht konfiguriert ist, dürfen ihn keine Mails erreichen. Und obige beiden Vorgehensweisen bieten ideale Erfolgsaussichten hierfür. Wenn es schnellgehen muss und nicht viele Mails anliegen, reicht Variante 2, hat man einen High-Volume-Mailserver mit hohem Traffic, sollte man sich für 1. mit Absicherung durch 2. entscheiden und sofern verfügbar, einen Backup-Mailserver verwenden (der jedoch vorerst noch keine Mails final zustellt).

Da wir nun Postfix abgehakt haben, können wir weiter voranschreiten und ispCP konfigurieren. Als Kurzbeschreibung hierfür kann mit wenigen Worten „Neuinstall, Konfig wiederherstellen, Update“ verwendet werden, wobei aber auch hier der Teufel im Detail steckt. War bis hierhin alles ohne große Konzentration möglich, können alle nun folgenden Schritte zu extrem schwer zu lokalisierenden Fehlern führen.

Setzen wir also erst einmal mit der Installation von MySQL fort, denn auch hier gibt es ein wenig was zu beachten. Oben habe ich ja bereits erwähnt, dass wir von MySQL sowohl die Datenbank ispcp wie auch die Datenbank mysql benötigen. Während dies Grundlegend erst einmal auch stimmt, ist es aber auch hier nicht die ganze Wahrheit, da die Datenbank mysql allein für die Authentifizierung der Datenbank-Nutzer zuständig ist. Fehlt einem diese Datenbank, ist zwar nicht partout Schluss, ABER man wird beim Rückspielen von ispCP erheblichen Aufwand bekommen. Wer also nicht allzu viel Erfahrung damit hat, in fremden Skripten sich Passwörter rauszudebuggen, sei hiermit wärmstens empfohlen, nach der mysql-Datenbank zu suchen, bevor er fortsetzt. Ist diese wirklich nicht auffindbar, buss anhand der ispCP-Keyfiles und einem Hack in den ispCP-Skripts im späteren Verlauf das entschlüsselte Passwort abgefangen werden. Gleiches gilt zudem für die Datei /etc/mysql/debian.cnf (oder analoge, je nach Distribution), in der die Maintainer-Passwörter für den Datenbank-Zugang enthalten sind. Auch hier gilt: Ist diese nicht auffindbar, muss man nach dem Rückspielen der mysql-Datenbank ein wenig mehr Aufwand treiben, indem man MySQL ohne Beachtung der Authentifikationstabellen startet

mysqld --skip-grant-tables

und nach dem setzen eines neuen Passwortes für den Maintainer-Zugang die entsprechende Konfigurationsdatei von Hand ausfüllt. Der Inhalt sollte dabei wie Folgt aussehen:

# Automatically generated for Debian scripts. DO NOT TOUCH!
[client]
host     = localhost
user     = debian-sys-maint
password = #password#
socket   = /var/run/mysqld/mysqld.sock
[mysql_upgrade]
user     = debian-sys-maint
password = #password#
socket   = /var/run/mysqld/mysqld.sock
basedir  = /usr

Hierbei muss statt #password# das Klartext-Passwort verwendet werden, was soeben in der Datenbank gesetzt wurde. Ich werden nachher aber noch einmal auf diesen Punkt zurückkommen.

Denn erst einmal können wir uns mit einer relativ einfachen Aufgabe beschäftigen: eine „Dummy-Installation“ von ispCP. Diese ist notwendig, um ein lauffähiges ispCP auf das System zu bekommen. Dieser Schritt ist auch einer der Gründe, warum keine Installation vorhanden sein darf: Diese wäre durch diesen Schritt das erste Mail überschrieben und wird nachher noch ein weiteres Mal überschrieben. Für die Installation von ispCP kann nach den ergangenen Vorbereitungen mit Postfix mit der normalen Anleitung für die Installation einer frischen Version von ispCP vorgegangen werden. Es empfiehlt sich in diesem Schritt, gleich mit einer aktuellen ispCP-Version anzufangen, selbst wenn auf dem alten Server nicht die aktuelle Version von ispCP lief. Dieser Schritt wird implizit durch einen später noch zu besprechenden Schritt nachgeholt. Vorsicht sollte aber auch hier wieder in Bezug auf Postfix gelten: Dieser sollte auch hier wieder vom Empfang und Ablehnen von Mails abgehalten werden. Dies ist AFAIR am Ende des Setup-Prozesses der Fall; es kann aber auch nicht schaden, mit htop ein Auge auf die aktuelle Prozessliste des Servers während der gesamten Arbeiten zu werfen.

Ist man bis hierhin gekommen, hat man den Einfachen Teil der Arbeiten geschafft. Ab nun an beginnt ein wenig forensische Arbeit, die eine Menge Fingerspitzengefühl erfordert. Als nächstes gilt es, die beiden Hauptdatenbanken von ispCP (nämlich genau die bereits erwähnten beiden) wieder einzupflegen. Hierzu beenden wir den MySQL-Server mit

/etc/init.d/mysql stop

bzw. mit einem nicht ganz so sanften

killall mysqld

sollte sich dieser weigern auf Geheiß des Startskriptes herunterzufahren.

Und nun kommt die angekündigte forensische Arbeit: Im nächsten Schritt müssen die Datenbanken ispcp und mysql zurückkopiert werden. Diese müssen unter /var/lib/mysql die beiden vorhandenen Ordner ersetzen. Wer Backups haben möchte, braucht diese beiden Ordner lediglich umzubenennen und kann dann wie gehabt auf diese von MySQL aus zugreifen. Hat man die beiden Ordner aus seinem Backup wiederhergestellt, gilt es zudem, die Berechtigungen für alle Dateien unter /var/lib/mysql zu korrigieren. Diese müssen auf den Owner mysql mit Gruppe mysql lauten. Am besten man erledigt dies kurz von der Kommandozeile:

cd /var/lib/mysql
chown -R mysql:mysql */

Womit wir auch wieder bei dem oben genannten Punkt wären: Hat man die Maintainer-Zugänge des alten Systems, so müssten diese jetzt unter /etc/mysql zurückgespielt werden. Hat man diese nicht, muss jetzt die entsprechende Korrektur der Passworte vorgenommen werden. für ispCP kann man sich diesen Schritt jedoch noch etwas aufheben, weil zu einem späteren Zeitpunkt wir eh auf diese Zugänge zurückkommen werden.

Apropos Zugänge: Dieser Moment ist glaube ein wundererbarer Moment, die Nutzer in der /etc/passwd, /etc/shadow sowie /etc/group und /etc/gshadow wiederherzustellen. Wer diese Dateien hat, muss aus jeder Datei folgende Dinge in sein neues System übernehmen:

  • vu* – Alle Virtuellen Nutzer von ispCP
  • vmail – Der Mailnutzer. ACHTUNG: Dieser muss UID 1000 haben, da ansonsten der Courier-Mailserver wahrscheinlich in einem späteren Schritt spinnt
  • mail – Die Gruppe für den Mailverkehr. Diese sollte aber genauso wie der Nutzer vmail bereits angelegt worden sein. Hier gilt GID 8

Nachdem nun die ispCP-Datenbank wieder eingerichtet ist und alle wesentlichen Nutzer wieder existieren, kann man nun auch die restlichen Nutzerdaten zurückspielen. Unter /var/www/virtual müssen die Nutzerberechtigungen dabei noch nicht hundertprozentig stimmen, da dies nachher gleich von ispCP korrigiert wird. unter /var/mail/virtual sollte aber zwingend auf UID 1000/GID 8 (UID vmail + GID mail) für ALLE Dateien und Verzeichnisse geachtet werden.

Sind auch diese wieder eingespielt und am richtigen Platz, müssen wir bevor wir mit ispCP fortfahren können noch für einen gültigen Datenbank-Zugang des FTP-Servers sorgen. hier gibt es nun zwei Möglichkeiten:

  1. Man besitzt die alte /etc/proftpd.conf noch
  2. Man besitzt sie nicht mehr

Besitzt man sie noch, stellt man sie wieder her, besitzt man sie nicht mehr, muss man für den Account vftp das Zugangspasswort des MySQL auf das in der vorhandenen Konfiguration genannte ändern. In jedem Falle muss das Passwort in der Konfiguration mit dem Zugang zur Datenbank übereinstimmen. Und damit es nicht zu einfach wird, haben wir auch hier einen kleinen Stolperstein: ispCP sucht das Passwort für den FTP in seiner Arbeitskopie, d.h. unter /etc/ispcp/proftpd/working/proftpd.conf. Somit müssen /etc/proftpd.conf (System) und /etc/ispcp/proftpd/proftpd.conf (ispCP) in Bezug auf das Passwort synchron sein. Anderweitig gibt es keinen Zwang, an beiden Stellen den gleichen Dateiinhalt zu haben, auch wenn es eine Reihe von Fehlerquellen eliminiert.

Womit wir bei einem Stolperstein währen, der mich eine Menge Zeit gekostet hat: ab diesem Zeitpunkt sollte man sicherstellen, dass die beiden Key-Files vom ispCP die Schlüssel des alten Systems repräsentieren. Dazu sucht man sich diese aus seinem Backup heraus und ersetzt die Dateien /var/www/ispcp/gui/include/ispcp-db-keys.php und /var/www/ispcp/engine/ispcp-db-keys.pl durch die jeweiligen Versionen des Backups. Fehlt einem eine dieser Dateien, so kann die jeweils andere durch Übernehmen der String-Daten erzeugt werden. Vergisst man dies, wird sich ispCP später beim Update über nicht funktionierende Login-Zugänge zur Datenbank beschweren oder auf der Weboberfläche einen Verbindungsfehler zur Datenbank melden.

Je nach Größe der ispCP-Installation gibt es nun u.U. den Wunsch, den Update-Prozess etwas zu beschleunigen, da ispCP gleich jegliche Verwaltungsstrukturen neu aufbauen wird. Da einige der hierzu notwendigen Teilschritte aber nur Bruchteile von Sekunden dauern und durch eine Feinheit im Source unnötig ausgebremst werden, kann man sich überlegen, ob man in vier der Management-Skripte von ispCP einen kurzen Patch (jeweils Auskommentieren einer Zeile, leicht zu finden) vornimmt. Details dazu gibt es im ispCP-Bugtracker, der zudem die Richtigkeit dieses Vorgehens bestätigt. Zur Durchführung suche man unter /var/www/ispcp/engine in allen Skripten ispcp-*-mgr nach einer Zeile mit

    sleep(1);

und kommentiere diese durch Ergänzung einer Raute aus:

    #sleep(1);

Welche Skripte das betrifft, findet man am schnellsten mit Hilfe von

grep sleep ispcp-*-mgr

Diese Änderung führt dazu, dass für ein mittleres System (25 Domains, 100 Subdomains, 500 Postfächer) die im folgenden Schritt benötigte Zeit von etwa 15 Minuten auf etwa 1-2 Minuten reduziert wird, was insbesondere vor dem Hintergrund, dass der nächste Schritt mit wahrscheinlichkeit mehrfach angegangen werden muss, stark von Vorteil ist.

Nachdem unser System nun soweit vorbereitet ist, vielleicht noch ein letzter Hinweis, der einem bei der Fehlersuche gleich sehr gut helfen wird: in der Datei /etc/ispcp/ispcp.conf sollte man am Ende die Zeile

DEBUG = 0

auf

DEBUG = 1

ändern. Dies schaltet während des Updates eine Reihe zusätzliche Anzeigen ein, die im Falle von Fehlern schneller den Weg zur Ursache weisen. Zusätzlich muss man in die ispcp.conf die Passwort-Kennungen seines alten Systems eintragen. Zusätzlich muss unter ispcp.old.conf in /etc/ispcp/ die ispcp.conf des alten Systems liegen.

Hat man diese Vorbereitungen unter /etc/ispcp getroffen, ruft man das Update-Skript (EXTREM wichtig, sonst darf man die Hälfte der Arbeit noch mals erledigen ;-)) auf:

cd /var/www/ispcp/engine/setup
./ispcp-update

Ist das Update von ispCP erfolgreich durchgelaufen, ist man, außer einer Reihe von Aufräumarbeiten, die man noch erledigen muss, mit dem Recovery soweit fertig. Schlegt das Update fehl, beginnt die im Wesentlichen auf Trial-and-Error (mit mehr letzterem) verbundene Fehlersuche. Alternativ kann an dieser Stelle auch das Howto zur Regenerierung der Konfiguration verwendet werden, was aber im Grunde analog zu einem DB-Update funktioniert. Dies sollte man aber nur tun, wenn das alte System bereits auf dem aktuellen Stand war. Ansonsten sollte man DRINGEND die Finger von dieser Variante lassen!

Ferner noch eine Anmerkung zum Update-Prozess. Während des Prozesses fragt ispCP ggf. nach dem vftp-Passwort. In diesem Falle sollte man überprüfen, ob der MySQL läuft UND ob das in der Konfiguration des proFTPd gegebene Login stimmt. Sollten sich außerdem einige Daten des Servers (Domainname, IP) geändert haben, sind diese vor dem Update in der Datenbank von ispCP anzupassen (Siehe Migrationsanleitung).

Sollte nach dem „erfolgreichen“ Lauf des Update-Scripts der Apache nicht starten, müssen noch alle Nutzer-Accounts im System registriert werden. Dies geht am einfachsten nach dieser Anleitung. Wichtig ist der Teil bzgl. des Skripts groups.sh:

#!/bin/false
#Coming soon. This will differ in some points from the script given at the forums!

Dieses sollte nach Anlegen einer Datei my.cnf im Home-Verzeichnis des Root-Users gestartet werden. Die my.cnf hat dabei das oben genannte Format.

[client]
user=root
password=#password#

Dieses Script legt mit useradd alle ggf. fehlenden Accounts an und setzt nochmals die richtigen Berechtigungen auf allen Ordnern (incl. den FCGI-Konfigurationen der Nutzer). Um dabei etwas Arbeit zu sparen liest es die Daten direkt aus der Datenbank von ispCP, da dort alle nötigen Daten bereits enthalten sind. Ggf. vorhandene Doppelbelegungen von User- und Gruppen-IDs sollte man vorher manuell beheben oder nachträglich anpassen (d.h. bei betroffenen Programmen korrigieren).

Sollte ich einen Punkt übersehen oder vergessen haben, oder gibt es sonst Fragen zu diesem Vorgehen, können diese gerne in den Kommentaren gestellt werden.

P.S.: Danke an beshig für’s Betatesten.

Flattr this!

Keine Kommentare »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress