AdminDay 2009: Wenn sich der Admin in den Fuß schießt

Die Untiefen des Administrator-Alltags erfordern viel Wissen, das meist am praktischen Beispiel einer selbstverschuldeten Katastrophe erworben werden muss. Auf den folgenden Seiten erzählen heise-Netze-Leser über ihre Admin-Patzer.

In Pocket speichern vorlesen Druckansicht 15 Kommentare lesen
Lesezeit: 17 Min.
Von
  • Reiko Kaps
Inhaltsverzeichnis

Administratoren sind wie Kapitäne. Ihre Schiffe heißen Netzwerk, Server und Router, doch wie echte Seemänner müssen sie sich um den nötigen Proviant kümmern, gefährliche Fahrwasser erkennen und aufkommende Stürme umfahren. Am Morgen überprüfen sie Passagierlisten und horchen auf den Ping der Server. Abends schrubben sie das Vordeck und müssen sich anschließend beim Käptn's-Dinner auch noch für die eingeschlagenen Kurse rechtfertigen.

Wie auch auf See führen Fehlentscheidung zu fatalen Ergebnissen: Daten gehen über Bord, auf der ausgewählten Route herrscht Gegenwind und einige Passagiere hängen immer seekrank über der Reling. Rettungsmaßnahmen wie Datensicherung oder Neuinstallation erzürnen oft die Mannschaft, die im schlimmsten Fall meutert.

Die Untiefen des Administrator-Alltags erfordern also viel Lernen, meist am praktischen Beispiel einer selbstverschuldeten Katastrophe. Auf den folgenden Seiten erzählen heise-Netze-Leser von ihren Patzern und Fußschüssen.

Unbilden lauern – trotz oder wegen aller Aufmerksamkeit – an allen möglichen Stellen. Die Wahrscheinlichkeit für einen gelungenen Fußschuss scheint bei den Dateisystem-Kommandos rm, mv und cp unter Unix am höchsten, was sich an der Zahl der Zuschriften zeigt. Wir haben daher die Geschichten zu rm und seinen Schwesterbefehlen zusammengefasst.

Unix-Kommandos nehmen an, dass der Administrator weiß, was er vorhat. Zu lästigen Nachfragen, wie sie etwa in Form diverser Dialogboxen unter Windows auftauchen, lassen sich die Dateikommandos rm, mv oder cp auf Unix-Maschinen zwar bewegen (Parameter -i), aber letztlich mindern diese nur das Arbeitstempo oder stören den Skriptablauf. Eine gewisse Berühmtheit hat in diesem Zusammenhang der Löschbefehl rm erlangt, der ganze Verzeichnisbäume mit nur zwei Optionen (-rf) ins Nirwana schickt. Erfahrene Systemverwalter übersetzen das Kommando samt der beiden Parameter daher auch mit "read mail really fast" und warnen ausdrücklich vor dem unbedachten Aufruf von rm -rf /.

Deutlich eleganter erreicht man die gleiche Katastrophe, wenn man per Wildcard alle versteckten Dateien unter /root in einem Rutsch löschen will: Der Befehl rm -rf .* erledigt die Aufgabe zuverlässig, arbeitet sich im Dateibaum nach oben und schreddert das System, weil der Ausdruck .* dummerweise auch auf das übergeordnete Verzeichnis .. passt.

Ebenfalls auf der Verliererseite sind Admins, die sich den Kopf über Fehlermeldungen zerbrechen: Nach einem Tag voller Skripte, die Arbeiten auf Windows-Rechnern erledigen, soll der Unix-Server Daten per Skript einsammeln und wegsortieren: Nach den ganzen Batch-Skripten, deren Kommentare mit "rem" beginnen, erscheint dem müden Admin ein "rm" am Zeilenanfang durchaus als eine sinnvolle Kommentarmarkierung. Nach dem Start meldet das Programm zwar noch, dass es "cp" nicht finden könne, doch Quelle und Ziel landen unwiederbringlich im Orkus. Admins, die des Öfteren C programmieren, schweben dabei in noch größerer Gefahr. Verwechselt er das Shell-Kommentarzeichen # mit dem C-typischen //, sollte er schon einmal die Platten mit der neusten Datensicherung aus dem Schrank holen:

rm -rf /kannweg /kannauchweg // /sollnichtweg

Apropos Löschen in Shell-Skripten: Die Zeile rm -rf $DATAPATH/$DATADIR soll Daten unter $DATAPATH/$DATADIR entsorgen, doch tut sie das nur dann, wenn beide Variablen existieren und nicht leer sind. Ansonsten gilt auch hier "Read mail really fast".

In die Kategorie "shit happens" fallen vagabundierende Leerzeichen in den Pfadangaben eines Löschbefehls (statt rm -rf /tmp/ besser nicht rm -rf / tmp eintippen. Ärgerlich wird es jedoch bei Tastaturen die Sonderzeichen wie ~ erst nach einem weiteren Tastendruck in die Konsole schreiben und damit alle Dateien im Verzeichnis entsorgen. Auch die Reihenfolge der Kommandoparameter spielt bei rm eine nicht zu unterschätzende Rolle. Während der Admin älterer Unixe mit rm -i * die Löschung jeder Datei abnicken darf, nimmt das Kommando bei der Eingabe von rm * -i an, dass der letzte Parameter eine Datei ist.

Will man trotzdem Dateien rekursiv löschen, etwa weil der Server ausgedient hat, sollte man ihn sicherheitshalber vom LAN abstöpseln – vergessene Netzwerklaufwerke könnten sonst massiven Schaden nehmen.

Der Befehl shutdown startet Unix-Rechner neu oder schaltet sie aus. Gäbe es dort nicht den Prozesstöter kill, könnte man auch shutdown als Killeranwendung bezeichnen.

Der Parameter -h gibt bei vielen Unix-Kommandos eine Kurzhilfe aus. Wer damit mal eben auf einem älteren Server die Optionen von shutdown nachschauen will ... fährt ihn herunter.

Unter Linux passiert das zwar nicht mehr so einfach, ein zweiter Parameter ist dafür notwendig. Das schützt den Admin jedoch nicht vor Fehlinterpretationen:

Kollege: "Wie fährt man denn einen Linux-Server runter?"
Admin: "Mit dem Kommando shutdown -h now"
... Klicker di klacker di klick ...
Kollege: "Dann fährt er auch wieder hoch, oder?"
Antwort: "Nein, das wäre dann shutdown -r now"
Kollege: "Mist! Dann muss ich jetzt doch die 80 Kilometer ins Rechenzentrum fahren!"

Solche Vorkommnisse müssen einem erfahrenen Administrator zu der niederschmetternden Erkenntnis gebraucht, die er einem Neuling mitteilte: "90 Prozent aller Fehler sitzen vor dem Monitor ..." Ein Zwischenruf vom anderen Ende des Büros: "... Mist ! ich habe den falschen Server heruntergefahren ...". Der erfahrene Kollege fährt wenig beeindruckt fort: "Ich korrigiere: 95 Prozent ..."

Vertieft in die Arbeit, installierte ich per RDP eine Software auf einem Windows-Server. Scheint alles gut zu laufen, Routine eben, da klingelt das Telefon: Ein Kunde, der sich nicht mit irgendeinem Supporter zufriedengeben will.

Kunde: "..., das Netzwerk an meinem Laptop funktioniert nicht".
Admin: "Alles kein Problem, machen'se mal Rechtsklick auf die Eigenschaften in der Netzwerkumgebung. Ist das Symbol LAN-Verbindung grau?"
Kunde: "Ja."
Admin: "Ja, sicher?"

Zum Nachstellen der Situation klickte ich mich zu den Einstellungen durch und deaktiviert die Netzwerkverbindung. Spontan bricht die die RDP-Sitzung zusammen, die auf dem 200 Kilometer weit entfernten Server lief.

Man nehme eine zentrale LDAP-Benutzerverwaltung, die aus Sicherheitsgründen per SSL an diversen Terminals, an einen Webserver und E-Mail-Server angebunden ist. Auch der Zugriff auf E-Mails und die technische Verwaltung der Terminals, die auf mehrere Standorte verteilt sind, läuft über SSL-verschlüsselte Verbindungen. Zugriffe des Administrator per SSH wurden natürlich gesperrt. Der gesamte Aufbau funktioniert ein Jahr lang perfekt, doch dann ging nichts mehr: Leider hatte ich die dazu benötigten SSL-Zertifikate zu später Stunde mit einer Laufzeit von einem Jahr erstellt. Fernwartung E-Mails zwischen den Admins funktionierte natürlich auch nicht mehr ...

Lotus-Domino-Server haben einen Adminp-Prozess, der sämtliche administrativen Aufgaben in eine Datenbank schreibt und diese später ausführt. Lange vor meiner Zeit hatte mein Vorgänger einige Postfächer falsch angelegt und deren Löschung wieder über Adminp in Auftrag gegeben. Adminp-Aufgaben müssen Admins jedoch bestätigen, was für diese Aufgaben nicht passierte – letztlich standen sie in den kommenden drei Jahren in der Warteschlange.

Diese Woche habe ich den Adminp-Prozess per Hand angestoßen und somit alle ausstehenden Verwaltungsanfragen ausgeführt. Leider habe ich versäumt, den Inhalt der Warteschlange zu überprüfen: Die alten Verwaltungsaufgaben taten, was sie sollten und löschten ungefähr zehn Mail-Datenbanken, leider auch einige der Chefs.

Jeder Administrator entwickelt eigene Strategien, die dem laufenden Rechnerpark vor den Unbilden von Updates sichern sollen. Arbeitet beispielsweise ein Server mit zwei per RAID-1 gespiegelte Platten, lässt sich eine davon vor Updates entfernen. Schlägt die Software-Aktualisierung fehl oder geht sonst irgendetwas daneben, baut der Admin die zweite Platte aus, legt sie beiseite, schraubt die erste Platte wieder ein und startet den Rechner neu. Anschließend kommt die zweite Platte wieder ins RAID, das sogleich die von Platte 1 auf Platte 2 spiegelt und damit den Zustand vor dem Update wiederherstellt. Diese Verfahren klingt praktikabel, stößt jedoch dann an Grenzen, wenn man gleichzeitig zwei Server mit identischen Platten aber unterschiedlichen RAID-Controllern aktualisieren will.

Nun kam der Tag, an dem zwei Systeme in Abhängigkeit voneinander aktualisiert und getestet werden mussten. Aus beiden Systemen wurden je eine Platte entfernt und mehr oder minder erfolgreich aktualisiert. Ein nachfolgender Funktionstest ging schief, sodass das Restore-Szenario durchgeführt werden musste. So kam es, wie es kommen musste: Die Platten wurden vertauscht und in das jeweils andere System installiert. Das Problem: die Server waren zwar vom gleichen Hersteller, hatten auch das gleiche Chassis, allerdings völlig unterschiedliche RAID-Controller, die mit den anderen Platten nichts anfangen konnten.

Eine Uni Mitte der 80ziger, drei Rechner mit Apollo Domain OS und ich, ein recht frischer Administrator. Meine erste Aufgabe: Zwei Maschinen mit 512 MByte Speicherplatz gegen eine neue mit einem (!) GByte tauschen. Die Daten der beiden alten sollen zusammen auf dem neuen landen, damit die alten für andere Arbeitsgruppen eingesetzt werden können. Ich sollte das nachts erledigen, damit am morgen die Arbeit ohne Unterbrechung weitergehen kann.

Als alle auf dem Heimweg waren, tippte ich in einem Fenster mit eingefrorenem Eingabepuffer folgende Befehle untereinander weg:

cp -r //node_a/DATA/* //node_c/DATA/  
cp -r //node_b/DATA/* //node_c/DATA/
rm -r //node_a/DATA/*
rm -r //node_b/DATA/*

Damals gab es noch nicht so viele Sicherheitsmaßnahmen, wie die auf "rm -i" gealiasten rm-Kommandos in den heutigen Linux Distributionen. Ein Kommando tat genau das, was man schrieb. Nicht mehr, aber auch nicht weniger.

Ich warf noch einen zweiten Blick auf die Kommandos, war zufrieden und hob die Einfrierung auf. Das erste Kopierkommando lief, und die wiederholte Ausmessung des geringer werdenden Plattenplatzes in einem zweite Fenster ergab eine restliche Ausführungsdauer von etwa einer Stunde. Also genügend Zeit für ein Weizenbier und eine Pizza. Gerade da, als das Bier bestellt war, blitze mir ein Gedanke durch den Kopf: "Was macht cp eigentlich, wenn eine Datei schon vorhanden ist?" Ich wusste es nicht, zahlt die Rechung und bewegte mich in Richtung Campus. Wenige Minuten später las ich die Antwort, die sinngemäß etwa so lautete:

> cp -r //node_a/DATA/* //node_c/DATA/	
successful
> cp -r //node_b/DATA/* //node_c/DATA/
error "Keine Methode zur Behandlung von Zielkonflikten angegeben. Befehl wird
abgebrochen."
> rm -r //node_a/DATA/*
successful
> rm -r //node_b/DATA/*
successful

Ich hatte also eine saubere Kopie des ersten Servers und einen sauberen zweiten Server. Die Nächte der nächsten Wochen verbrachte ich damit, ein Vollbackup und die über 100 darauf aufbauenden inkrementellen Backups einzuspielen. Ich habe von diesem Tage an nie wieder einen rm-Befehl über den Kommandozeilenpuffer abgeschickt, bevor alle vorangehenden Aktionen überprüft und erfolgreich abgeschlossen waren.

Ich bin zwar nicht der Admin, war aber massiv von einem Admin-Fehler betroffen: Während ich längere Zeit nicht im Büro war, wurden alle meine Mails auf unserem Exchange-Server an einen Kollegen weitergeleitet. Das Original verblieb in meinem Postfach.

Das Problem trat auf, als eine Mail mit dem Wörtchen "Viagra" eintrudelte. Anscheinend gibt es eine Filterung auf Spam, die von unserer Firma ausgeht. Der Server verweigerte also die Weiterleitung des "Viagra"-Spams an meinen Kollegen und versuchte, mich darüber per E-Mail zu informieren: "Message forwarding has been denied because of rule 'viagra'".

Wie alle anderen Mails wurde dieser Hinweis ebenfalls an meinen Kollegen weitergleitet. Genaugenommen blieb es beim Versuch, da auch diese Mail gegen die Viagra-Regel verstieß. Der Kollege bekam den Hinweis also nicht, ich jedoch eine neue Mail über diesen Regelverstoß.

Als ich mich mal wieder von zu Hause einloggte, um die Mails zu checken, fand ich zu meinem Erschrecken circa 55.000 Mails – zu 99,999 Prozent waren Hinweise auf die Regelverstöße. Versuche, diese Mailflut über das Outlook-Webinterface zu bewältigen, bleiben erfolglos: Innerhalb weniger Minuten waren es hunderte neue Mails. Erst am nächsten Tag schaffte unser EDV-Dienstleister es, den Hinweis abzuschalten, nachdem sie zunächst das Problem erst mal gar nicht wahrhaben wollten. Die Kollegen wunderten sich unterdessen, weshalb der Server so langsam war – abgestürzt ist er nicht!

Sonntagnachmittag, großer Wechsel auf einem Router mit paralleler Telefonkonferenz zum Kunden, der Ähnliches auf seinem Router eintatzelte ...

In weiser Voraussicht – es handelte sich um einen Cisco-Router – begann ich die Einrichtungssitzung mit dem Kommando reload in 30 – also Router in 30 Minuten neu starten. Nur für den Fall, dass ich mich aussperre.

Nun begann die Sitzung: Konfiguration hier angepasst, Konfiguration da angepasst, auf die Rückmeldung des Kunden warten, noch ein wenig optimieren und praktisch fertig. Da bricht die Telefonleitung zusammen! Eine einzige Frage war noch offen.

Wir versuchten derweil, die Telefonkonferenz wieder aufzubauen. Das dauert jedoch einige Minuten, da offensichtlich eine Telefonanlage hängt. Kaum steht die Leitung und wir haben die ersten Wörter gewechselt, sehe ich mit blankem Entsetzen, wie sich mein Router zum Neustart verabschiedet, ein wr hatte ich natürlich noch nicht abgesetzt – bitte nicht schimpfen, liebe Cisco-Trainer. Die Konfiguration war noch ungesichert, und so verabschiedeten sich über 20 Minuten Konfigurationsmarathon.

Manchmal hat der Administrator die Chance, seinen Fußschuss ungeschehen zu machen. Das schmerzt zwar oft, spart aber meist viel Zeit:

11:50 Uhr. Ich ändere schnell die Konfiguration des SSH-Servers. Server einmal stoppen und wieder starten:

# vi /etc/sshd/sshd_config
# /etc/init.d/sshd stop
# /etc/init.d/sshd start

Der zweite Befehl beendet neben dem Server-Prozess auch die aktuelle SSH-Sitzung. Leider steht der Rechner 20 Kilometer entfernt, wird aber in 10 Minuten gebraucht. Was also tun?

Der Netzwerkscanner nmap zeigt auf dem Server eine aktiven FTP-Server, bei dem sich ein Root-Benutzer anmelden kann.

# ftp host
ftp> get /etc/init.d/sshd
ftp> cd /etc/cron.hourly
ftp> put sshd
ftp> chmod +x sshd

Punkt 12:00 Uhr weckt Cron den SSH-Server auf. Nach dem Anmelden schnell die Datei /etc/cron.hourly/sshd löschen, und die Situation ist gerettet!

In einer ähnlichen Situation fummelten zwei Hobby-Admins auf ihrem Root-Server am installierten Debian-Linux (Woody). Der Hoster bot zu jener Zeit weder einen automatischen Neustart noch ein Rescue-System an, das die Situation kostengünstig hätte retten könnten. Ob es damals ein Up- oder ein Downgrade war, das den SSH-Server lahmlegte, ist nicht mehr sicher festzustellen:

Große Panik, wir kamen nicht mehr per SSH-Konsole auf den Server. Allerdings liefen alle anderen Dienste wie FTP, WWW und E-Mail ohne Probleme weiter. Ach, FTP! Das ist ja praktisch. Damit bekommt man ja Dateien auf den Server und wieder runter. Und der Webserver führt CGIs aus. Damit wären wir ja fast schon wieder drinnen!

Der Gedanke wurde schnell in einem CGI-Script umgesetz, das uns per ps mitteilte, dass der SSH-Server nicht läuft. Was wir ja bereits wussten! Also einmal den SSH-Server neu starten, vielleicht sagt er dabei ja was Sinnvolles. Aber unser CGI-Script läuft mit den Rechten des Webserver-Benutzer www-data. Die üblichen Methoden via su oder sudo wollten auch nicht so recht im CGI funktionieren, da sie interaktiv ein Passwort abfragen.

Hilfe versprach das glücklicherweise installierte Tool expect. Das CGI-Skript wechselte per expect in den Root-Account und startet testweise den SSH-Server. Der beendet sich wegen falscher Parameter in der Konfiguration wieder, schrieb aber ins Browser-Fenster, dass er den eingestellten Wert von ListenAddr nicht mag.

Die neue Fassung des Skripts ändert mit dem Stream-Editor sed den Eintrag in der Einrichtungsdatei und wirft erneut den Server an. Nach einigen Sekunden konnten wir uns wieder anmelden.

#!/bin/sh

echo "Content-Type: text/plain"
echo
echo "-----------------"
expect 2>&1 <<END
set timeout 30
spawn "su"
expect -re "Password: "
sleep 1
send "XXX\r"
expect -re "#"
send "/etc/init.d/ssh start"
expect -re "#"
#send "apt-get install ssh=1:3.4p1-1.woody.3 -y --force-yes\r"
#expect -re "#"
#send "sed -i '/ListenAddr/ s/::/0.0.0.0/' /etc/ssh/sshd_config\r"
#expect -re "ssp:"
END

Neben den Zuschriften schrieben viele Leser des Aufrufs ihre Erlebnisse im Forum auf, deren Höhepunkte wir hier als Linkliste zeigen: (rek)