ADMIN

2023

02

2023-01-31T12:00:00

Endpoint Security

PRAXIS

040

Server

USV

Kontrollierte Shutdowns mit NUT

Kraft aus der Nuss

von Andreas Stolzenberger

Veröffentlicht in Ausgabe 02/2023 - PRAXIS

Ein Stromausfall im Serverraum hinterlässt oft eine Spur der Verwüstung im aktiven Datenbestand. Unterbrechungsfreie Stromversorgungen können das verhindern, jedoch nur für eine begrenzte Zeit. Das genügt aber schon, damit die Network UPS Tools den unkontrollierten Absturz von Servern zu einem kontrollierten Shutdown abwenden. Wir beleuchten im Workshop die Bestandteile des NUT-Systems und erklären, wie Sie diese in der Praxis einsetzen.

Unterbrechungsfreie Stromversorgungen (USV) schützen vor Stromausfällen und – je nach Typ (siehe Kasten "USV-Typen") – auch vor Stromschwankungen und Spannungsspitzen aus dem Netz. Wenn die Energie einmal ausbleibt, ist der Schutz durch die USV jedoch begrenzt. Kritische Infrastrukturen starten deshalb parallel zur USV gleich einen Dieselgenerator oder eine Brennstoffzelle – über diesen teuren Luxus verfügen die meisten IT-Installationen aber nicht. Je nach Leistung und Akkukapazität überbrückt eine USV also nur eine Zeitspanne von fünf bis 15 Minuten. Dies genügt allerdings, um die angebundenen Server kontrolliert herunterzufahren und somit einen Datenverlust zu vermeiden.
Damit das wiederum funktioniert, muss die IT-Installation mit der USV kommunizieren können. Ein gesicherter Server sollte dabei von der USV nicht nur über den Status, Ladezustand und die Restlaufzeit informiert sein. Ebenso muss die USV Kommandos des Servers entgegennehmen können. Im ungünstigsten Fall leiten die geschützten Rechner einen Shutdown ein und der Strom kehrt zurück, bevor dieser abgeschlossen ist. Nimmt dann die USV einfach wieder den Regelbetrieb auf, bleiben die IT-Dienste abgeschaltet. Die USV muss also vom Verwaltungsserver die Nachricht: "Ich fahre jetzt herunter" erhalten und daraufhin nach einer vereinbarten Zeitspanne den USV-Ausgang tatsächlich ab- und wieder einschalten, um damit den kontrollierten Neustart einzuleiten.
In der Regel schützt eine USV nicht nur einen einzelnen Server. Die Nachrichten der USV müssen daher über das Netzwerk an alle angebundenen Systeme gelangen. Die verschiedenen Hersteller liefern mit ihren Geräten daher eigene Software mit, die aber wiederum nur die USVs der eignen Produkte unterstützen.
Unterbrechungsfreie Stromversorgungen (USV) schützen vor Stromausfällen und – je nach Typ (siehe Kasten "USV-Typen") – auch vor Stromschwankungen und Spannungsspitzen aus dem Netz. Wenn die Energie einmal ausbleibt, ist der Schutz durch die USV jedoch begrenzt. Kritische Infrastrukturen starten deshalb parallel zur USV gleich einen Dieselgenerator oder eine Brennstoffzelle – über diesen teuren Luxus verfügen die meisten IT-Installationen aber nicht. Je nach Leistung und Akkukapazität überbrückt eine USV also nur eine Zeitspanne von fünf bis 15 Minuten. Dies genügt allerdings, um die angebundenen Server kontrolliert herunterzufahren und somit einen Datenverlust zu vermeiden.
Damit das wiederum funktioniert, muss die IT-Installation mit der USV kommunizieren können. Ein gesicherter Server sollte dabei von der USV nicht nur über den Status, Ladezustand und die Restlaufzeit informiert sein. Ebenso muss die USV Kommandos des Servers entgegennehmen können. Im ungünstigsten Fall leiten die geschützten Rechner einen Shutdown ein und der Strom kehrt zurück, bevor dieser abgeschlossen ist. Nimmt dann die USV einfach wieder den Regelbetrieb auf, bleiben die IT-Dienste abgeschaltet. Die USV muss also vom Verwaltungsserver die Nachricht: "Ich fahre jetzt herunter" erhalten und daraufhin nach einer vereinbarten Zeitspanne den USV-Ausgang tatsächlich ab- und wieder einschalten, um damit den kontrollierten Neustart einzuleiten.
In der Regel schützt eine USV nicht nur einen einzelnen Server. Die Nachrichten der USV müssen daher über das Netzwerk an alle angebundenen Systeme gelangen. Die verschiedenen Hersteller liefern mit ihren Geräten daher eigene Software mit, die aber wiederum nur die USVs der eignen Produkte unterstützen.
In der Regel bieten USV-Fertiger also verschiedene, zueinander inkompatible Werkzeuge an, die dann jeweils nur mit einem bestimmten USV-Typ zusammenarbeiten. Das liegt größtenteils daran, dass viele Hersteller besonders im Einsteigersegment fertige USV-Designs anderer Produzenten übernehmen und dann einfach ihr Logo auf das Gehäuse kleben.
Bestandteile und Workshopaufbau
Abhilfe schafft hier ein Open-Source-Projekt namens "NUT". Die nussige Abkürzung steht für "Network UPS Tools". Das Projekt basiert auf drei Komponenten: Der UPS-Driver (upsdrvctl) kommuniziert mit der angebundenen USV. Dazu nutzt er je nach Gerät verschiedene Kommunikationskanäle wie eine klassische serielle Schnittstelle, USB oder SNMP. Der Driver selbst greift auf ein Plug-in für den jeweiligen UPS-Typ und dessen Kommunikationskanal zu. Eine aktuelle Liste der unterstützten UPS-Geräte finden Sie unter [1].
Auf den UPS-Driver greift der UPS-Server (upsd) zu. Dieser kommuniziert via Driver mit der USV und stellt die Informationen der USV über das NUT-Protokoll im LAN zur Verfügung. Damit können NUT-Clients völlig unabhängig vom verwendeten Gerät via NUT-Protokoll mit dem Server kommunizieren. So lassen sich problemlos mehrere USVs verschiedener Hersteller verwenden und überwachen. Der Server verwaltet zudem Nutzerkonten mit verschiedenen Zugriffsrechten.
Der UPS-Client oder Monitor (upsmon) schließlich meldet sich lokal oder via LAN am UPS-Server an und überwacht dessen Statusmeldungen. Der Client löst bei Bedarf den System Shutdown aus und meldet dies zurück an den UPS-Server, der dann die USV zum Abschalten veranlasst. In einem üblichen NUT-Setup steht ein Server mit der USV in Verbindung und betreibt folglich den Driver, Server und den Monitor. Auf allen anderen Systemen arbeitet nur der Monitor.
Als quelloffene Software lässt sich NUT auf allen gängigen Betriebssystemen einsetzen. Dazu zählen neben Linux, macOS und Windows auch BSD, Solaris oder vSphere. Für diesen Workshop setzen wir ein simples Branch- oder Home-Office-Setup ein. Hier sichert eine GreenCell-Standby-UPS (360W) einen HP-Microserver (Fileserver) und einen Intel-NUC als Applikationsserver plus den Netgear-Switch, an dem beide Systeme angeschlossen sind. Diese Komponenten verbrauchen zwischen 80 und 100 Watt. Der HP-Microserver steht per USB mit der UPS in Verbindung und betreibt den NUT-Driver, -Server und Monitor unter RHEL 8. Der Intel-NUC, ebenfalls unter RHEL 8, ist via NUT-Monitor zugeschaltet.
Treiber einrichten
Im ersten Schritt richten wir das NUT-Paket auf dem Server ein, der mit der USV in Verbindung steht. Abhängig von der verwendeten Distribution (RHEL, Fedora, Debian) nutzen Sie die Paketmanager apt oder dnf. Unser RHEL-Aufbau braucht zuerst das EPEL-Repository und kann dann die Tools via dnf install nut nut-client installieren. Mit den nötigen Binaries auf dem System geht es an die UPS-Treiber-Konfiguration. Dafür müssen Sie ein paar Vorbereitungen treffen, denn der NUT-Driver läuft auf dem System nicht mit Root-Rechten. Daher darf er nicht auf USB-Geräte oder serielle Schnittstellen zugreifen.
Als Erstes müssen Sie also herausfinden, als welches Device sich ihre USV am System meldet. Auf einer USB-Verbindung identifiziert sich jedes Gerät über eine zweigeteilte ID, die aus einem Hersteller- und Produktcode bestehen sollte. Das Linux-Tool "lsusb" listet die angeschlossenen Geräte und IDs auf. Unsere simple USV macht sich dabei leider nicht die Mühe, eine sinnvolle USB-ID zu verwenden. Das lsusb-Kommando listet sie als:
Bus 001 Device 005: ID 0001:0000 Fry's Electronics
Wenn Sie das Gerät in der Liste nicht identifizieren können, führen Sie auf der Root-Konsole des Servers das Kommando dmesg -ew aus und stecken Sie die USB-Verbindung der USV erst danach an. Das Kernel-Log sollte dann in etwa so aussehen wie im Listing-Kasten 1.
Listing 1: USV-Gerät identifizieren
[ +0,029192] usb 1-1.5: new low-speed USB device number 5 using ehci-pci [ +0,084772] usb 1-1.5: New USB device found, idVendor=0001, idProduct=0000, bcdDevice= 1.00 [ +0,000007] usb 1-1.5: New USB device strings: Mfr=1, Product=2, SerialNumber=0 [ +0,000002] usb 1-1.5: Product: MEC0003 [ +0,000002] usb 1-1.5: Manufacturer: MEC
Passend zum jeweiligen Gerät benötigen Sie dann eine "UDEV"-Regel. Diese setzt die Zugriffsberechtigung und kann den NUT-Treiber neu starten, falls Sie das Gerät im laufenden Betrieb anschließen. Für unseren Workshop schaut die passende Regel so aus wie im Listing-Kasten 2.
Listing 2: Beispiel für UDEV-Regel
/etc/udev/rules.d/99-nut-ups.rules SUBSYSTEM!="usb", GOTO="nut-usbups_rules_end" ACTION=="add|change", SUBSYSTEM=="usb|usb_device", SUBSYSTEMS=="usb|usb_device", ATTR{idVendor}=="0001", ATTR{idProduct}=="0000", MODE="664", GROUP="nut", RUN+="/sbin/upsdrvctl stop; /sbin/upsdrvctl start" LABEL="nut-usbups_rules_end"
Schließen Sie eine USV mit einem klassischen seriellen Kabel an Ihren Server, könnten Sie ebenfalls eine passende UDEV-Regel erstellen, beispielsweise 99-nut-ttyS0.rule:
KERNEL=="ttyS0", GROUP="nut"
In der Regel geht es hier jedoch simpler. Moderne Linux-Installationen gewähren der Benutzergruppe "dialout" Zugriff auf alle seriellen Ports. Daher genügt es, wenn der Benutzer "nut" zur Gruppe "dialout" gehört. Der passende Eintrag in "/etc/ group" lautet bei RHEL beispielsweise:
dialout:x:18:nut
Das NUT-Paket beinhaltet ein Tool namens "nut-scanner", das die angebundene USV automatisch erkennen und konfigurieren kann. Allerdings funktioniert dieser Scanner nicht mit allen Geräten. Zudem müssen Sie zuerst den Zugriff auf das Device via UDEV konfigurieren.
Nutzen Sie die erwähnte Hardwareliste auf der NUT-Driver-Webseite, um den passenden Treiber zu ermitteln. Im Zweifelsfall hilft nur, verschiedene Treiber und Einstellungen durchzuprobieren. In unserem Aufbau funktioniert beispielsweise der Treiber "blazer_usb" mit der im Listing-Kasten 3 dargestellten Treiberkonfiguration in der Datei "/etc/upd/ups.conf".
Listing 3: "/etc/upd/ups.conf"
xretry = 5 pollinterval = 5 [greencell]       driver = blazer_usb       port = auto       desc = "GreenCell"       vendorid = "0001"       productid = "0000"       default.battery.voltage.low = 10       default.battery.voltage.high = 14
Mit einer passenden Konfiguration starten Sie den Treiber mittels systemctl restart nut-driver und prüfen mit systemctl status nut-driver, ob er korrekt arbeitet. In der Ausgabe sollten dann Zeilen wie im Kasten 4 erscheinen. Jetzt läuft der Treiber mit der logischen USV "greencell". Welche Informationen er von der USV erhält, also zum Beispiel den Akkustand, rufen Sie mit upsc greencell@localhost über die Kommandozeile ab.
Listing 4: Statusausgabe des NUT-Treibers
anut-driver.service - Network UPS Tools - power device driver controller Active: active (running) since upsdrvctl[31115]: Supported UPS detected with megatec protocol blazer_usb[31117]: Startup successful
Bild 2: Das Grafana-Dashboard zeigt, dass die UPS im Akkubetrieb bei der Ausgangsspannung schwankt. Der sofortige Abfall des Ladestands beim Ausfall lässt auf einen schwächelnden Akku schließen.
NUT-Server im LAN konfigurieren
Für den LAN-Betrieb benötigt die Konfiguration des NUT-Servers drei kleine Konfigurationsdateien. "/etc/ups/upsd. conf" legt die Netzwerkeinstellungen fest und sollte so aussehen:
LISTEN 0.0.0.0 3493
Falls Ihr Server eine lokale Firewall verwendet, muss der Port natürlich offen sein. Den Zugriff zur UPS selbst schützt eine simple Authentisierung, die Sie in der Datei "/etc/ups/upsd.users" festlegen:
[admin]
      password = <Passwort>
           actions= SET
           actions = FSD
           instcmds = ALL
           upsmon master
[user1]
      password = <Passwort>
     upsmon slave
Der Admin-Nutzer meldet sich dabei später über den UPS-Monitor des lokalen Systems an. Die Berechtigung "FSD" erlaubt es ihm, über den UPS-Treiber das Kommando "Forced Shut Down" an die USV zu übermitteln. Der Knoten "upsmon master" steuert die USV über den UPS-Server-Dienst.
Alle via LAN angebundenen Systeme arbeiten als "upsmon slave". Damit bekommen Sie die UPS-Nachrichten, können aber die USV selbst nur dann steuern, wenn der Master nicht reagiert.
Wie bei anderen Programmen, die in der Vergangenheit "master" und "slave" als Begriffe verwendet haben, wird NUT künftig aus ethischen Gründen andere Bezeichnungen verwenden. Neuere Versionen arbeiten daher mit "upsmon primary" und "upsmon secondary". Die Version 2.7.4 in unserem Setup kennt jedoch noch kein "upsmon primary" und arbeitet noch mit den alten Bezeichnungen. In der Datei "/etc/ups/nut.conf" schließlich steht lediglich der Betriebsmodus:
MODE=netserver
Laufen UPS-Treiber und -Server, geht es an die abschließende Konfiguration des primären UPS-Monitors. Die sieht in einem simplen Setup in etwa so aus – die folgenden drei Listings müssen natürlich zusammenhängend in einer Datei stehen:
/etc/usp/upsmon.conf
MONITOR greencell@localhost 1 admin <Passwort> master
MINSUPPLIES 1
SHUTDOWNCMD "/sbin/shutdown -h +0"
Die Zeile "MONITOR" enthält den Login zur im upsd deklarierten USV. Die Zahl "1" gibt an, dass der Server mit einem Netzteil an dieser USV hängt. Server mit zwei Power-Supplies könnten hier entweder angeben, dass sie mit beiden an einer USV hängen oder Sie nutzen zwei MONITOR-Einträge für zwei separate USVs. Es folgen Benutzername, Passwort und Monitortyp. Mit MINSUPPLIES legen Sie fest, wie viele Netzteile aktiv bleiben müssen. Hängt der Server an zwei USVs, von denen eine in den kritischen Batteriestatus wechselt, die andere aber noch nicht, leitet der UPS-Monitor noch keinen Shutdown ein. SHUTDOWN­CMD bestimmt das Kommando, über das Sie ihr System herunterfahren.
POLLFREQ 5
POLLFREQALERT 5
HOSTSYNC 15
DEADTIME 15
Die POLL-Zeiten geben an, wie oft der UPS-Monitor den Status der USV abfragt. Die ALERT-Variante legt dabei das Intervall fest, während die USV auf Akkustrom arbeitet. HOSTSYNC regelt, wie lange Primary und Secondary Nodes aufeinander warten. Reagiert der Primary nicht mehr auf den Secondary Node, übernimmt Letzterer die Kontrolle. Reagiert der Secondary nicht mehr auf den Primary, geht Letzterer davon aus, dass der Secondary bereits herunterfährt. Sollte die USV länger als die DEADTIME nicht auf Anfragen reagieren, während sie im Status "Akkubetrieb" war, fährt der Monitor das System sofort herunter:
POWERDOWNFLAG /etc/killpower
RBWARNTIME 43200
NOCOMMWARNTIME 300
FINALDELAY 5
Der primäre Node setzt das POWERDOWNFLAG, wenn der Shutdown startet. So könnten andere Skripte auf den Event reagieren.
Sollte die USV an den Host übermitteln, dass sie einen neuen Akku benötigt, erinnert der UPS-Monitor den Admin einmal täglich daran (RBWARNTIME). Setzt die Kommunikation zur USV länger als die NOCOMMWARNTIME aus, wird der Administrator ebenfalls informiert.
Für die Benachrichtigungen definieren Sie ihr eigenes Kommando mit dem Eintrag NOTIFYCMD, zu dem es eine ganze Reihe konfigurierbarer Nachrichten wie beispielsweise NOTIFYMSG LOWBATT gibt. Unser Beispielaufbau nutzt die Notify-Funktion gar nicht.
Hier übermittelt Telegraf die upsd-Informationen an Grafana, das als zentraler Alarmierer arbeitet. Nachdem der primäre Knoten bei einem Low-Battery-Zustand allen Secondaries das Shutdown-Kommando übermittelt hat, wartet er nochmals fünf Sekunden (FINALDELAY), bevor er selber den Shutdown einleitet.
Auf den angebundenen LAN-Clients sieht das Setup nahezu identisch aus, nur dass Angaben wie FINALDELAY fehlen und der Nutzer sich anders anmeldet:
MONITOR greencell@<nut-server-host>:3493 1 user <Passwort> slave
Damit ihre Konfigurationsdatei funktioniert, überprüfen Sie zunächst mit dem Kommando upsmon -F, ob der Dienst im Vordergrund startet. Läuft die Konfiguration, aktivieren Sie auf dem primären Knoten die Dienste "nut-driver", "nut-server" und "nut-monitor" über Systemd (systemctl enable <dienst> --now). Die LAN-Clients benötigen nur den Monitordienst.
Das hier vorgestellte Szenario arbeitet mit dem unverschlüsselten NUT-Protokoll zwischen Server und Clients. Bei Bedarf können Sie aber passende Zertifikate erstellen, verteilen und die NUT-Kommunikation via SSL verschlüsseln.
Bild 2: Das Grafana-Dashboard zeigt, dass die UPS im Akkubetrieb bei der Ausgangsspannung schwankt. Der sofortige Abfall des Ladestands beim Ausfall lässt auf einen schwächelnden Akku schließen.
Informationen in Grafana zeigen
Setzen Sie Grafana für das Monitoring und Alerting ein, können Sie über das Tool Telegraf die Informationen von NUT abrufen und an InfluxDB übermitteln. Entweder generieren Sie dazu eine eigene conf-Datei im Verzeichnis "/etc/telegraf/telegraf.d" oder fügen folgende Zeilen an die bestehende "/etc/telegraf/telegraf.conf" an. Damit stellen Sie dann die USV-Werte in Grafana dar:
 [[inputs.upsd]]
      server = "<Nut-Server-Host>"
      port = 3493
      username = "<User1>"
      password = "<Passwort>"
Fazit
Auch eine gute USV kann einen kompletten Stromausfall nicht verhindern. Setzen Sie ein unüberwachtes Gerät ein, fallen Ihre Server einfach nur ein paar Minuten später aus. Erst die richtige Kombination aus USV und Network UPS Tools sorgt dafür, dass Ihre Server bei einer längeren Downtime sanft herunterfahren. Das gute an NUT als Managementwerkzeug ist, dass es herstellerunabhängig mit einer Vielzahl unterschiedlicher Geräte arbeitet. Sollten Sie ihre USV tauschen, benötigen Sie nicht zwingend ein Gerät vom selben Hersteller, um kompatibel zur USV-Managementsoftware zu bleiben. Sie können dann einfach mit weiteren USVs anderer Abieter die Kapazität aufstocken und das bestehende Tool weiter nutzen.
(ln)
Link-Codes
[1] Zu NUT kompatible USV-Hardware: https://networkupstools.org/stable-hcl.html