Es ist immer eine peinliche Anlegenheit, es zugeben zu müssen, aber manchmal löscht man eben mal eine wichtige Datei auf einem Server, die sich dann nicht mehr so einfach wiederherstellen lässt. So ist es mir passiert, als ich letztens auf einem Webserver ein wenig durchsieben und nicht mehr verwendete Zertifikate und Schlüssel löschen wollte. Ärgerlicherweise kam mir dabei auch Schlüssel unter die Finger, der noch in Verwendung war. Am nächsten Tag begrüßte mich dann der Cronjob mit der Meldung, dass apachectl configtest die Schlüsseldatei nicht finden konnte. Der Apache und HTTPS liefen noch, aber nur noch bis zum nächsten Neustart. Wie also wieder an den privaten Schlüssel kommen?

Ärgerlicherweise gehört der private Schlüssel ja zu den Sachen, die man niemals herausgeben soll, daher kann man ihn auch nicht – im Gegensatz zum Zertifikat – nochmal vom Anbieter holen. Ein Backup des Servers existierte zwar, jedoch leider nur die Möglichkeit, es komplett zurückzuspielen, aber nicht einzelne Dateien rauszuholen. Da der Apache aber noch lief, war mir klar, dass der Schlüssel noch im Arbeitsspeicher liegen musste. Also beschloss ich, ihn daher zu beschaffen.

Passe Partout

Praktischerweise haben zwei Franzosen bereits ein passendes Tool namens Passe Partout dafür geschrieben. Die Makefile des Downloads enthält leider einen kleinen Fehler, der zu Fehlern wie undefined reference to `PEM_write_RSAPrivateKey' führt, weshalb man entweder die Version von GitHub herunterladen sollte oder die entsprechende Änderung einfach selbst vornimmt. Das Programm lässt sich dann einfach mit dem Aufruf von ./build.sh kompilieren.

Die Schlüssel aus dem RAM holen

Um die Schlüssel aus dem RAM zu holen, sucht man sich zunächst einen passenden Apache-Prozess:

ps ax | grep apache2

Anschließend übergibt man eine PID aus der ersten Spalte an das Programm.

./passe-partout <pid>

Die Ausgabe meiner Version war deutlich umfangreicher als die in der Dokumentation. Nach einigen Sekunden beendet sich das Programm und die gefundenen Schlüssel solten im aktuellen Ordner liegen. Diese kann man mit ls *.key auflisten. Bei mir konnten nicht unter jedem Apache-Prozess Schlüssel gefunden werden, ich musste einige PIDs durchprobieren, bevor ich Erfolg hatte.

Anschließend muss man nur noch prüfen, welches der richtige Schlüssel für das Zertifikat ist. Dazu vergleicht man den Modulus des Zertifikats mit dem des Schlüssels.

openssl x509 -noout -modulus -in my_cert.pem | openssl md5
openssl rsa -noout -modulus -in my_key.key | openssl md5

Da üblicherweise einige Schlüssel ausgelesen werden, bietet es sich an, den Vergleich automatisch vornehmen zu lassen. Dies geht mit dem mitgelieferten Ruby-Skript match_private_key.rb. Wer jedoch kein Ruby zur Hand hat und nicht installieren möchte, kann auch folgenden Bash-Befehl verwenden:

for f in *key; do [ "$(openssl rsa -noout -modulus -in $f | openssl md5)" == "$(openssl x509 -noout -modulus -in my_cert.pem | openssl md5)" ] && echo "$f"; done