[Guide] ESXi / APC-USV / Automatischer Shutdown mit CentOS-VM

besterino

Legende
Thread Starter
Mitglied seit
31.05.2010
Beiträge
7.565
Ort
Wo mein Daddel-PC steht
Bin gerade dabei, mir das einzurichten und da ich das alles im Zweifel - wenn ich es wieder brauche - vergessen haben werde, hier ein kleines HowTo.

Gibt es zwar alles im Netz, aber hier trage ich mal alle Schritte zusammen, vom Einrichten der VM über die Installation von CentOS bis hin zu eben der Konfiguration von APCUPSD. Sollte dann auch für jemanden geeignet sein, der bei Null anfängt (so wie ich vorhin ;) ).

Anmerkungen / Anregungen / Verbesserungen wie immer gerne willkommen!

JETZT FUNKTIONAL ;)

Kurzzusammenfassung:

1. CentOS-VM aufsetzen und CentOS installieren + updaten
2. In CentOS-VM usb-utils + apcupsd installieren
3. apcupsd in SELinux als Ausnahme zulassen (damit apcupsd den SSH-client nutzen darf)
4. In CentOS-VM SSH-keys für user root (!) erzeugen und public-key dem ESXi-Host "beibringen"
5. Auf ESXi-Host in einem Datenspeicher (!) Script-Datei mit den einzelnen Shutdown-Befehlen erstellen
6. In CentOS-VM die Datei "/etc/apcupsd/apccontrol" anpassen, dass anstelle des lokalen shutdowns per ssh die Script-Datei aus 4. ausgeführt wird.


ALLGEMEINE VORBEREITUNGEN (ESXi-HOST / VM AUFSETZEN)

Ausgangsbasis:
1. Host: ESXi 6.5U1
2. USV: APC "Smart-UPS C 1000" und APC "BACK-UPS ES 700"
3. Hardware-Setup: Verbindung USV<-->Host mit USB-Kabel an ganz normalem USB-Port des Host

SSH auf ESXi-Host aktiviereren+starten:
1. TSM-SSH-Dienst manuell starten.
2. Unter Host-->Verwalten-->Dienste rechtsklick auf den Dienst "TSM-SSH" und dann auf Richtlinie "Mit dem Host starten und beenden" Haken setzen.

00_ESXi_SSH.jpg

Wäre ja blöd, wenn das Ganze beim nächsten Reboot des Hosts nicht mehr funktioniert...

Setup VM Hardware:
CPU: 1
RAM: 2048MB (geht bestimmt auch weniger)
USB: APC
02_CentOS_Install.jpg 01_VM_Settings.jpg

CentOS-VM installieren
Download: CentOS 7 64Bit "Everything ISO"

Ich nehm immer englisch als Sprache, da die meisten Howtos zu Linux eh auf englisch sind. ;)

04_CentOS_lang.jpg

Im nächsten Screen empfehlen sich einige Anpassungen:

1. Network & Host Name
Praktisch: VMX3NET wird von Haus aus unterstützt.
1.1 NIC aktivieren und ggf. Hostnamen setzen
05_CentOS_Net_Act.jpg

1.2 Unter "Configure" den automatischen Start bei Verfügbarkeit aktivieren
06_Centos_Net_Autostartjpg.jpg

2. Keyboard Layout:
Da nehme ich dann gerne deutsch...
07_Centos_Keyboard.jpg

3. Date & Time anpassen:
Region: Europe
City: Berlin
Network time: on
08_Datetime.jpg

4. Installation Destination:
Muss man nur einmal aufrufen und mit "Done" bestätigen.
09_Centos_Disk.jpg

5. User Festlegen:
Neben dem Root-Passwort lege ich zusätzlich direkt einen Admin-User an - wir wollen ja nicht alles immer mit root machen...
10_Centos_RootUSer.jpg 11_Centos_ADMIN.jpg

Dann begrüßt uns auch bald schon ein 1/3 Reboot-Button (irgendwie klappt das mit der Darstellung im ESXi-Browser-Console nicht so gut):

12_Centos_Reboot.jpg

Nach dem Reboot begrüßt sehn wir dann (hoffentlich) den Login / geht natürlich auch per SSH.


VM KONFIGURIEREN
Nun haben wir die Basis und können uns dem eigentlichen Thema widmen:

APCUPSD installieren:
1. Naja. Als erstes bringen wir mal das System auf den aktuellen Stand:
Code:
$ sudo yum upgrade
Achtung, man muss ab und an mal mit "y" bestätigen.

2. USB-Utilities installieren (möglicherweise optional, hab's mal gemacht)
Code:
$ sudo yum install usbutils

3. APCUPSD installieren (ist nicht im Standard, daher muss man zusätzliche Quellen hinzufügen):
Code:
 $ sudo yum install epel-release
$ sudo yum update -y
$ sudo yum install apcupsd
$ sudo chkconfig apcupsd on

4. Reboot der VM (geht bestimmt auch anders, aber so geht's halt auch)

5. Ich musste gar nichts mehr manuell konfgurieren, erster Test mit apcaccess:
Code:
$ apcaccess
APC      : 001,034,0851
DATE     : 2018-01-04 14:14:44 +0100
HOSTNAME : MEINER
VERSION  : 3.14.14 (31 May 2016) redhat
UPSNAME  : MEINER
CABLE    : USB Cable
DRIVER   : USB UPS Driver
UPSMODE  : Stand Alone
STARTTIME: 2018-01-04 14:14:42 +0100
MODEL    : Back-UPS ES 700G
STATUS   : ONLINE
LINEV    : 234.0 Volts
LOADPCT  : 0.0 Percent
BCHARGE  : 100.0 Percent
TIMELEFT : 9.9 Minutes
MBATTCHG : 5 Percent
MINTIMEL : 3 Minutes
MAXTIME  : 0 Seconds
SENSE    : High
LOTRANS  : 180.0 Volts
HITRANS  : 266.0 Volts
ALARMDEL : 30 Seconds
BATTV    : 13.5 Volts
LASTXFER : Automatic or explicit self test
NUMXFERS : 0
TONBATT  : 0 Seconds
CUMONBATT: 0 Seconds
XOFFBATT : N/A
STATFLAG : 0x05000008
SERIALNO : 3B1035X01052
BATTDATE : 2010-08-24
NOMINV   : 230 Volts
NOMBATTV : 12.0 Volts
FIRMWARE : 871.O2 .I USB FW:O2
END APC  : 2018-01-04 12:14:07 +0100
$

Sieht gut aus.

SELinux für apcupsd in der VM konfigurieren

0. root werden: "sudo -s"
1. SELinux tools nachrüsten: "yum install policycoreutils-python"
2. Ausnahme für apcupsd setzen: "semanage permissive -a apcupsd_t"

Hinweis: mit dem semanage-Befehl erlauben wir apcupsd quasi "alles" was SELinux normalerweise verbieten würde. Für Sicherheits-Fanatiker ist das natürlich nicht ideal, sondern man müsste apcupsd/apccontrol theoretisch nur den Zugriff auf /usr/bin/ssh und ggf. /root/.ssh/rd_rsa erlauben (die gleich im nächsten Schritt erzeugt wird). Mir war das aber gerade zu mühsam, mich in die Untiefen von SELinux reinzufuchsen und das Sicherheitsrisiko nehme ich sehenden Auges...

SSH konfigurieren
Damit wir uns so voll interaktiv (ohne Passwort-Eingabe) mit der VM über SSH automatisch auf dem ESXi-Host einloggen können, müssen wir uns anstelle per Passwort mit einem SSH-Key authentifizieren.

Alle folgenden Befehle in der VM ausführen! NICHT auf dem ESXi-Host!

Alle Befehle als root ausführen!

0. Falls noch nicht geschehen, zu "root" werden:
Code:
 $ sudo -s

1. SSH-Key für den VM-Nutzer erzeugen:
Wenn man nach einer Passphrase gefragt wird, leer lassen (wir wollen ja später ohne Passworteingabe Befehle ausführen)! Optional: mit dem "-C" Parameter kann man dem Key eine Beschreibung hinzufügen, die dann später die Zuordnung der Keys zu Nutzern und Maschinen erleichtert (siehe Beispiel unten).
Code:
$ ssh-keygen -t rsa -b 4096 -C "root@APC700"

2. SSH-Key dem ESXi-Host "beibringen" für den login als "root":
Wenn man sich das erste mal mit dem ESXi-Host per SSH verbindet, muss man einmal mit "yes" bestätigen, dass man das will. Dann wird man noch einmal nach einem Passwort gefragt - das ist dann das root-Passwort deines ESXi-Hosts!
Code:
 $ cat ~/.ssh/id_rsa.pub | ssh root@[B]HOSTNAME_ODER_IP_DEINES_ESXI-Hosts[/B] 'cat >> /etc/ssh/keys-root/authorized_keys'
The authenticity of host '192.168.178.14 (192.168.178.14)' can't be established.
RSA key fingerprint is [LUSTIGE ZEICHENFOLGE].
RSA key fingerprint is [NOCH EINE LUSTIGE ZEICHENFOLGE].
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '192.168.178.14' (RSA) to the list of known hosts.
Password:
$

Ob das ganze erfolgreich war, können wir dann einfach testen. Wenn der folgende Befehl ohne Passwort-Abfrage erfolgreich zu einem Login auf dem ESXi führt, lüppt das Ganze soweit:
Code:
 ssh root@HOSTNAME_ODER_IP_DEINES_ESXI-Hosts

Jetzt haben wir die Grundfunktionalität.

Erster Zwischenstop: TESTEN

Testen wir das Ganze doch nun einmal. Vorsichtshalber alle anderen VMs auf dem Host sauber herunterfahren.

Dann setzen wir einmal für diesen Testzweck die "Maxtime" auf z.B. 30 Sekunden in der /etc/apcupsd/apcupsd.conf über den TIMEOUT-Parameter:
Code:
# If during a power failure, the UPS has run on batteries for TIMEOUT
# many seconds or longer, apcupsd will initiate a system shutdown.
# A value of 0 disables this timer.
#
#  Note, if you have a Smart UPS, you will most likely want to disable
#    this timer by setting it to zero. That way, you UPS will continue
#    on batteries until either the % charge remaing drops to or below BATTERYLEVEL,
#    or the remaining battery runtime drops to or below MINUTES.  Of course,
#    if you are testing, setting this to 60 causes a quick system shutdown
#    if you pull the power plug.
#  If you have an older dumb UPS, you will want to set this to less than
#    the time you know you can run on batteries.
TIMEOUT 10

Dann noch einmal den Dienst neustarten:
Code:
 service apcupsd restart

Und nun können wir mal testweise das Powerkabel ziehen... Achtung: sobald die VM runterfährt, Strom wieder ranstecken! Der ESXi-Host wird ja momentan noch nicht herunter gefahren!

Dann begrüßt uns recht flott (in meinem Fall allerdings nichts wegen des Timers sondern der leeren Batterie):
Code:
Broadcast message from root@VM-HOSTNAME (Thu Jan  4 12:49:59 2018):

Power failure on UPS VM-HOSTNAME. Running on batteries.

Broadcast message from root@VM-HOSTNAME (Thu Jan  4 12:50:11 2018):

UPS VM-HOSTNAME initiated Shutdown Sequence

Broadcast message from root@VM-HOSTNAME (Thu Jan  4 12:50:11 2018):

Remaining battery runtime below limit on UPS VM-HOSTNAME. Doing shutdown.

Der Test ist erfolgreich, wenn sich dann die VM selbst runterfährt.

Aber das ist ja nicht der Sinn der Übung, sondern es sollen ja vor allem die wichtigen VMs und der ESXi-Host sauber herunter gefahren werden.


ESXI-HOST "SHUTDOWN VMs + HOST KONFIGURIEREN"

Wir gehen also jetzt 'rüber zum ESXi-Host, soll heißen, dort einloggen per SSH (mit dem user root).

1. VMs auflisten
Dort lassen wir uns zunächst mit "vim-cmd vmsvc/getallvms" alle unsere VMs anzeigen und merken uns die IDs zu den jeweiligen VM-Namen:
Code:
[root@ESXI:~] vim-cmd vmsvc/getallvms
Vmid       Name                         File                          Guest OS        Version   Annotation
4      01_SolarisVM   [IntelP600] 01_SolarisVM/01_SolarisVM.vmx   solaris11_64Guest   vmx-13
[root@ESXI:~]

2. Script basteln
Für unsere Automatisierung kreieren wir beispielsweise ein Verzeichnis "scripts". Achtung: Das Verzeichnis muss offenbar auf einem Datenspeicher liegen und darf NICHT im root-Verzeichnis erstellt werden! Ansonsten sind Verzeichnis und Inhalt nach dem nächsten Reboot weg! Hint Hint: sollte vermutlich auch nicht auf einem NFS-Speicher einer Storage-VM liegen, die ihr mit dem Script herunter fahren möchtet...
Code:
$ mkdir /vmfs/volumes/EINERDEINERDATENSPEICHER/scripts

Dann erstellen wir eine Datei, in der wir unsere gesammelten Befehle für den Fall eines Stromausfalls ablegen, zum Beispiel mit dem Namen "shutdown-all-vms.sh":
Code:
 $ vi /vmfs/volumes/DEROBENGEWÄHLTEDATENSPEICHER/scripts/shutdown-all-vms.sh
Mini-Erläuterung zu vi:
Um Text einzugeben die Taste "i" drücken. Wenn ihr mit der Eingabe fertig seid, "ESC". Zum Speichern ":w" und ENTER, zum Verlassen von vi dann ":q" und ENTER. Habt ihr was verfummelt, könnt ihr mit ":q!" den Editor ohne Änderungen an der Datei wieder verlassen.

Um eine VM nun herunter zu fahren nutzt man dann den Befehl "vim-cmd vmsvc/power.shutdown [VMID#]", in der gewünschten Reihenfolge. Das Ganze kann man dann noch mit gewissen Pausen bestücken, wenn zum Beispiel eine Storage-VM dabei ist, die erst herunter gefahren werden soll, wenn all dort liegenden VMs auch wirklich unten sind.

Achtung: Ihr dürft die CentosVM selbst nicht auch herunter fahren, sonst wird das Script abgebrochen! Diese VM wird dann von ESXi selbst auf die eher harte Weise beendet, wenn der Host sich selbst herunter fährt.

In meinem Fall sieht die shutdown-all-vms.sh zum Beispiel auszugsweise so aus:
Code:
vim-cmd vmsvc/power.suspend 1
vim-cmd vmsvc/power.shutdown 7
vim-cmd vmsvc/power.shutdown 6
#vim-cmd vmsvc/power.shutdown 8
#vim-cmd vmsvc/power.shutdown 9
sleep 30s
vim-cmd vmsvc/power.shutdown 2
sleep 120s
poweroff
~

Zur Erläuterung:
VM #1 macht irgendwie zicken, wenn ich sie richtig herunter fahre. Darum schicke ich sie nur schlafen (suspend) bis ich das dann mal irgendwann gefixt habe...
VM #7 und #6 sind normale VMs (Windows 10, Sophos UTM)
VM #8 und #9 sind Centos-APCUPSD-VMs für dieses HowTo, sollen NICHT herunter gefahren werden und sind daher auskommentiert (#)
VM #2 ist eine Storage-VM und wird daher erst am Ende herunter gefahren und dann auch noch mit einem 30-Sekunden-Zeitpuffer

3. APCUPSD in der VM für den (Remote-)Aufruf des Scripts konfigurieren

Auf zum großen Finale!

Wir begeben uns zurück in die VM und erstellen mal als erstes eine Sicherheitskopie der Datei, an der wir gleich herumfummeln. ;-)
Code:
cp /etc/apcupsd/apccontrol /etc/apcupsd/apccontrol.backup.DATUM

Dann editieren wir die Datei "apccontrol" mit vi (s.o.) oder einem anderen Editor Eurer Wahl und ändern Folgendes von "${SHUTDOWN}" bis "shutdown"":

Also

Code:
...
 ;;
    doshutdown)
        echo "UPS ${2} initiated Shutdown Sequence" | ${WALL}
[B]        ${SHUTDOWN} -h -H now "apcupsd UPS ${2} initiated shutdown"[/B]
    ;;

in:

Code:
;;
    doshutdown)
        echo "UPS ${2} initiated Shutdown Sequence" | ${WALL}
[B]        ssh root@HOSTNAME_ODER_IP_ESXi-HOST "sh /vmfs/volumes/DEINOBENGEWÄHLTERDATENSPEICHER/Scripts/shutdown-all-vms.sh"[/B]
    ;;

NOCHMAL TESTEN

Ich empfehle dringend, die Funktionalität auch der apccontrol-Datei und des shutdown-scripts zu testen, also Strom wegnehmen und den ESXi-Host beobachten, dass zuerst die VMs und dann der Host herunter gefahren werden.

Für Hartgesottene und ggf. hilfreich bei der Fehlersuche: Testen kann man seine modifzierte apccontrol-Datei übrigens auch mit "sudo ./apccontrol doshutdown" - davon wird aber ausdrücklich abgeraten! Dafür muss man dann aber nicht immer den dämlichen Strom-Stecker der USV ziehen... Das Auslösen über diesen Befehl findet primär Fehler im Shutdown-Script und bei der Connectivity (SSH), aber z.B. nicht rund um SELinux und anderen Problemchen mit dem apcupsd-Dienst selbst.

Jo, und das war's dann eigentlich auch schon. :d



Quellen:
Graceful UPS shutdowns for your ESXi server with Centos The Helpful Hacker
Random Stuff: OpenSSH Public Key Authentication
Random Stuff: SSH into ESXi 5 host using public key
ESXi vm shutdown script · GitHub
Performing common virtual machine-related tasks with command-line utilities (2012964)
SSH-Key authentication is not working - SELinux - Experiencing Technology
Linux/Services/Ups - Iveze
HowTos/SELinux - CentOS Wiki
An Introduction to SELinux on CentOS 7 – Part 2: Files and Processes | DigitalOcean
 
Zuletzt bearbeitet:
Wenn Du diese Anzeige nicht sehen willst, registriere Dich und/oder logge Dich ein.
Wer btw. eine NAS von Synology hat (Oder XPEnology als VM laufen lassen hat), kann das herunterfahren darüber auch anstoßen - Leider aber nicht mit sovielen Einstellmöglichkeiten ab wann. (Geht bestimmt auch mit QNAP - Aber nie getestet, da keine USB USV daran angesteckt ist)
Wenn ich mal Lust und Laune habe, kann ich das mal am Wochenende auch hier reinposten, da evtl. für einige Interessant (Wird aber auf dem ESXi Teil je nach deiner Beschreibung wohl nicht viel anders sein :bigok:)
 
Wer btw. eine NAS von Synology hat (Oder XPEnology als VM laufen lassen hat), kann das herunterfahren darüber auch anstoßen - Leider aber nicht mit sovielen Einstellmöglichkeiten ab wann. (Geht bestimmt auch mit QNAP - Aber nie getestet, da keine USB USV daran angesteckt ist)
Wenn ich mal Lust und Laune habe, kann ich das mal am Wochenende auch hier reinposten, da evtl. für einige Interessant (Wird aber auf dem ESXi Teil je nach deiner Beschreibung wohl nicht viel anders sein :bigok:)

Wäre interessant, wie man bei Synology noch andere externe Aktionen damit triggern kann. Habe es zwar mit einer Windows VM gelöst, aber interessant ist es alle mal.
 
Platzhalter / Inhalt konsolidiert im Startpost.
 
Zuletzt bearbeitet:
Wäre interessant, wie man bei Synology noch andere externe Aktionen damit triggern kann. Habe es zwar mit einer Windows VM gelöst, aber interessant ist es alle mal.
Siehe Anhang - Ist zurzeit unkonfiguriert, aber man kann da nicht nur die IP von anderen Diskstations einfügen.
Die NAS schickt halt stumpf ein Signal, dass der Empfänger (Falls er z. B. eben die APC Tools installiert hat) in einen shutdown geht und anschließend fährt die VM/Maschine selbst herunter, somit eig. kein Problem.

Wie gesagt - würde am Wochenende mal auch ne Anleitung hierzu reinposten, aber zurzeit bin ich noch unterwegs :)
 

Anhänge

  • 1234.JPG
    1234.JPG
    84,7 KB · Aufrufe: 289
  • 123.JPG
    123.JPG
    58 KB · Aufrufe: 375
Platzhalter / konsolidiert im Startpost.
 
Zuletzt bearbeitet:
Super Anleitung!!!
Werde ich bei mir auch in Kürze umsetzen.

Zwei Fragen noch dazu:

1. Könnte man das nicht auch komplett in der VM machen, welche sich dann am Ende selbst runterfährt?
Dann würde nur der ESXi übrigbleiben, welcher aber m.W. ohnehin im Speicher läuft und somit hoffentlich kein Problem mit einem harten Stop (Stromunterbrechung) hat?

2. Kann man statt MAXTIMEOUT auch REMAININGTIME verwenden, so dass die VMs erst runtergefahren werden, kurz bevor die Akkus leer sind (natürlich mit entsprechender Pufferzeit)?
 
1. Geht bestimmt irgendwie. Aber mir wäre wichtiger, den Host sauber herunter zu fahren, als die billo UPS-VM. Der Host versucht ja beim shutdown schon noch, die VMs sauber zu beenden. Außerdem ist es da viel kritischer, wenn der Host noch ungeschriebene Daten irgendwo im (RAM)Cache hat - die soll der mal lieber ordentlich wegschreiben, bevor das Licht ausgeht. ;) Dagegen darf die UPS-VM gerne ""hops" gehen - die leg' ich mir jetzt sowieso noch einmal als Kopie irgendwo auf's NAS, so dass ich die razzfazz im Falle eines Falles wieder zurückkopieren kann. An der ändere ich ja nichts mehr, wenn's einmal läuft.

2. Ja, das ist der Standard: APCUPSD löst den Shutdown normalerweise aus wenn entweder a) nur noch eine bestimmte Restzeit in der UPS steckt oder b) die Batterie nur noch X% voll ist. Der MAXTIME-Parameter muss dafür nur auf 0 gesetzt werden (0 ist auch default), ich hatte den nur für Testzwecke auf 30 gesetzt.
 
Hmm... also EIGENTLICH sollte es so funktionieren. Wenn ich den ssh-Befehl manuell absetze, fährt er auch alle VMs ordentlich runter. Nur wenn ich den Befehl über apccontrol aufrufe, passiert nichts - kennt jemand das Problem und hat evtl. eine Lösung?
 
Wenn Du im Host die VMs auf automatisch starten/Herunterfahren eingestellt hast, sollte doch durch den Befehl des Host-Shutdowns die VMs in umgekehrter Reihenfolge auch herunterfahren - wozu brauchst Du dann die IDs um sie per Skript zu stoppen? - vorallem starten die ja dann nicht wieder mit dem Host o_O
 
@konfetti: dazu komm ich noch. ;)

Momentan habe ich aber noch das Problem, dass ich mit dem apcupsd-Script gar nicht auf den ESXi-Host komme. Vermutlich funkt mir SELINUX dazwischen, so dass ich mit dem apcupsd-user gar keine SSH-Verbindung aufbauen kann. Immerhin ändert sich mit "setenforce 0" die Fehlermeldung in /var/log/messages von

"Jan 4 18:29:26 apcupsd apcupsd: /etc/apcupsd/apccontrol: line 111: /usr/bin/ssh: Permission denied"

in

"Jan 4 18:48:24 apcupsd apcupsd: Host key verification failed."

Wie könnte ich denn den doofen SSH-Befehl als mein lokaler User ausführen, bevor ich jetzt das ganze System umbiege? ;)
 
als welcher lokaler User? - entweder gibst Du dem Script die Rechte oder trägst des halt User+Pass in des Script mit ein, sofern Du den ESX-Host mit lokaler User meinst.
 
Hab den Fehler gefunden... und oben im HowTo korrigiert. Da apcupsd als root läuft, muss man (natürlich) das SSH-Key-Paar als root auf der VM erstellen und dann auch dem ESXi-Host mitgeben. :wall:

So viel dazu.

Für Hartgesottene: Testen kann man seine modifzierte apccontrol-Datei übrigens mit "sudo ./apccontrol doshutdown" - davon wird aber ausdrücklich abgeraten! Dafür muss man dann aber nicht immer den dämlichen Strom-Stecker der USV ziehen...

ToDo: momentan hab' ich für meine beiden USV jeweils eine separate VM erstellt. Es soll ja gehen, mit einer VM mehrere USV zu steuern bzw. abhängig von den Events auf mehreren USV unterschiedliche Aktionen auszulösen. Damit habe ich mich noch nicht beschäftigt - eins nach dem anderen. ;)
 
Zuletzt bearbeitet:
So ein Käse. Ich fürchte, ich brauche doch noch einmal Hilfe der Linuxxer hier. Mir Fehlen gerade irgendwie die Ideen für die weitere Fehlersuche.

Folgendes Problem: Wie ich heute auf die harte Tour feststellen musste, fährt meine VM den ESXi-Host bei einem Stromausfall doch nicht automatisch herunter.

Immerhin erkennt die VM/apcupsd laut /var/log/messages, dass der Strom weg war und initiiert den Shutdown:
Code:
248 Feb  5 16:28:44 apcupsd apcupsd[1077]: Power failure.
    249 Feb  5 16:28:50 apcupsd apcupsd[1077]: Running on UPS batteries.
    250 Feb  5 16:28:50 apcupsd wall[6602]: wall: user root broadcasted 1 lines     250 (51 chars)
    251 Feb  5 16:41:56 apcupsd apcupsd[1077]: [B]Battery charge below low limit.[/B]
    252 Feb  5 16:41:56 apcupsd apcupsd[1077]: [B]Initiating system shutdown![/B]
    253 Feb  5 16:41:56 apcupsd apcupsd[1077]: User logins prohibited
    254 Feb  5 16:41:56 apcupsd wall[6612]: wall: user root broadcasted 1 lines     254 (39 chars)
    255 Feb  5 16:41:56 apcupsd wall[6614]: wall: user root broadcasted 1 lines     255 (68 chars)
    256 Feb  5 16:41:56 apcupsd apcupsd: /etc/apcupsd/apccontrol: line 111: /usr    256 /bin/ssh: Permission denied

Er geht auch in die richtige Stelle im Script, um die SSH-Connection zum ESXi-Host herzustellen und dort das VM-Shutdown-Script auszuführen, scheitert aber irgendwie an Berechtigungen:
Code:
  256 Feb  5 16:41:56 apcupsd apcupsd: /etc/apcupsd/apccontrol: [B]line 111: /usr/bin/ssh: Permission denied[/B]

Die dazugehörende Configdatei apccontrol sagt in der genannten Zeile:
Code:
108     ;;
    109     doshutdown)
    110         echo "UPS ${2} initiated Shutdown Sequence" | ${WALL}
    111         /usr/bin/ssh root@192.168.178.10 "sh /vmfs/volumes/SSDSandsk_Local/Scripts/shutdown-all-vms.sh"
    112     ;;

Das absurde: der SSH-login ohne passwort funktioniert mit dem user root völlig problemlos:
Code:
[root@VM]# ssh 192.168.178.10
The time and date of this login have been sent to the system logs.

WARNING:
   All commands run on the ESXi shell are logged and may be included in
   support bundles. Do not provide passwords directly on the command line.
   Most tools can prompt for secrets or accept them from standard input.

VMware offers supported, powerful system administration tools.  Please
see www.vmware.com/go/sysadmintools for details.

The ESXi Shell can be disabled by an administrative user. See the
vSphere Security documentation for more information.
[root@ESXi:~]

Auch wenn ich das apccontrol-Script manuell in der VM als root mit dem Befehl ./apccontrol doshutdown auslöse, funktioniert es...

Was zum Henker habe ich übersehen?
 
Zuletzt bearbeitet:
Mein Service Account müsste doch eigentlich „root“ sein - dachte ich jedenfalls? Oder anders formuliert: wie finde ich denn den Account heraus, unter dem apcupsd läuft bzw. das Script aufgerufen wird?

Würde es alternativ helfen, das Key-file in Root/.ssh oder so ausdrücklich mit anzugeben und zur Not auf read-Access für alle zu setzen?
 
Zuletzt bearbeitet:
Der Serviceaccount heißt apcupsd, erkennbar im zweiten Quote.
Das war Quatsch. Prüfe aber trotzdem mal ob es einen solchen User gibt.


Du kannst entweder im SSH Befehl das identity File vom root User mit angeben (finde ich doof, da auch die Rechte angepasst werden müssen), oder im Homeverzeichnis des Serviceusers ein eigenes keyfile anlegen (oder das von root kopieren). Das Homeverzeichnis steht in der Datei /etc/passwd.
 
Zuletzt bearbeitet:
Dein Service läuft vermutlich als User root, kontrollieren kannst Du das z.B. mittels:
ps -eF | grep apcupsd
Die erste Spalte ist der User, unter dem der Prozess läuft.

Ich gehe davon aus, dass Du
- den Filename des Private Key auf id_rsa gelassen hast
- keinen ssh-agent oder keychain verwendest
- die Dateirechte innerhalb des .ssh Ordners original gelassen hast
Meistens ist das Problem, dass irgendwelche Variablen der Umgebung bei einem Service oder Cron nicht zur Verfügung stehen, die Du normalerweise nutzen kannst.

Mach mal aus Deinem ssh Befehl folgendes:
/usr/bin/ssh root@192.168.178.10 "sh /vmfs/volumes/SSDSandsk_Local/Scripts/shutdown-all-vms.sh" -i /root/.ssh/id_rsa -v 2> /tmp/apcupsd_ssh.log
und poste nach einem Connect Versuch den Inhalt der Logdatei.

Grüße
Martin
 
Zuletzt bearbeitet:
Danke! Das sollte meinen Verdacht bestätigen, dass apcupsd tatsächlich als root läuft:
Code:
$ ps -eF | grep apcupsd
root      1077     1  0 31197  1812   0 Feb05 ?        00:00:07 /sbin/apcupsd -b -f /etc/apcupsd/apcupsd.conf
userNo1    2028  2005  0 28165   976   0 16:16 pts/0    00:00:00 grep --color=auto apcupsd
$
Ich gehe davon aus, dass Du
- den Filename des Private Key auf id_rsa gelassen hast
- die Dateirechte innerhalb des .ssh Ordners original gelassen hast
Richtig.

- keinen ssh-agent oder keychain verwendest
Öhhh... kann ich das ausschließen, wenn ich nicht weiß, was das sein soll/wie das funktioniert? ;)

Deinen Vorschlag kann ich heute Abend hoffentlich mal ausprobieren! Danke schon einmal bis hierhin!
 
Vermutlich. Ein ssh-agent dient dazu, verschlüsselte Private-Keys nach Eingabe eines Passworts zu entschlüsseln und für eine gewisse Zeit entschlüsselt zu halten. Habe ich aber noch nie auf einem Server verwendet und wird vermutlich bei Dir auch nicht aktiv sein (wobei ich weder mit CentOS noch mit SELinux viel Erfahrung habe). Kannst ja mal folgendes ausführen: rpm -qa | grep -E 'ssh-agent|keychain'
Wird vermutlich keinen Treffer geben.
Ich glaube aber auch nicht so recht, dass es an SELinux liegt, weil das Skript eingeloggt ausgeführt sich ja verbindet. Kannst dennoch mal Deinen aktuellen SELinux mit getenforce ansehen und zum Testen temporär deaktivieren: setenforce 0

Das ist aber alles Stochern im Trüben, sieh Dir erst mal das Logfile an. Da kann man zumindest mal erkennen, wohin die Reise geht. Ob er nicht den korrekten Private Key verwendet, ob die Berechtigungen nicht passen, ob er den Host nicht in der verwendeten known_hosts findet usw.
 
Hmmm... also das hat bisher noch nicht zum Erfolg geführt.

Wenn apccontrol über einen powerloss getriggered wird, bekomme ich in der log-Datei mein übliches:
Code:
/etc/apcupsd/apccontrol: line 112: /usr/bin/ssh: Permission denied
apcupsd_ssh.log.triggered (END)

Löse ich das manuell über ./apccontrol doshutdown aus, klappt's (der ESXi-Host fährt herunter) und ich bekomme:
Code:
OpenSSH_7.4p1, OpenSSL 1.0.2k-fips  26 Jan 2017
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 58: Applying options for *
debug1: Connecting to 192.168.178.15 [192.168.178.15] port 22.
debug1: Connection established.
debug1: permanently_set_uid: 0/0
debug1: identity file /root/.ssh/id_rsa type 1
debug1: key_load_public: No such file or directory
debug1: identity file /root/.ssh/id_rsa-cert type -1
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_7.4
debug1: Remote protocol version 2.0, remote software version OpenSSH_7.5
debug1: match: OpenSSH_7.5 pat OpenSSH* compat 0x04000000
debug1: Authenticating to 192.168.178.15:22 as 'root'
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: algorithm: curve25519-sha256
debug1: kex: host key algorithm: rsa-sha2-512
debug1: kex: server->client cipher: aes128-ctr MAC: hmac-sha2-256 compression: none
debug1: kex: client->server cipher: aes128-ctr MAC: hmac-sha2-256 compression: none
debug1: kex: curve25519-sha256 need=32 dh_need=32
debug1: kex: curve25519-sha256 need=32 dh_need=32
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: Server host key: ssh-rsa SHA256:ldxJvJz6+SiKGz8vLwuvdkAeSKKBV39GNv+wyB72y7k
debug1: Host '192.168.178.15' is known and matches the RSA host key.
debug1: Found key in /root/.ssh/known_hosts:2
debug1: rekey after 4294967296 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: rekey after 4294967296 blocks
debug1: SSH2_MSG_EXT_INFO received
debug1: kex_input_ext_info: server-sig-algs=<ssh-ed25519,ssh-rsa,rsa-sha2-256,rsa-sha2-512,ssh-dss,ecdsa-sha2-nistp256,ecdsa-sha2-nistp384,ecdsa-sha2-nistp521>
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,keyboard-interactive
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /root/.ssh/id_rsa
debug1: Server accepts key: pkalg rsa-sha2-512 blen 535
debug1: Authentication succeeded (publickey).
Authenticated to 192.168.178.15 ([192.168.178.15]:22).
debug1: channel 0: new [client-session]
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug1: Sending environment.
debug1: Sending env LANG = en_US.UTF-8
debug1: Sending command: poweroff
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug1: client_input_channel_req: channel 0 rtype eow@openssh.com reply 0
debug1: channel 0: free: client-session, nchannels 1
debug1: fd 2 clearing O_NONBLOCK
Connection to 192.168.178.15 closed.
Transferred: sent 3976, received 3016 bytes, in 0.1 seconds
Bytes per second: sent 76917.1, received 58345.6
debug1: Exit status 0
apcupsd_ssh.log.manual (END)

Nach weiterer Google-Suche scheint vielleicht tatsächlich SELinux das Problem zu sein: in /var/log/audit/audit.log finde ich mehrere Einträge entsprechend dieser Seite:
Code:
type=AVC msg=audit(1515076635.820:122): avc:  denied  { getattr } for  pid=1490 comm="apccontrol" path="/usr/bin/ssh" dev="dm-0" ino=25517356 scontext=system_u:system_r:apcupsd_t:s0 tcontext=system_u:object_r:ssh_exec_t:s0 tclass=file

Dann mal selinux mit setenforce 0 ausgeschaltet und siehe da, die Kiste fährt runter!

So - jetzt muss ich nur noch einen Weg finden, SElinux beizubringen, dass es apccontrol das Ausführen des SSH-Befehls (inkl. Zugriff auf's keyfile) erlaubt... das mach' ich dann mal "morgen". ;)

Edit: Puh, SELinux ist ja mal wieder eine ganz eigene Welt. Der hier (http://www.iveze.nl/wiki/index.php/Linux/Services/Ups) klingt vielversprechend:

Selinux
Selinux causes quite some trouble for apcupsd.
The override scripts have the wrong type, so apcupsd does not execute them.
Ssh usage is not allowed by apcupsd
Since we do not consider apcupsd a great liability to the server, we choose to make the type apcupsd_t permissive.
semanage permissive -a apcupsd_t
 
Zuletzt bearbeitet:
Poste doch bitte mal den Output von unserem neuen logfile /tmp/apcupsd_ssh.log
 
Hab ich doch oben. (Heißen nur apcupsd_ssh.log.triggered und apcupsd_ssh.log.manual.)
 
Sorry, habe das aufm Handy völlig übersehen.
Ja, der apcupd Service darf aufgrund SELinux ssh überhaupt nicht aufrufen, zum Keyfile kommt es noch gar nicht.
Muss ich mir mal ansehen, von SELinux wie gesagt kaum Plan.
 
manmanman... weiter geht's, lese gerade das SELinux wiki von CentOS quer.

SELinux "überwacht" also auch den ssh-client:
Code:
$ ls -Z /usr/bin/ssh
-rwxr-xr-x. root root system_u:object_r:ssh_exec_t:s0  /usr/bin/ssh

apcupsd läuft offenbar im Typ "unconfined":
Code:
$ ps axZ | grep apcupsd
system_u:system_r:apcupsd_t:s0   1134 ?        Ssl    0:00 /sbin/apcupsd -b -f /etc/apcupsd/apcupsd.conf
unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 1459 pts/0 S+   0:00 grep --color=auto apcupsd

in /var/log/audit/audit.log finden sich verschiedene denied-Einträge rund um apcupsd und apccontrol (fett und Unterstreichung von mir):
Code:
 11433 type=AVC msg=audit(1517959882.283:408): avc:  [B][U]denied[/U][/B]  { execute } for  pid=2540 comm="[B][U]apccontrol[/U][/B]" name="ssh" dev="dm-0" ino=
  11433 25517356 scontext=system_u:system_r:[B][U]apcupsd_t[/U][/B]:s0 tcontext=system_u:object_r:ssh_exec_t:s0 tclass=file
  11434 type=AVC msg=audit(1517959882.283:408): avc:  [B][U]denied[/U][/B]  { read open } for  pid=2540 comm="[B][U]apccontrol[/U][/B]" path="/usr/bin/ssh" dev=
  11434 "dm-0" ino=25517356 scontext=system_u:system_r:[B][U]apcupsd_t[/U][/B]:s0 tcontext=system_u:object_r:ssh_exec_t:s0 tclass=file
  11435 type=AVC msg=audit(1517959882.283:408): avc:  [B][U]denied[/U][/B]  { execute_no_trans } for  pid=2540 comm="[B][U]apccontrol[/U][/B]" path="/usr/bin/ss
  11435 h" dev="dm-0" ino=25517356 scontext=system_u:system_r:[B][U]apcupsd_t[/U][/B]:s0 tcontext=system_u:object_r:ssh_exec_t:s0 tclass=file
  11436 type=SYSCALL msg=audit(1517959882.283:408): arch=c000003e syscall=59 success=yes exit=0 a0=1f34c20 a1=1f2ed00 a2=1f34800 a3=
  11436 7ffccbc2fae0 items=0 ppid=2534 pid=2540 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=(none) s
  11436 es=4294967295 comm="ssh" exe="/usr/bin/ssh" subj=system_u:system_r:[B][U]apcupsd_t[/U][/B]:s0 key=(null)
  11437 type=PROCTITLE msg=audit(1517959882.283:408): proctitle=2F7573722F62696E2F737368002D74002D69002F726F6F742F2E7373682F69645F72
  11437 7361002D7600726F6F74403139322E3136382E3137382E313500706F7765726F6666
  11438 type=AVC msg=audit(1517959882.287:409): avc:  [B][U]denied[/U][/B]  { setuid } for  pid=2540 comm="ssh" capability=7  scontext=system_u:sy
  11438 stem_r:apcupsd_t:s0 tcontext=system_u:system_r:[B][U]apcupsd_[/U][/B]t:s0 tclass=capability
  11439 type=SYSCALL msg=audit(1517959882.287:409): arch=c000003e syscall=117 success=yes exit=0 a0=ffffffffffffffff a1=0 a2=fffffff
  11439 fffffffff a3=7f6f29dea300 items=0 ppid=2534 pid=2540 auid=4294967295 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0
  11439  tty=(none) ses=4294967295 comm="ssh" exe="/usr/bin/ssh" subj=system_u:system_r:apcupsd_t:s0 key=(null)
  11440 type=PROCTITLE msg=audit(1517959882.287:409): proctitle=2F7573722F62696E2F737368002D74002D69002F726F6F742F2E7373682F69645F72
  11440 7361002D7600726F6F74403139322E3136382E3137382E313500706F7765726F6666
  11441 type=AVC msg=audit(1517959882.287:410): avc:  [B][U]denied[/U][/B]  { getattr } for  pid=2540 comm="ssh" path="[B][U]/root/.ssh/id_rsa[/U][/B]" dev="dm-
  11441 0" ino=25462332 scontext=system_u:system_r:[B][U]apcupsd_t[/U][/B]:s0 tcontext=unconfined_u:object_r:ssh_home_t:s0 tclass=file

Coming up next: Jetzt muss ich irgendwie den Zugriff erlauben... ("semanage" gibt's jedenfalls irgendwie schonmal nicht, aber immerhin "chcon". Eine ganze policy mit audit2allow wollte ich jetzt eigentlich nicht basteln).

Aus meiner Sicht noch verständlicher als das Wiki: An Introduction to SELinux on CentOS 7 – Part 2: Files and Processes | DigitalOcean

Zu Analyse- und Testzwecken habe ich schonmal die selinux-tools mit "yum install policycoreutils-python" für "semanage", "sesearch" usw. nachgerüstet...

...und dann die Geduld verloren und einfach wie oben in dem Zitat mal "semanage permissive -a apcupsd_t" gesetzt. VM-Reboot. Power getrennt. Shutdown vom ESXi-Host läuft durch. Habe fertig. :hwluxx:


Funzt dann übrigens auch ohne dass man explizit mit "-i" den Key angibt.

HowTo oben ist bereits angepasst und entsprechend um den Schritt zu SELinux ergänzt.
 
Zuletzt bearbeitet:
HowTo geringfügig überarbeitet / konsolidiert / Quellen ergänzt.
 
Zuletzt bearbeitet:
Läuft das bei dir immer noch so in der Konstellation oder hast du, wie von "konfetti" bereits im Januar angemerkt, zwecks Auto-Start/Stopp deiner VMs umgestellt?
 
Das läuft immer noch so. Stabil und auf Herz und Niere hinsichtlich Funktionalität getestet.

Never change a running system. Und zu faul, an der Stelle jetzt weiter zu fummeln oder zu optimieren. ;)
 
Hardwareluxx setzt keine externen Werbe- und Tracking-Cookies ein. Auf unserer Webseite finden Sie nur noch Cookies nach berechtigtem Interesse (Art. 6 Abs. 1 Satz 1 lit. f DSGVO) oder eigene funktionelle Cookies. Durch die Nutzung unserer Webseite erklären Sie sich damit einverstanden, dass wir diese Cookies setzen. Mehr Informationen und Möglichkeiten zur Einstellung unserer Cookies finden Sie in unserer Datenschutzerklärung.


Zurück
Oben Unten refresh