So mancher kennt es – man switcht durch die Konsole des Servers, meistens mit den Pfeiltasten und hämmert auf die Entertaste wenn es gerade passt und man den gleichen Befehl wie vorher nochmals ausführen möchte. Das Problem: Wenn man vorher den rm Befehl mit gleicher Endung genutzt hat, aber eigentlich nicht rm, sondern den Editor ausführen möchte, löscht man die jeweilige Datei. In meinem Fall war das die maltris.org-Konfigurationsdatei des Nginx-Webservers. Zum Glück lief der Server noch, sodass von dem Problem nach Außen hin niemand etwas gemerkt hat.
Nun horte ich unter meiner maltris.org-Domain einige in Entwicklung befindliche Projekte und von allen war die individuelle Konfigurationsdatei weg. Neu schreiben ist eine Möglichkeit, kostet aber eine beachtliche Menge Zeit. Deshalb liegt es nahe, zu versuchen, die aktuell im Server geladenen Dateien wiederherzustellen. Dazu kann man den Speicher auslesen, was folgend erklärt wird.
Zuerst installieren wir gdb. gdb steht für GNU Debugger und ermöglicht das Auslesen des Speichers:
apt-get install gdb
Nun erstellen wir eine Datei, welche wir anschließend ausführen können:
scheissetrifftdenluefter.sh
In diese Datei schreiben wir:
# Set pid of nginx master process here
pid=8841# generate gdb commands from the process’s memory mappings using awk
cat /proc/$pid/maps | awk ‘$6 !~ “^/” {split ($1,addrs,”-“); print “dump memory mem_” addrs[1] ” 0x” addrs[1] ” 0x” addrs[2] ;}END{print “quit”}’ > gdb-commands# use gdb with the -x option to dump these memory regions to mem_* files
gdb -p $pid -x gdb-commands# look for some (any) nginx.conf text
grep worker_connections mem_*
grep server_name mem_*
Alles was nun noch zu tun ist, ist die Prozessnummer (pid) vom Nginx Meisterprozess herauszufinden:
ps aux | grep ‘nginx master’
Die Rückgabe sieht etwa so aus:
root 8841 0.0 0.0 32168 120 ? S Nov26 0:00 nginx: master process /usr/sbin/nginx -c /etc/nginx/nginx.conf
Die pid ist die Nummer hinter dem User, mit dem Nginx den Meisterprozess startet welcher dann die Arbeiterprozesse startet, also 8841. Entsprechend muss in der .sh-Datei die pid eingetragen werden.
Mit chmod +x wird die Datei gefügig – ausführbar – gemacht:
chmod +x scheissetrifftdenluefter.sh
Anschließend wird die Datei, sofern der Nutzer im gleichen Verzeichnis wie die Datei befindlich, wiefolgt ausgeführt:
./scheissetrifftdenluefter.sh
Nun erfolgt eine Ausgabe an deren Ende etwas steht, das etwa zu folgender passt:
Binary file mem_0099f000 matches
Im Verzeichnis wurden nun mehrere Dateien angelegt. Darunter auch die Datei mem_0099f000.
In dieser Datei kann nun nach brauchbarem Material gesucht werden. Ich habe nicht die komplette Konfiguration zurückholen können, da Nginx von Zeit zu Zeit bestimmte Speicherabschnitte mit anderen Daten beschreibt, was dafür sorgt das so mancher Text kaum oder gar nicht mehr zu gebrauchen ist. Probiert einfach aus und versucht euer Bestes.
Weiterhin gibt es noch was feines für die “Root-Akrobaten” unter euch. Nennt sich “etckeeper” und sorgt wohl dafür, dass Änderungen über Bazaar (bzr, Version-Control Software die von Inkscape, Emacs und Co. genutzt wird) einmal pro Tag zum lokalen Repository (wird bei der Installation automatisch angelegt) committet werden. Also wird alle 24 Stunden die geänderte Datei gesichert und man kann auch mal versehentlich was löschen, da im Repo noch immer die alten Versionen vorrätig sind. Das ist äußerst empfehlenswert und wird in Kürze auch bei mir, nicht ausschließlich für die Nginx-Konfigurationsdateien, zur Verwendung kommen.
Macht unheimlich viel Arbeit, wenn auch ein schöner Hack. Ich hoffe du hast draus gelernt und zerballerst nicht mehr die Configs auf Produktivsystemen :D