Sie möchten Ihre Server-Infrastruktur gegen Viren, Einbrüche und Stromausfälle schützen und benötigen dafür Hardware, Software oder Dienstleistungen aus einer Hand?
Dann nehmen Sie Kontakt mit uns auf. Wir nehmen uns gerne Zeit für eine ausführliche und kostenlose Erstberatung.
Dieser Artikel wurde im Mai 2010 erstmals veröffentlicht und seitdem nicht aktualisiert; der Inhalt ist eventuell veraltet. Wir planen keine Überarbeitung des Artikels, werden aber Fehler bei Bekanntwerden korrigieren.
Mitteilungen über Fehler nehmen wir gerne per E-Mail entgegen.
Dieser Artikel beschäftigt sich mit einer Methode, mehrere Server oder PCs, die gemeinsam an einer USV betrieben werden, bei Stromausfall geordnet herunterzufahren. Der Artikel bezieht sich zwar auf Smart-USVs von APC und die zugehörige Software Powerchute Business Edition in der Version 8.0.1, die hier gezeigten Lösungsansätze lassen sich aber auf andere Umfelder übertragen.
Um beim Ausschalten eines Servers oder PCs Datenkonsistenz sicherzustellen und die Hardware vor Schäden zu bewahren, darf dem betreffenden Gerät nicht einfach die Stromzufuhr entzogen werden, sondern es muß geordnet heruntergefahren werden [Link]. Im Falle eines plötzlichen, unangekündigten Stromausfalls ist dies nicht möglich, es sei denn, die betreffenden Geräte sind an eine unterbrechungsfreie Stromversorgung (USV) angeschlossen.
Neben der Überbrückung von Stromausfällen haben USVs noch andere Aufgaben wie zum Beispiel den Schutz der angeschlossenen Geräte vor Spannungsschwankungen im Stromnetz.
Es gibt USVs in vielen Größenordnungen, vom Kleingerät für Einzelplatz-PCs, das einen Stromausfall gerade so lange überbrücken kann, um dem PC ein geordnetes Herunterfahren zu ermöglichen, bis hin zu USVs für Rechenzentren mit Tausenden von Servern, deren Akkus und Diesel-Tanks in großen Gebäuden mit mehreren Stockwerken untergebracht sind und die mehrere Tage oder Wochen autonomen Betrieb ermöglichen [Link].
Es gibt im wesentlichen drei Bauarten von USVs: Offline, Line-Interactive und Online. Von der Bauart hängt ab, wie hoch der Wirkungsgrad einer USV ist, wie schnell sie einen Stromausfall erkennt und auf Eigenversorgung umschaltet, und gegen welche Art von Störungen im Stromnetz sie die angeschlossenen Verbraucher schützt [Link].
Ein weiteres elementares Merkmal zur Unterscheidung der USVs ist die Leistungsklasse. Die Leistungsklasse einer USV wird üblicherweise in Voltampere (VA) angegeben; bei der Planung einer USV-Anlage sollte die Leistungsklasse jeder USV so gewählt werden, daß sie ungefähr der gemeinsamen Spitzenlast aller angeschlossenen Verbraucher entspricht. Dies sorgt nicht nur für eine sinnvolle maximale Laufzeit der USV von mindestens einigen Minuten bei Stromausfall, sondern die (teuren) Wandler und Wechselrichter müssen die angeschlossene Last ebenfalls handhaben können.
Bei der Auslegung einer USV ist genau auf die für die Angabe der Leistungsklasse verwendete Einheit zu achten, je nach Art der angeschlossenen Verbraucher ist zwischen Watt (W) und Voltampere (VA) umzurechnen [Link]. Überdimensionierung schadet keinem Gerät, macht die USVs aber teurer und sorgt für einen schlechteren Wirkungsgrad.
Wir empfehlen unseren Kunden für typische Serverräume in kleineren Unternehmen in der Regel eine Überdimensionierung um den Faktor 1.5, was meistens einen guten Kompromiß zwischen allen Anforderungen darstellt: Der Wirkungsgrad verschlechtert sich nicht merklich, die Mehrkosten halten sich im Rahmen, die Laufzeit verlängert sich, und wichtige Kleinverbraucher wie KVM-over-IP-Geräte, deren Funktion auch bei Stromausfall essentiell ist, können später hinzugefügt werden.
Viele kleinere und mittlere Unternehmen (KMUs) betreiben nur wenige Server, die sich in ein oder zwei 19″-Racks in einem dedizierten Serverraum befinden und gegen Stromausfall zu sichern sind. Da der Platz im 19″-Rack kostbar ist und der Kaufpreis einer USV bezogen auf deren Ausgangsleistung für größere USVs im allgemeinen günstiger ist als für kleine, ist es meist sinnvoll, alle Server über eine einzige USV abzusichern.
Dies allerdings ist ohne erhebliche zusätzliche Investitionen mit fast keiner USV machbar. In der Regel wird eine USV über eine serielle oder USB-Schnittstelle an einen Server angebunden; auf diesem arbeitet eine Software, die vom Hersteller der USV geliefert wird, stets den Zustand der USV kennt und bei Bedarf den Server herunterfährt. Das Problem liegt darin, daß andere Rechner zunächst keine Verbindung zur USV herstellen und damit nicht auf Stromausfälle reagieren können.
Dieses Problem kann auf mehrere Arten gelöst werden: Manche USVs besitzen Einschübe für zusätzliche serielle oder USB-Schnittstellen; darüber lassen sich zwei (selten auch mehr) Rechner vollwertig an die USV anschließen. Andere USVs besitzen einen Einschub für ein Netzwerkmodul, mit dem entsprechende Software kommunizieren kann. Dies wäre eigentlich der Königsweg, kann eine solche Netzwerkschnittstelle doch fast beliebig viele Rechner anbinden.
Ein solches Modul sollte das gängige Ethernet mit RJ45-Anschlüssen als Medium unterstützen, seine Geschwindigkeit ist dabei irrelevant: Bereits die Datenrate des antiken Standards 10Base-T liegt grob um den Faktor 100 über der maximalen Datenrate einer üblichen RS232-Schnittstelle.
Allen Nachrüst-Optionen ist jedoch die völlig überzogene Preisvorstellung des jeweiligen Herstellers gemeinsam. So kosten die Netzwerk-Module oft ähnlich viel wie die USV, zudem lassen sich diese Module oft nicht mehr mit kostenloser Software des Herstellers ansprechen, sondern erweiterte Software muß erworben und teuer bezahlt werden. Die Nachrüst-Module mit seriellen oder USB-Schnittstellen sind etwas günstiger und funktionieren meist noch mit der kostenlosen Software des jeweiligen Herstellers, dennoch sind auch sie immer noch maßlos überteuert.
Es verbleibt ein dritter Weg, nämlich die Lösung des Problems per Software. Dabei muß derjenige Rechner, der mit der USV direkt verbunden ist, über Software-Protokolle die anderen Rechner über den Zustand der USV informieren. Da entsprechende Software von den USV-Herstellern gar nicht oder wieder nur gegen teures Geld angeboten wird, lohnt sich der Blick auf ein kleines Projekt, welches wir vor einiger Zeit bei einem Kunden durchgeführt haben.
Gegeben waren ein Server mit Microsoft Windows 2003 Server R2 und zwei Server mit Linux (SuSE SLES, Debian Lenny), eine USV mit einer für die drei Server gut ausreichenden Ausgangsleistung sowie eine TCP/IP-Infrastruktur, an die alle Server angeschlossen waren.
Die USV stammte aus der Serie "Smart-UPS" des bei KMUs beliebten Herstellers APC und war mit dem Windows-Server über eine serielle Schnittstelle verbunden. Auf dem Windows-Server war die von APC kostenlos erhältliche und für den Betrieb mit der USV vorgesehene Software "Powerchute Business Edition 8.0.1 für Windows" installiert und ordnungsgemäß konfiguriert.
Diese (auch für Linux erhältliche) Software wird im folgenden mit "PBE" bezeichnet.
Das Ziel des Projekts bestand darin, ohne Anschaffung zusätzlicher Hardware oder Software sicherzustellen, daß nicht nur der Windows-Server, sondern auch die beiden Linux-Server geordnet heruntergefahren werden, sobald ein Stromausfall auftrat.
PBE läßt sich detailliert konfigurieren; fast jedem Ereignis, das im Laufe des Betriebs einer USV auftreten kann, läßt sich ein Programm zuordnen, das bei Eintritt des Ereignisses ausgeführt wird. Wird hierfür ein Script verwendet, das sich mit den Linux-Servern verbinden und dort die Kommandos zum Herunterfahren absetzen kann, ist das Problem gelöst.
Daß die Umsetzung auch eines einfachen Prinzips viele unerwartete Fallstricke bergen und viel Zeit kosten kann, wird im weiteren Verlauf des Artikels deutlich.
Praktisch auf jedem Linux-Server, der aus der Ferne administriert werden kann, ist ein sogenannter SSH-Daemon installiert, meist der openssh-Daemon. Diese Software erlaubt Benutzern über eine verschlüsselte Netzwerk-Verbindung einen Login und stellt eine Shell zur Verfügung. Für viele Administratoren stellt SSH aufgrund der Sicherheit die Standardmethode zum Zugriff auf Linux-Server dar. Unter Linux wird ein guter Teil der Administration auf der Kommandozeile erledigt, und so gibt es fast immer einen Kommandozeilen-Befehl zum Herunterfahren des Systems.
Das SSH-Protokoll und der openssh-Daemon bieten noch eine Unzahl weiterer Möglichkeiten. Leider kann dieser Artikels nicht ausführlich auf Subsysteme, Tunneling, die verschiedenen Arten der Authentifizierung und weitere Spezialitäten eingehen; es gibt aber genügend Literatur darüber.
Zum Zugriff auf einen SSH-Server von Windows aus wird entsprechende Client-Software benötigt. So wie unter Linux fast immer der openssh-Daemon als Server verwendet wird, so hat sich unter Windows das kostenlose, zuverlässige und voll ausgestattete putty als Standard-Client durchgesetzt. putty beherrscht diverse Terminal-Emulationen, kann mit verschiedenen Zeichen-Encodings umgehen und kennt nahezu alle Spezialitäten des SSH-Protokolls, Tunneling eingeschlossen.
Damit ist klar, wie der Remote-Shutdown eines Linux-Servers von Windows aus prinzipiell ablaufen kann: Linux-Login per SSH, Absetzen des shutdown-Befehls.
putty als Programm mit grafischer Oberfläche ist für die Verwendung auf der Kommandozeile aber nur bedingt geeignet. Es gibt deshalb auch eine Kommandozeilen-Version von putty namens plink, die sehr gut in Scripts eingesetzt werden kann. plink kann SSH-Verbindungen initiieren und nach dem Login auf dem entfernten Rechner Befehle ausführen. Ist plink im Verzeichnis c:\programme\putty installiert, so wird mit dem Kommando
C:\>c:\programme\plink -ssh 192.168.20.249 -l shutdown -pw geheim \ /sbin/shutdown -h now
Folgendes erreicht: plink versucht, eine SSH-Verbindung zu 192.168.20.249 aufzubauen und dort den Befehl "/sbin/shutdown -h now" auszuführen, beides im Namen des Benutzers "shutdown" mit dem Paßwort "geheim". Wir gehen unten noch darauf ein, welche Schwierigkeiten auf der Linux-Seite der Ausführung dieses Befehls im Wege stehen können.
Für obigen Code gilt übrigens: Der Backslash (\) wird als Zeichen für die Zeilenfortsetzung gebraucht. Steht der Backslash als letztes Zeichen einer Zeile, so ist er beim Abtippen des Kommandos ersatzlos wegzulassen und die nächste Zeile ohne Zeilenumbruch und ohne führende Leerzeichen anzuhängen. Obiges Beispiel besteht demnach in Wirklichkeit aus einer einzigen Zeile (die allerdings zu lange ist für den zur Verfügung stehenden Platz). Wir werden dies im ganzen Artikel so handhaben.
Wir kommen nicht umhin, kurz auf die Verwaltung von SSH-Schlüsseln durch putty und plink einzugehen. Der Grund dafür wird in den folgenden Kapiteln ersichtlich.
Eine SSH-Verbindung wird (aus Sicht des Anwenders am Client) auf eine der folgende Arten aufgebaut: Durch direkte Angabe von Benutzername und Paßwort, durch Übersendung eines elektronischen Zertifikats an den Server, oder durch automatische Abholung der benötigten Login-Daten oder Zertifikate aus einer Infrastruktur für Authentifizierung und Berechtigung (Active Directory, SSH-Agent, Radius-Server) und Übersendung an den Server.
In der überwältigenden Mehrzahl aller Fälle kommt in KMUs die erste Variante zum Einsatz, weil dafür keine Zertifikate verwaltet werden müssen, weil keine zentrale Authentifizierungs-Infrastruktur aufgebaut oder erweitert werden muß, und weil sie hohe Sicherheit bietet, zumindest bei Verwendung von SSH2 als Protokoll und sorgfältigem Umgang mit den öffentlichen Schlüsseln der SSH-Server.
In allen Fällen wird die Verbindung unter Einsatz asymmetrischer Verschlüsselung aufgebaut. Dabei tauschen Client und Server unter anderem öffentliche Schlüssel aus, anhand derer beide Maschinen zuverlässig identifiziert werden können. Diese Identifizierung ist vor allem für die Client-Seite, also den Anwender, aus folgendem Grund sehr wichtig:
Gelingt es einem Angreifer, einen Anwender auf einen präparierten SSH-Server zu locken (anstelle desjenigen, mit dem sich der Anwender eigentlich verbinden wollte), beispielsweise durch ARP-Spoofing oder DNS-Manipulationen, so könnten dort die Login-Daten des Anwenders abgegriffen werden. Welche Konsequenzen sich daraus ergeben, hängt von der Art der Anmeldung (Login / Paßwort oder Zertifikat) und von weiteren Parametern ab.
Aus diesem Grund geben putty und plink eine Warnung aus, wenn sie eine SSH-Verbindung zu einem bislang unbekannten Server aufbauen sollen. Im Warnhinweis ist unter anderem der Hash-Wert des öffentlichen Schlüssels des Servers enthalten, der den Schlüssel eindeutig identifiziert. Der Anwender kann die Identität des Servers anhand des Hash-Wertes prüfen, sofern ihm der korrekte Hash-Wert vorab mitgeteilt worden ist. Nach Bestätigung der Warnung durch den Anwender speichern plink und putty den Hash-Wert, so daß bei zukünftigen Verbindungen zum selben Server keine Nachfrage mehr erfolgt; ohne Bestätigung der Warnung bauen putty und plink die Verbindung nicht auf.
Von zentraler Bedeutung ist nun, daß putty und plink diese Schlüssel nur für denjenigen Benutzer speichern, in dessen Namen sie gerade ausgeführt werden. Die Schlüssel werden in der Windows-Registry im Zweig HKEY_CURRENT_USER\... abgelegt [Link]. Dieses Vorgehen ist sinnvoll, weil sich Anwender, die denselben PC nutzen, an verschiedene SSH-Server verbinden können und weil deshalb die Warnungen vor unbekannten Servern pro Anwender erfolgen sollten.
Im Zusammenspiel mit den anderen für unser Projekt benötigten Software-Komponenten können dadurch jedoch unerwartete Probleme entstehen, deren Natur und Lösung unten beschrieben wird.
Nahezu jedes Linux-System stellt auf der Kommandozeile einen Befehl zum Herunterfahren des Systems zur Verfügung. Es handelt sich dabei um ein eigenständiges Programm, meist mit dem Namen shutdown und oft im Verzeichnis /sbin beheimatet.
Dieses Programm ist in der Regel privilegiert: Es kann nur vom Superuser ausgeführt werden, nicht von regulären Benutzern [Link]. shutdown überprüft bei seinem Aufruf, von wem es aufgerufen wurde, und stellt gegebenenfalls seine Tätigkeit mit einer entsprechenden Fehlermeldung ein (beispielsweise "You must be root to do this") [Link].
Dies ist sinnvoll, denn andernfalls könnte jeder Benutzer, der Zugang zu einem Linux-System hat, dieses absichtlich oder aus Versehen herunterfahren und damit viel Ärger verursachen.
Hier allerdings ist das genannte Verhalten hinderlich. Wie oben gezeigt, soll von Windows aus per plink eine SSH-Verbindung zum Linux-Server aufgebaut und dort der Befehl zum Herunterfahren abgesetzt werden. Dazu muß plink auf entsprechende Login-Daten zugreifen, die als Kommandozeilen-Parameter direkt beim Aufruf an plink übergeben (wie in obigem Beispiel) oder auf andere Weise auf dem Windows-System hinterlegt werden müssen.
Der SSH-Login auf dem Linux-System und die Ausführung von shutdown erfolgen dann im Namen des entsprechenden Benutzers. Nun wird kein Linux-Administrator die Zugangsdaten des Superusers für sein System herausgeben, erst recht nicht für den Zweck der Hinterlegung in Scripts auf Windows-Maschinen. Dies bedeutet Arbeit auf der Linux-Seite:
Zunächst empfiehlt es sich, dort exclusiv für den hier geschilderten Zweck einen neuen Benutzer mit Standardrechten und dem Benutzernamen "shutdown" anzulegen; dessen Paßwort sollte wie immer nicht zu erraten sein. Die Login-Daten dieses Benutzers können auf Windows-Seite bedenkenlos hinterlegt werden, weil er auf dem Linux-System keine besonderen Zugriffsrechte besitzt.
Genau dies bewirkt aber, daß die Ausführung von shutdown durch diesen Benutzer zunächst scheitert. Es gibt mehrere Lösungen für dieses Problem, von denen zwei hier kurz vorgestellt werden sollen.
Die schnellste (und unsauberste) Lösung besteht darin, den Superuser zum Besitzer des Programms /sbin/shutdown zu machen und den Berechtigungen für diese Datei das setuid-Bit hinzuzufügen. Ersteres ist in der Standard-Installation von Linux meist ohnehin der Fall, Letzteres bedeutet, daß das Programm stets im Namen des Benutzers ausgeführt wird, der es besitzt, und nicht im Namen des Benutzers, der es aufruft [Link].
Damit ist ein gravierender Nachteil dieser Lösung klar: Jeder Benutzer, der Shell-Zugang auf dem System hat, könnte das System herunterfahren, weil /sbin/shutdown nun immer im Namen des Superusers ausgeführt wird. Falls /sbin/shutdown zudem aufgrund von Absicht oder aufgrund einer Sicherheitslücke in der Lage wäre, Dateien zu manipulieren, so könnte jeder Benutzer, der es aufrufen kann, entsprechende Manipulationen mit allen Berechtigungen des Superusers durchführen.
Diese Lösung kann sehr einfach implementiert werden:
fenrir:/# ls -l /sbin/shutdown -rwxr-xr-x 1 root root 18196 2008-08-12 16:09 /sbin/shutdown fenrir:/# chmod u+s /sbin/shutdown fenrir:/# ls -l /sbin/shutdown -rwsr-xr-x 1 root root 18196 2008-08-12 16:09 /sbin/shutdown
Eine weit bessere, aber etwas aufwendigere Lösung besteht in der Nutzung des sudo-Mechanismus. Dieser Mechanismus erlaubt es, genau zu konfigurieren, welcher Benutzer welches Programm in wessen Namen ausführen darf. Auf die Konfiguration des sudo-Mechanismus kann hier nicht detailliert eingegangen werden, aber nach Studium der entsprechenden Handbücher sollten keine unüberwindbaren Probleme dabei auftreten.
So könnte dem Benutzer shutdown die Berechtigung erteilt werden, ausschließlich das Programm /sbin/shutdown im Kontext der Superuser-Identität auszuführen. Der Benutzer shutdown könnte danach das System auf folgende Weise herunterfahren:
fenrir:/# sudo /sbin/shutdown -h now
Zur Durchführung der genannten Änderungen an den Dateiattributen von /sbin/shutdown oder der Konfiguration des sudo-Mechanismus werden Superuser-Rechte benötigt. Eventuell muß der Administrator des Linux-Systems die gewünschten Änderungen durchführen.
Im Rahmen unseres Projekts haben wir uns für die Variante 1) entschieden. Beim betreffenden Kunden ist sichergestellt, daß außer dem Administrator (und dem neuen Benutzer "shutdown") keine anderen Benutzer Shell-Zugang auf das System haben oder auf sonstige Weise Programme starten können. Andernfalls hätten wir Variante 2) gewählt.
Eine weitere Idee wäre, die Superuser-Gruppe zum Besitzer des Programms shutdown zu machen und dessen Ausführungsberechtigungen als setgid zu setzen. Ersteres ist bei einer Standard-Installation von Linux wiederum meist bereits der Fall, Letzteres bedeutet, daß das Programm mit den Berechtigungen der Gruppe ausgeführt wird, die es besitzt, und nicht im Namen der Gruppe, der der Benutzer angehört, der es aufruft.
Von diesem Vorgehen ist dringend abzuraten:
Erstens bringt es schlicht nicht den gewünschten Erfolg. Bei unseren Tests auf einer Standard-Installation von Debian Lenny hat sich /sbin/shutdown geweigert, seine Arbeit zu tun, sofern es nicht vom Superuser aufgerufen wurde. Dies galt auch, wenn die ausführbare Datei auf setgid gesetzt war und der aufrufende Benutzer der Superuser-Gruppe angehörte.
Zweitens müßte der Benutzer, der das Programm ausführen können soll, noch der Superuser-Gruppe hinzugefügt werden. Zwar könnte dann nicht mehr jeder Benutzer mit Shell-Zugang das System herunterfahren, aber der betreffende Benutzer erhielte Superuser-Rechte auf einen Teil des Systems, da er nun zur Superuser-Gruppe gehörte und diejenigen Teile des Systems lesen und manipulieren könnte, auf die diese Gruppe Zugriffsrechte besitzt.
Der Vollständigkeit halber sei trotzdem die Implementierung dieser Lösung gezeigt:
fenrir:/# ls -l /sbin/shutdown -rwxr-xr-x 1 root root 18196 2008-08-12 16:09 /sbin/shutdown fenrir:/# chmod g+s /sbin/shutdown fenrir:/# ls -l /sbin/shutdown -rwxr-sr-x 1 root root 18196 2008-08-12 16:09 /sbin/shutdown fenrir:/# usermod -g root shutdown
Ebenfalls ins Leere führt der oft gelesene Rat [Link], die Datei /etc/shutdown.allow anzulegen und den shutdown-Eintrag in /etc/inittab auf bestimmte Weise zu ändern: Dies hat nur Auswirkungen, wenn der Rechner durch einen Affengriff an der lokalen Konsole heruntergefahren werden soll. Beim Aufruf von /sbin/shutdown auf der Kommandozeile in einer Shell haben weder der Parameter -a noch die Datei /etc/shutdown.allow irgendeinen Einfluß [Link].
Ab hier gehen wir davon aus, daß /sbin/shutdown auf dem Linux-System als setuid gesetzt ist. Leser, die sich stattdessen für die Nutzung des sudo-Mechanismus entschieden haben, müssen den Befehlen, die auf der Linux-Seite ausgeführt werden, jeweils den sudo-Befehl voranstellen. Dies gilt nicht nur für die folgenden Beispiele, sondern auch für die später gezeigten Batch-Dateien.
Starten Sie nun auf dem Windows-Server putty und bauen Sie eine SSH-Verbindung zu Ihrem Linux-Server auf, wobei Sie die Login-Daten des Benutzers shutdown verwenden. Wenn Sie jetzt Befehle (wie "date") eingeben können und diese eine sinnvolle Ausgabe (wie das aktuelle Datum) liefern, fahren Sie mit dem nächsten Test fort.
Mißlingt der Verbindungsaufbau oder erhalten Sie keine Möglichkeit zur Eingabe, so liegt der Fehler auf Linux-Seite in der Konfiguration des SSH-Servers, der Benutzer oder der Zugangssysteme; im Rahmen dieses Artikels können wir darauf nicht eingehen.
Versuchen Sie nun herauszufinden, wo das shutdown-Programm abgelegt ist (meist in /sbin), und führen Sie dieses Programm auf folgende Weise aus:
fenrir:/# /sbin/shutdown -h now
Achtung: Das Linux-System sollte nun herunterfahren. Führen Sie diesen Test nicht auf Produktionssystemen oder nur zu unkritischen Zeiten aus.
Fährt das Linux-System herunter, gehen Sie zum nächsten Test über. Andernfalls beobachten Sie etwaige Fehlermeldungen und versuchen Sie zu ermitteln, ob der Benutzer shutdown wirklich die Berechtigung zum Herunterfahren des Systems besitzt.
Starten Sie jetzt unter Windows die Kommandozeile und geben Sie den bereits oben gezeigten Code ein, wobei Sie die IP-Adresse und das Paßwort an Ihre Gegebenheiten anpassen (bitte beachten Sie wieder das Zeichen zur Zeilenfortsetzung):
C:\>c:\programme\plink -ssh 192.168.20.249 -l shutdown -pw geheim \ /sbin/shutdown -h now
Wieder sollte das Linux-System herunterfahren. Geschieht dies nicht, so liegt vermutlich ein einfacher Tippfehler vor oder eine falsche IP-Adresse vor. Es ist fast unmöglich, daß die oben genannten Tests mit putty das gewünschte Ergebnis liefern, dieser Test jedoch versagt.
Können Sie mithilfe des oben gezeigten Codes Ihre Linux-Systeme zuverlässig von Windows aus herunterfahren, so ist die Konfiguration auf Linux-Seite abgeschlossen.
Die Installation von PBE ist unproblematisch. Im Prinzip wird lediglich ein Dienst installiert, der Agent genannt wird. Der Agent kommuniziert über eine der oben genannten Schnittstellen mit der USV, stellt mithilfe eines integrierten Webservers per HTTP(S) die Verbindung zur Außenwelt her, so daß die Abfrage von Informationen und die Konfiguration mithilfe eines Browsers möglich sind, und führt beim Eintreten bestimmter Ereignisse Aktionen aus, die diesen zugeordnet worden sind.
Als widerspenstig erweist sich hingegen die Konfiguration. Das Konzept ist umständlich, die Hilfetexte auf der Konfigurationsoberfläche nicht vorhanden oder auf dem Niveau der Hilfetexte eines typischen PC-BIOS ("Choose Yes to enable the option; Choose No to disable the option"). Die Dokumentation ist eine Unverschämtheit, nirgends lassen sich die grundlegenden und so wichtigen Informationen zum Zusammenspiel der zeitlichen Abläufe zwischen den normalen Ereignissen und dem Shutdown-Vorgang finden. Gleiches gilt für die Website des Herstellers.
Es ist geradezu ein Armutszeugnis für APC, daß überdies einige Hilfetexte auf den Konfigurationsseiten und Stellen in der Dokumentation gravierende Fehler aufweisen. Dokumentation für in hochsensiblen Bereichen einzusetzende Geräte eines Herstellers, der das professionelle Umfeld bedienen möchte, hat wahrlich anders auszusehen.
Dies ist ein großes Problem:
Der Administrator muß sich in mühevoller Kleinarbeit selbst herleiten, auf welche Weise der Agent wohl berechnet, ob die gewählte Konfiguration der Ereignisse und des Shutdown-Vorgangs zulässig ist, ob also die Kapazität der Batterien die konfigurierten zeitlichen Abfolgen und Zeitspannen überhaupt erlaubt. Natürlich muß die erarbeitete Vermutung dann in weiterer zeitintensiver, zermürbender Kleinarbeit gründlich getestet werden; schließlich geht es hier um die Konfiguration der Lebensversicherung für das wertvollste Gut eines Unternehmens, nämlich seine Daten.
Ferner kann die Beachtung falscher Aussagen im Handbuch und der Hilfe den Arglosen zu einem im entscheidenden Augenblick versagenden USV-System führen.
Wir werden deshalb im folgenden das Software-Konzept grob erklären und auf einen schlimmen Fehler in der Dokumentation hinweisen. Sobald Sie die hier vorgestellte Konfiguration verändern möchten, sind gründliche Tests mit möglichst vielen Fehlersituationen unerläßlich. Es ist wahrscheinlich, daß die Dokumentation noch weitere schwere Fehler enthält.
In der Terminologie von PBE ist mit dem Begriff Shutdown nicht nur das Herunterfahren des Servers gemeint, sondern der Shutdown umfaßt den gesamten Prozeß vom Herunterfahren des Betriebssystems bis zum Abschalten der USV.
Selbstverständlich kann konfiguriert werden, unter welchen Bedingungen der Shutdown ausgelöst wird und in welcher zeitlichen Abfolge die verschiedenen Stufen stattfinden. Nach seinem Start kann der Shutdown eventuell wieder angehalten werden, wenn die auslösenden Bedingungen wegfallen. Das Abschalten der USV am Ende des Shutdown läßt sich nach unserer Kenntnis nicht verhindern, es kann aber eingestellt werden, unter welchen Bedingungen die USV sich wieder einschaltet.
Es ist unseres Wissens nicht möglich, dem Agent den Shutdown komplett zu untersagen. Die Shutdown-Sequenz läßt sich in der Konfigurationsoberfläche zwar konfigurieren, aber nicht deaktivieren. Daß dies so auch sinnvoll ist, zeigt der nächste Abschnitt.
Wesentlich universeller können Ereignisse verwendet werden. Praktisch für jedes Ereignis, das während des Betriebs einer USV auftreten kann, kann festgelegt werden, welche Benachrichtigungen und Aktionen es nach sich ziehen soll. Da als Aktion auch die Ausführung eines Programmes möglich ist, steht ein mächtiges System zur individuellen Konfiguration zur Verfügung. Dessen Nutzung wird allerdings durch die indiskutable Dokumentation erschwert.
Kein Ereignis muß zwingend mit einer Aktion verbunden werden.
Betrachtet man das Gesamtsystem etwas abstrakter, so kann der Shutdown als eine Aktion betrachtet werden, die einem Ereignis "Shutdown" zugeordnet ist, das sich von den anderen Ereignissen in einigen Punkten unterscheidet: Es ist nicht in der Liste der Ereignisse enthalten, sondern wird über eigene Menüs konfiguriert, und es ist zwingend mindestens mit der Aktion "Shutdown" verbunden.
Aus dieser Sicht erscheint es natürlich, daß auch der Eintritt des Ereignisses "Shutdown" mit dem Versand von Benachrichtigungen oder dem Aufruf von Programmen verbunden werden kann. Daß dies für das Gelingen manchen Projekts entscheidend ist, wird im nächsten Abschnitt klar.
Unser Ziel bestand zunächst darin, dafür zu sorgen, daß bei Eintritt eines Stromausfalls die beiden Linux- und der Windows-Server nach wenigen Minuten heruntergefahren würden. Die maximal mögliche Laufzeit der USV sollte dabei nur zu einem geringen Teil genutzt und die USV nach dem Herunterfahren der Server nicht abgeschaltet werden.
Beides diente dem Zweck, andere wichtige Kleingeräte, die ebenfalls von der USV versorgt wurden, möglichst lange funktionsfähig zu halten, darunter eine kleine Telefonanlage, ein DSL-Router und ein Ethernet-Switch. Da ein regulärer Shutdown ohne anschließende Abschaltung der USV nicht möglich war, haben wir dies über die Zuordnung eines Scripts zu einem geeigneten Ereignis realisiert.
Dabei handelt es sich um ein Ereignis, welches eintritt, sobald die USV die angeschlossenen Verbraucher für eine bestimmte Zeit lang ununterbrochen aus ihren Batterien versorgt hat, im allgemeinen also zu einem bestimmten Zeitpunkt nach Eintritt eines Stromausfalls, sofern in der Zwischenzeit die reguläre Stromversorgung nicht wiedergekehrt ist.
Mit diesem Vorgehen alleine blieben jedoch bestimmte Sondersituationen unbehandelt, von denen eine exemplarisch genannt werden soll:
Würde die USV, etwa aufgrund rhythmischer Stromausfälle, wiederholt zwischen Batterieversorgung und regulärem Betrieb umschalten, so könnten sich ihre Batterien entleeren, ohne daß das Script ausgeführt würde, also ohne daß die von der USV versorgten Server heruntergefahren würden.
Das erwähnte Ereignis, von dem das Script aktiviert wird, tritt nämlich wie geschildert erst ein, wenn die USV für eine bestimmte Zeit ununterbrochen im Batteriebetrieb arbeitet; die Batterien werden bei aufeinanderfolgenden, kurzen Stromausfällen jedoch genauso entleert wie bei einem einzigen mit insgesamt gleicher Zeitdauer. Dies gilt zumindest, wenn zwischen den Stromausfällen nicht genügend Zeit zum Wiederaufladen der Batterien liegt.
Der folgende Mechanismus würde dieses und alle weiteren Probleme ähnlicher Natur zuverlässig lösen: Das Herunterfahren aller von der USV versorgten Server wäre einzuleiten, sobald die Restlaufzeit der Batterien ein gewisses Maß unterschritte. Genau dies ist nun aber das Kriterium, aufgrund dessen der Agent das im vorherigen Abschnitt erwähnte Ereignis "Shutdown" auslöst.
Damit ist ein sicherer USV-Betrieb möglich: Zunächst ist die für den Shutdown benötigte Zeit für jeden der von der USV versorgten Server unter Worst-Case-Bedingungen zu ermitteln und darauf ein gewisses Sicherheitspolster aufzuschlagen. Dann wird der Shutdown so konfiguriert, daß daß er so früh begonnen wird, daß die Restlaufzeit der Batterien auf jeden Fall zum vollständigen Herunterfahren aller angeschlossenen Server genügt.
Das Prinzip unserer Konfiguration läßt sich so beschreiben: Es gibt zwei Ereignisse, die beide zum Herunterfahren der Server führen. Das erste dieser Ereignisse tritt ein, sobald die USV die angeschlossenen Verbraucher für eine bestimmte Zeit ununterbrochen aus ihren Batterien versorgt hat; das zweite tritt ein, wenn die USV im Batteriebetrieb arbeitet und die verbleibende Stützzeit unter die zum Shutdown aller Server benötigte Zeit sinkt.
Gerne hätten wir hierfür ausschließlich das zweite Ereignis verwendet, weil es ohnehin nicht deaktiviert werden kann, aus den oben genannten Gründen unverzichtbar ist und für den genannten Zweck ausreichen würde. Leider ist es aber unweigerlich mit der kompletten Abschaltung der USV am Ende des Shutdown verbunden; zumindest wir haben keinen Weg gefunden, diese zu verhindern.
Aus diesem Grund haben wir zusätzlich das erste Ereignis verwendet, das dem Shutdown vorgeschaltet ist, deshalb in aller Regel einen Stromausfall abfängt und nicht zwangsweise die Abschaltung der USV nach sich zieht. Der Shutdown wird damit nur noch in einer der oben genannten, sehr unwahrscheinlichen Sondersituationen eintreten; der einzige Schaden besteht dann in der Abschaltung der USV am Ende. De facto ist dieser Fall bislang noch nie eingetreten.
Das oben geschilderte System versagt nur noch in einer einzigen Situation, nämlich wenn die USV samt der von ihr versorgten Server mit Batterien gestartet wird, deren Kapazität nicht mehr zur vollständigen Durchführung des Shutdown-Vorgangs ausreicht, und wenn unmittelbar nach dem Start ein Stromausfall auftritt. Dies kann passieren, wenn die USV von vornherein unterdimensioniert ist oder mit teilentleerten oder nach langer Nichtbenutzung geschwächten Batterien gestartet wird.
Eine Schwächung der Batterien während des regulären Betriebs stellt hingegen kein Problem dar. Sinkt die Restlaufzeit unter den benötigten Wert, so treten weitere Ereignisse ein, die zu Einträgen im Log des Agent oder zum Versand entsprechender Benachrichtigungen führen können, so daß der Administrator auf alternde Batterien und sich verkürzende Restlaufzeit zeitnah aufmerksam wird.
Um dies zu leisten, muß der Agent die Batterielaufzeit kennen. Diese kann bei Kenntnis der theoretischen Kapazität der Batterien und deren Entladekurven aus der zu bedienenden Gesamtlast errechnet werden, die der Agent jederzeit von der USV abfragen kann. Der so ermittelte Wert kann je nach Alter und Güte der Batterien allerdings von der Realität abweichen [Link]; dies gilt auch, wenn anstelle der vom Hersteller empfohlenen Batterien Billigmodelle von Drittherstellern verwendet werden.
Deshalb sollte einmal bis zweimal pro Jahr eine Laufzeitkalibrierung der USV vorgenommen werden, ebenso nach größeren Änderungen der Gesamtlast, die die USV zu bedienen hat. Bei diesem Vorgang versorgt die USV die angeschlossenen Geräte so lange wie möglich aus ihren Batterien, schaltet (hoffentlich) kurz vor der Entleerung der Batterien wieder auf die reguläre Spannungsversorgung um und merkt sich die gemessene maximale Stützzeit.
Die Belastung der Batterien ist dabei sehr hoch, weil diese fast entladen werden [Link]; der Vorgang sollte deshalb nicht gerade wöchentlich durchgeführt werden. Aus naheliegenden Gründen sollte auch nicht gerade ein Gewitter am Himmel stehen, wenn die Laufzeitkalibrierung gestartet wird.
Die Herstellung einer Worst-Case-Situation für die Berechnung der benötigten Zeit zum Shutdown kann sich als komplexes Unterfangen erweisen. Es genügt jedenfalls nicht, auf jedem der beteiligten Server möglichst alle benutzten Anwendungen zu starten und dann die zum Herunterfahren benötigte Zeit zu messen. Vielmehr muß bedacht werden, daß die zum Herunterfahren eines Servers benötigte Zeit sich unter bestimmten Umständen signifikant verlängern kann, gerade wenn etwa aufgrund eines Stromausfalls andere Komponenten der EDV-Infrastruktur ausgefallen sind.
So verlängert sich zum Beispiel die zum Herunterfahren benötigte Zeit unter manchen Betriebssystemen scheinbar ins Unendliche, wenn der betreffende Server keine Antworten auf DNS-Anfragen mehr erhält oder sich von noch angemeldeten Clients verabschieden möchte, zu denen die Netzwerkverbindung unterbrochen ist. Wer hier sicher gehen möchte, kommt um eine gründliche Analyse der vorhandenen Situation und um Änderung der Konfiguration an diversen Stellen nicht herum.
Ein weiteres Problem stellen die enormen Sprünge in der Leistungsaufnahme dar, die bei modernen Servern auftreten können. Der Agent kann die verbleibende Stützzeit der USV nur aus der jeweils aktuellen Gesamtlast abschätzen; dümpelt etwa ein Server mit mehreren Prozessoren oder Kernen zum Zeitpunkt der Abfrage im Regelbetrieb mit geringer Auslastung vor sich hin, so sollte beim Herunterfahren kein Programm gestartet werden, welches alle Prozessorkerne, Festplatten und Speichermodule voll auslastet, die Leistungsaufnahme des Servers verdoppelt und damit die Prognose des Agent über die verbleibende Stützzeit ins Leere laufen läßt.
Im Extremfall könnte dies dazu führen, daß die USV die Versorgung der angeschlossenen Verbraucher abschalten muß, bevor der betreffende Server komplett heruntergefahren ist. Dagegen hilft nur ein großzügiger Sicherheitsaufschlag bei der Angabe der für den Shutdown benötigten Zeit in der Konfigurationsoberfläche des Agent.
Die folgende Abbildung zeigt einen kleinen Ausschnitt aus der Liste der Ereignisse mit ihren zugeordneten Aktionen in der Konfigurationsoberfläche des Agent. Sie gelangen dorthin, indem Sie nach der Anmeldung in der Konfigurationsoberfläche im linken Menü "Events", dann "Actions" wählen. Aus dem gezeigten Ausschnitt ist ersichtlich, daß wir für jedes Ereignis alle zur Verfügung stehenden Benachrichtigungen aktiviert haben:
Ist "Logging" aktiviert, so wird das betreffende Ereignis in den Logs des Agent aufgezeichnet, die an anderer Stelle eingesehen werden können (leider aber nicht in der Ereignisanzeige von Windows).
Ist "Notification" aktiviert, so wird bei Eintritt des betreffenden Ereignisses eine Nachricht über den Nachrichtendienst von Windows an einen konfigurierbaren Kreis von Empfängern oder an alle PCs des betreffenden Subnetzes gesendet; der Nachrichtendienst muß hierfür auf dem sendenden Server und auf den empfangenden PCs laufen. Die neuesten Versionen von Windows enthalten diesen Dienst allerdings nicht mehr, so daß diese Möglichkeit nur mehr selten genutzt werden kann.
Ist "E-mail" aktiviert, so wird bei Eintritt des entsprechenden Ereignisses eine E-Mail an eine konfigurierbare Gruppe von Empfängern gesendet, wofür die Angabe eines SMTP-Servers und eines passenden Benutzerkontos erforderlich ist. Optionen zur Authentifizierung oder Verschlüsselung stehen hier nicht zur Verfügung, eventuell muß also ein interner SMTP-Server verwendet werden.
Die Empfängerkreise und SMTP-Optionen werden global eingestellt. Pro Ereignis existieren zusätzlich nur wenige weitere Einstellungen, darunter, wie oft "Notifications" wiederholt werden sollen. Dieses System ist gut zu handhaben, verständlich und in der Praxis sinnvoll.
Noch wichtiger und interessanter sind die letzten beiden Spalten. Ist "Shutdown" aktiviert, so startet der Agent bei Eintritt des betreffenden Ereignisses den Shutdown. Es ist möglich und oft sinnvoll, für keines der Ereignisse den Shutdown zu aktivieren. Dennoch wird dieser, unabhängig von der Konfiguration der Ereignisse, unter bestimmten Umständen durchgeführt. Genauere Erläuterungen hierzu finden sich im vorigen Abschnitt.
Ist "Command" aktiviert, so wird bei Eintritt des betreffenden Ereignisses ein Programm gestartet. Hierfür kann eine beliebige ausführbare Datei gewählt werden, also auch ein Script. Dieses muß bestimmte Anforderungen erfüllen, die weiter unten erläutert werden.
Das Ziel, die drei von der USV versorgten Server herunterzufahren, sobald die USV diese für eine bestimmte Zeitspanne ununterbrochen aus den Batterien versorgt hat, kann nun erreicht werden. Als geeignetes Ereignis steht "Time On Battery Threshold Exceeded" zur Verfügung; diesem wird ein Script zugeordnet, welches für das Herunterfahren der Server sorgt.
Das genannte Ereignis wurde konfiguriert wie folgt (es ist nur der hier relevante Ausschnitt der Optionen dargestellt):
Die beiden ersten Optionen sind selbsterklärend; als zu startendes Programm haben wir ein Script gewählt, auf dessen Inhalt wir im nächsten Abschnitt eingehen.
Mithilfe der dritten Option wird dem Agent mitgeteilt, wie lange die Ausführung dieses Scripts dauern wird. Dies ist nicht die reine Laufzeit des Scripts selbst, sondern die Zeitspanne vom Start des Scripts bis zur vollständigen Beendigung aller Aktionen, die von diesem direkt oder indirekt ausgelöst werden. Unter welchen Umständen sich die reine Laufzeit des Scripts von dieser Zeitspanne unterscheiden kann, wird in nächsten Abschnitt erläutert.
Ein Script besteht aus einzelnen Kommandos, die der Reihe nach abgearbeitet werden. Ein Kommando, welches die Laufzeit des Scripts nicht spürbar erhöht, wäre etwa das Schreiben eines Eintrags in eine Logdatei. Hingegen würde die Laufzeit Scripts um mehrere Minuten erhöht, wäre darin ein Kommando zum Kopieren einer 20 GB großen Datei enthalten.
Der Agent benötigt die Angabe der Laufzeit, um, auch im regulären Betrieb, laufend zu berechnen, ob die zur Verfügung stehende Restlaufzeit der Batterien noch den Anforderungen genügt. Die Mindestanforderung aus Sicht des Agent lautet in unserem Fall: Die Restlaufzeit der Batterien ab dem Startzeitpunkt des Scripts muß mindestens so hoch sein wie die angegebene Laufzeit des Scripts zuzüglich der für den Shutdown (hier ist der Shutdown im Sinne des Agent gemeint) benötigten Zeit.
Dies mag in unserem Fall widersinnig erscheinen, weil die Server nach einem Stromausfall in der Regel bereits vom Script heruntergefahren werden und insofern die Zeit zum Shutdown nicht benötigt wird. Genau dies kann dem Agent aber nicht bekannt sein; er besitzt keine Möglichkeit, das einem Ereignis zugeordnete ausführbare Programm auf seinen Zweck hin zu untersuchen.
Unser Script sollte mehrere Server herunterfahren, von denen auch im schlechtesten Fall keiner länger als 3 Minuten hierfür benötigte. Da das Herunterfahren auf jedem Server gleichzeitig gestartet werden konnte, haben wir die Ausführungszeit für das Script mit 5 Minuten angegeben. Im Übrigen wurden auf jedem der Server Maßnahmen getroffen und getestet, die ungebührliche Verzögerungen beim Herunterfahren (aus welchen Gründen auch immer) verhindern.
Der Vollständigkeit halber sei nun exemplarisch einer der Fehler in der nicht mehr zu unterbietenden Dokumentation belegt. Die folgende Abbildung zeigt einen Ausschnitt aus der Seite zur Konfiguration unseres Ereignisses "Time On Battery Threshold Exceeded", welches vermutlich eines der am häufigsten benutzten Ereignisse ist:
Hier wird allen Ernstes behauptet, dieses Ereignis trete ein, wenn die USV die angeschlossenen Geräte aus ihren Batterien versorge und die Restlaufzeit der Batterien unter die angegebene Zeitspanne sinke. In Wirklichkeit und wie aufgrund des Namens zu erwarten, tritt das Ereignis jedoch ein, sobald die USV die angeschlossenen Geräte für die angegebene Zeitspanne ununterbrochen aus ihren Batterien versorgt hat. In der Regel ist dies die Zeitspanne seit Eintritt eines Stromausfalls.
Wehe dem Administrator, der dieser Dokumentation glaubt: er würde in bestem Gewissen hier eine umso höhere Zeitspanne eintragen, je mehr Sicherheit er benötigt. In Wirklichkeit jedoch würde dadurch das Ereignis umso später ab Auftritt des Stromausfalls ausgelöst und damit das sorgfältig ausgearbeitete Konzept nutzlos.
Der Unterschied zwischen normalen Ereignissen und dem Ereignis "Shutdown" wurde weiter oben bereits diskutiert, ebenso die Gründe dafür, in unserem Fall das Ereignis "Time On Battery Threshold Exceeded" zusätzlich zum Ereignis "Shutdown" zu benutzen.
Deshalb gehen wir an dieser Stelle nur noch kurz auf die Konfiguration des Ereignisses "Shutdown" ein. Sie gelangen dorthin, indem Sie in der Konfigurationsoberfläche des Agent in der links befindlichen Menüleiste zuerst "Protected System", dann "Shutdown Settings" wählen, danach in der Zusammenfassung rechts unten den Link "Configure".
Die folgenden Abbildungen zeigen den relevanten Teil der Einstellungen:
Der Shutdown wird gestartet, wenn die USV im Batteriebetrieb arbeitet und nur noch 20 Minuten Laufzeit verbleiben ("Runtime Remaining Threshold"). Die Option ("Low Battery Signal"), übrigens nicht in der Hilfe erwähnt, scheint festzulegen, wann das Ereignis "Low Battery" ausgelöst wird; dieses ist in der Liste der anderen Ereignisse enthalten und kann dort weiter konfiguriert werden.
In unserer Konfiguration sollte "Low Battery Signal" keine Rolle spielen. Der Auslösezeitpunkt wurde deshalb so eingestellt, daß es nie eintritt, nämlich auf 10 Minuten verbleibender Batterielaufzeit; dies entspricht 10 Minuten nach Beginn des Shutdown, der bis dahin längst beendet sein sollte.
Aus den oben genannten Gründen benötigt der Agent die Angabe, wie lange der Shutdown dauert ("OS Shutdown Delay"). Hier ist die Zeitspanne einzutragen, die das Betriebssystem zum Herunterfahren benötigt, ohne die Zeitspanne, die für die Abarbeitung der ausführbaren Programme benötigt wird, die dem Shutdown zugeordnet sind.
Die Option "OS Shutdown Type" legt fest, wie das Betriebssystem heruntergefahren werden soll. Zur Wahl stehen der Ruhezustand und das Herunterfahren ohne oder mit Ausschalten des Servers.
Mithilfe der nächsten Optionen wird festgelegt, wie weit die Batterien der USV nach einem Shutdown mindestens wieder aufgeladen sein müssen, bevor die USV ihre Ausgänge wieder mit Leistung beaufschlagt ("UPS Turn On Battery Capacity"), wie lange nach dem Erreichen dieser Ladung damit gewartet werden soll ("UPS Turn On Delay"), und ob das Betriebssystem des vom Shutdown heruntergefahrenen Servers danach wieder automatisch starten soll ("Enable OS Reboot").
Die erste dieser drei Optionen ist wichtig, stellt sie doch die einzige Möglichkeit dar, ein Aufstarten mit Batterien zu vermeiden, die von vornherein nicht genügend Stützzeit für einen Shutdown liefern würden; dieses Problem wurde in den vorhergehenden Abschnitten bereits diskutiert. Warum das Drop-Down-Feld für diese Option nur Werte bis 90% enthält (und somit keine Möglichkeit besteht, die USV erst bei voll geladenen Batterien wieder einschalten zu lassen), bleibt das Geheimnis von APC.
Auch der Sinn der Option, das Anschalten der USV nach dem Laden der Batterien auf den gewünschten Grad noch verzögern zu können, erschloß sich uns nicht.
Die Option, das Betriebssystem nach Wiederanschalten der USV automatisch hochzufahren, wird nur dann die gewünschte Wirkung zeigen, wenn BIOS und Windows sauber zusammenspielen. Der Agent muß hierfür von Windows aus dem BIOS mitteilen, ob der betreffende Rechner nach dem nächsten Abschalten bei Wiederkehr der Stromversorgung automatisch neu starten soll oder eben nicht. Dies wird in den wenigsten Fällen funktionieren.
Auch der Shutdown mußte noch mit einem Script verknüpft werden, das das Herunterfahren der Linux-Server bewirkte; der Shutdown an sich bewirkt nur das Herunterfahren des Windows-Servers. Die letzten drei gezeigten Optionen legen fest, ob ein ("Enable Command File Execution") und welches ("Choose Command File Name") Programm beim Shutdown ausgeführt werden soll und wie lange die Ausführung dieses Programms dauert ("Command File Execution Duration").
Der Shutdown läuft insgesamt so ab: Sinkt die Restlaufzeit der Batterien unter den konfigurierten Wert, wird das angegebene Script gestartet. Nachdem die angegebene für die Abarbeitung des Scripts benötigte Zeit vergangen ist, gemessen ab Start des Scripts, wird das Herunterfahren des Betriebssystems eingeleitet. Nachdem die hierfür angegebene benötigte Zeit vergangen ist, gemessen ab Beginn der Herunterfahrens, wird die USV abgeschaltet.
Die Scripts, die dem Shutdown und dem Ereignis "Time On Battery Threshold Exceeded" zugeordnet wurden, unterscheiden sich leicht. Ersteres darf nur das Herunterfahren der beiden Linux-Server bewirken, weil beim Shutdown der Windows-Server ohnehin bereits durch den Agent heruntergefahren wird; Letzteres hingegen muß das Herunterfahren aller drei Server bewirken, weil das betreffende Ereignis nicht mit dem Shutdown verknüpft ist.
Die Scripts, die vom Agent beim Eintritt von Ereignissen aufgerufen werden, müssen in einem bestimmten Verzeichnis innerhalb des Dateisystems liegen. Wie in einigen der obigen Abbildungen sichtbar, erfolgt die Auswahl eines Scripts per Dropdown-Feld, das ausschließlich den Inhalt dieses Verzeichnisses anzeigt. Es ist nicht möglich, zu einem anderen Verzeichnis zu navigieren. In unserem Fall lautete das Verzeichnis "C:\Programme\APC\PowerChute Business Edition\agent\cmdfiles".
Der Prozeß des Herunterfahrens darf keinesfalls durch die aufgerufenen Scripts verzögert oder gar blockiert werden. Andernfalls wären die Laufzeitberechnungen des Agent nicht zutreffend, oder die betreffende Maschine würde überhaupt nicht herunterfahren. In beiden Fällen könnte die Stromzufuhr entzogen werden, während die Server noch arbeiten, und damit genau der Fall eintreten, der durch die USV verhindert werden soll.
Deshalb müssen die Scripts einen gewissen Aufbau besitzen. Entscheidend ist erstens, daß die Scripts keine Programmierfehler enthalten, die zu einer Blockierung oder Verzögerung führen. Zweitens darf ein Script nie auf Rückmeldungen oder Beendigung eines Befehls warten, der von diesem Script aufgerufen wird. Vielmehr ist jeder Befehl so aufzurufen, daß er in einem eigenen Prozeß oder Fenster im Hintergrund gestartet wird und die weitere Abarbeitung des Scripts nicht beeinflußt.
Wir haben die Scripts zweistufig aufgebaut: Das vom Agent aufzurufende Script liegt im oben genannten Verzeichnis und hat als Wrapper-Script die einzige Aufgabe, ein zweites Script, das die eigentliche Arbeit erledigt, im Hintergrund, also in einem eigenen Prozeß, aufzurufen. Der Vorteil liegt darin, daß das kritische Wrapper-Script, in dem sich jeder Fehler fatal auswirken könnte, extrem einfach gehalten werden kann; in unserem Fall genügt eine einzige Programmzeile.
Eine einfache Möglichkeit, Scripts unter Windows Server 2003 im Hintergrund zu starten, besteht in der Verwendung des Befehls "start". Im Rahmen dieses Artikels können wir auf diesen Befehl nicht tiefer eingehen; zu einem ersten Überblick verhilft "start /?". Unsere Scripts, die für das Herunterfahren bei einem "normalen" Stromausfall verantwortlich sind, besitzen nun folgenden Inhalt (bitte beachten Sie wieder die Bedeutung des Zeilenfortsetzungszeichens \):
Wrapper (C:\Programme\APC\PowerChute Business Edition\agent\cmdfiles\wrapper-all.cmd):
start "" "c:\batch\shutdown-all.cmd"
Haupt-Script (C:\Batch\shutdown-all.cmd):
SET USER=shutdown SET PASSWORD=secret SET PLINK=c:\programme\putty\plink.exe SET SHUTDOWN=c:\windows\system32\shutdown.exe @echo off start "FenrirLennyFirewall-Shutdown" "%PLINK%" -ssh 192.168.20.249 \ -l %USER% -pw %PASSWORD% /sbin/shutdown -h now start "FenrirLennyMain-Shutdown" "%PLINK%" -ssh 192.168.20.28 \ -l %USER% -pw %PASSWORD% /sbin/shutdown -h now start "Garak-Shutdown" "%SHUTDOWN%" /s /t 30
Da das Haupt-Script vom Wrapper-Script bereits im Hintergrund aufgerufen wird (aus der Sicht des Agent), wird sich der Leser vielleicht fragen, warum das Haupt-Script selbst ebenfalls sämtliche kritischen Befehle im Hintergrund aufruft. Die Antwort darauf zeigt, wie wichtig eine sorgfältige Worst-Case-Analyse der Situation ist und welch schwerwiegende Folgen durch einen scheinbar harmlosen Fehler verursacht werden können:
Das Haupt-Script soll zuerst die beiden Linux-Server und dann den Windows-Server herunterfahren. Falls nun ein Stromausfall auftritt und beispielsweise der erste Linux-Server keine Netzwerkverbindung annimmt, so beendet sich plink erst nach Ablauf mindestens des TCP/IP-Timeouts, der durchaus im Halbminuten- oder Minutenbereich liegen kann; verschiedene Betriebssysteme benutzen hier verschiedene Standard-Einstellungen.
Würde plink im Vordergrund aufgerufen, so wäre die weitere Abarbeitung des Scripts für längere Zeit blockiert, und die folgenden, essentiell wichtigen Befehle würden zu spät und im Extremfall gar nicht mehr ausgeführt. Daß dieses Szenario nicht nur Paranoia entspringt, sondern real eintreten kann, wird klar, wenn man die Banalität der Gründe betrachtet, aus denen Server keine Netzwerkverbindungen annehmen: Der Server könnte abgeschaltet oder abgestürzt sein, eine Netzwerk-Komponente könnte defekt oder funktionslos sein (insbesondere bei Stromausfall).
Grundsätzlich ist anzuraten, das Worst-Case-Szenario mit Sorgfalt zu erstellen, notorische Querdenker daran zu beteiligen, in den beteiligten Scripts alle Befehle im Hintergrund aufzurufen und das Verhalten bei Stromausfall auch in unwahrscheinlichen Situationen zu testen.
Trotz korrekter Konfiguration des Agent und trotz korrekter Scripts, die bei manuellem Aufruf wie erwartet arbeiteten, fuhren die Server bei Stromausfall zunächst nicht korrekt herunter; es schien, als würden die Scripts vom Agent schlicht nicht aufgerufen. Kurzzeitig vermuteten wir einen Fehler im Agent; erst bei einer Debugging-Sitzung wurde die wahre Ursache erkannt:
Der Agent ist unter Windows als Dienst implementiert, was die einzig sinnvolle Wahl darstellt. Jeder Dienst arbeitet im Kontext eines bestimmten Benutzerkontos und erbt dessen Berechtigungen, zum Beispiel zur Manipulation von Dateien. In der Diensteverwaltung von Windows kann eingestellt werden, unter welchem Benutzerkonto welcher Dienst läuft; im allgemeinen ist jedoch davon abzuraten, die Standardeinstellungen zu verändern.
Ruft ein Dienst weitere Programme auf, so laufen auch diese im Kontext des Benutzerkontos dieses Dienstes. Gleiches gilt, wenn ein so aufgerufenes Programm weitere Programme aufruft; in der Regel wird der Benutzer- und Sicherheitskontext stets vom aufrufenden Prozeß auf den aufgerufenen Prozeß vererbt. Es gibt Gründe und Mechanismen, dies zu umgehen, diesbezügliche Erläuterungen würden den Rahmen dieses Artikels aber sprengen.
In unserem Fall jedenfalls wurden der Agent, sämtliche von ihm aufgerufenen Scripts und die darin enthaltenen Befehle im Kontext des Kontos "Lokales System" ausgeführt. Dies trifft insbesondere auch für die Aufrufe von plink zu.
Wie oben erläutert, fordert plink bei erstmaligem Kontakt mit einem Server eine Bestätigung des Benutzers betreffend die Echtheit des öffentlichen Schlüssels des Servers. Ohne diese Bestätigung baut plink die Verbindung nicht weiter auf, und beim nächsten Wunsch nach einer Verbindung zum betreffenden Server beginnt das Spiel von vorn. Diese Bestätigung muß pro Server (genauer: pro öffentlichem Schlüssel) und pro Benutzer einmalig erfolgen.
Natürlich hatten wir unsere Scripts zum Testen zunächst im Kontext unseres Benutzerkontos ablaufen lassen und nicht im Kontext des Kontos, unter dessen Kontext der Agent arbeitet. Beim erstmaligen manuellen Aufruf der Scripts forderte uns plink wie erwartet zur Bestätigung der Korrektheit der Schlüssel auf. Gleiches wäre beim ersten Aufruf der Scripts durch den Agent zu erwarten gewesen, da die Verifizierung der Schlüssel pro Benutzer erfolgen muß.
Eine entsprechende Aufforderung bekamen wir jedoch nicht zu Gesicht, weil Sicherheitsmechanismen von Windows dies verhindern: In der Regel dürfen Dienste nicht mit dem Desktop interagieren. In unserem Fall wollte plink bei den Aufrufen seitens des Agent sehr wohl die Bestätigung über die Echtheit der Schlüssel einholen; die entsprechende Dialogbox wurde aber nicht angezeigt, weil plink im Kontext des Agent-Dienstes ablief und Windows dementsprechend die Interaktion mit dem Desktop, nämlich die Anzeige der Dialogbox, verhinderte.
Für dieses Problem existieren mehrere Lösungen. Die einfachste, sauberste und von uns empfohlene besteht darin, dem Agent-Dienst vorübergehend die Interaktion mit dem Desktop zu gestatten; in der Dienste-Verwaltung von Windows ist hierfür in den Eigenschaften eines jeden Dienstes ein Schalter vorgesehen. Mit etwas mehr Aufwand verbunden, aber systemtechnisch genauso sauber wäre es, die Scripts einmalig manuell im Kontext des Agent-Dienstes aufzurufen. Eine dritte Lösung wäre es, die Schlüssel manuell in der Registry einzutragen und plink damit vorzugaukeln, daß sie bereits bestätigt wären; hiervon ist allerdings wegen der Gefahr von Fehlern abzuraten.
Mit gutem Grund gibt es übrigens keine Möglichkeit, die vom Autor angebotene Version von plink zum Verzicht auf die Bestätigung öffentlicher SSH-Schlüssel zu bewegen. plink ist jedoch Open-Source-Software; der betreffende Programmteil könnte also entfernt werden. Wir raten aus Gründen der Sicherheit davon ab – das Erzwingen dieser Bestätigungen hat seinen Sinn.
Im Falle von Sicherheits-Upgrades auf den Linux-Systemen oder sonstigen Änderungen, in deren Rahmen der öffentliche SSH-Schlüssel der betreffenden Server gewechselt wird, muß diese Prozedur wiederholt werden. Die Administratoren der Linux-Systeme sollten Änderungen der öffentlichen SSH-Schlüssel den Administratoren des Windows-Servers zeitnah mitteilen. Letztere sollten unabhängig davon regelmäßig prüfen, ob die öffentlichen SSH-Schlüssel der durch die USV gesicherten Linux-Server gleich geblieben und somit einem vom Agent aufgerufenen plink noch bekannt sind.
Dieser Artikel zeigt, wie mehrere Server, die gemeinsam von einer USV aus der Reihe "Smart-UPS" von APC versorgt werden, bei Stromausfall kontrolliert heruntergefahren werden können, ohne daß in teure Hardware- oder Software-Optionen investiert werden muß. Die dargestellte Lösung besitzt kleinere Nachteile, mit denen die meisten KMUs allerdings gut leben können:
Der kontrollierende Windows-Server muß immer aktiv sein, solange dies auch mindestens einer der andere von der USV geschützten Server ist. Läuft der Windows-Server bei Auftreten eines Stromausfalls nicht, so erfahren die anderen Server nichts von dem Problem. Ihre Laufzeit wird dann zwar verlängert, solange die USV nicht abschaltet, aber sobald dies geschieht, wird ihnen plötzlich die Stromzufuhr entzogen, womit genau der Fall eintritt, der vermieden werden muß.
Die Kommunikation zwischen den Administratoren der betreffenden Systeme muß verläßlich stattfinden. Auf dem Windows-Server muß plink stets die aktuellen öffentlichen SSH-Schlüssel der Linux-Server für den Benutzer als bestätigt hinterlegt haben, in dessen Kontext der Agent-Dienst läuft.
Für unser Projekt waren diese Nachteile irrelevant, da mit anderen Mitteln sichergestellt und überwacht wurde, daß der steuernde Windows-Server im Dauerbetrieb arbeitet, und weil dieselbe Person für die Administration der Linux- und des Windows-Servers zuständig war.
Bei anderen Kunden hingegen war dies nicht akzeptabel, hier führte kein Weg am Kauf der genannten Hardware- und Software-Optionen vorbei. Auf jedem Server arbeitete dann eine vollwertige Software des betreffenden USV-Herstellers, und jeder Server kommunizierte unabhängig von den anderen mit dem in der USV nachgerüsteten Netzwerk-Modul.
Dieser Artikel wurde im Mai 2010 erstmals veröffentlicht und seitdem nicht aktualisiert; der Inhalt ist eventuell veraltet. Wir planen keine Überarbeitung des Artikels, werden aber Fehler bei Bekanntwerden korrigieren.
Mitteilungen über Fehler nehmen wir gerne per E-Mail entgegen.