Das entfernte Starten von Windows-Diensten über NRPE wurde im Wiki ja bereits beschrieben. Hier beschreibe ich, wie ich über NRPE Windows-Applikationen unter einem bestimmten User starte.
Das Problem / meine Situation: In unserer Firma gibt es einige Windows-Applikationen, die verschiedene Konvertierungen/Emails2DB/usw/usf-Funktionen ausführen. Konkret sieht das so aus, dass auf diesen Rechnern ein spezieller Benutzer (mit minimal-Rechten) angemeldet ist, und dort die Applikationen (GUI-basiert) vor sich hin werkeln (dass das alles auch als Windows-Service machbar wäre, sei hier nicht das Thema - meins ist es gottseidank auch nicht, ich bin nur fürs Monitoring da
.
Diese Programme fahren sich des öfteren fest (auch nicht mein Problem
), was ich zwar über Nagios erfahre, aber nun über Eventhandler „selbst heilen“ will, sprich: Nagios soll per NRPE den jew. Prozess abschießen und neu starten.
Mein erster Ansatz war, mit einem als Eventhandler über NRPE ausgelösten Script auf dieser Maschine den Prozess einfach zu killen und neu zu starten. Doch der neue Prozess läuft fortan dann im selben Benutzerkontext wie der NSClient++ (er wurde von ihm ja gestartet), nämlich SYSTEM. Folge: der Prozess läuft, aber die GUI ist nicht mehr sichtbar.
Es musste also eine Lösung her, mit der ich per NRPE eine Anwendung auf der Maschine abschießen und neu starten konnte, sodass diese in einem ganz bestimmten Benutzerkontext läuft.
Vorweg: nicht der Weisheit letzter Schluss, aber sie funktioniert, und zwar ohne die Benutzerdaten im Klartext hinterlegen zu müssen.
Ich bediene mich des Tools runasspc.exe (für private Nutzung kostenlos). Auszug aus der Hilfe:
"Runas Spc startet Programme unter einer anderen Benutzerkennung als dem derzeit angemeldeten Benutzer.\\ Welches Programm unter welcher Kennung gestartet werden soll liest Runas Spc aus einer mit runasspc.exe oder Runasspcadmin.exe erstellten verschlüsselten Datei.\\ Jede verschlüsselte Datei erhält aus Sicherheitsgründen Ihr eigenes Verschlüsselungspasswort, ähnlich eines Fingerabdruckes.\\ Die freigegebene Anwendung wird auf Bitebene überprüft ob Sie gestartet werden darf.\\ Runasspc erfordert keine Installation. Runas Spc kann zusammen mit einer Cryptdatei auf einen Rechner kopiert und von dort direkt gestartet werden.
Ich habe mich dazu entschlossen, per Eventhandler über check_nrpe direkt auf dem Problemhost ein vbscript zu starten, in welchem dann die Logik steckt, was in welchem Servicezustand zu tun ist.
restart_proc.vbs in c:\programme\nsclient\scriptsc:\programme\nsclient\nsc.ini um das Kommando „restart_proc“. $ARG1$ wird alle vier Parameter beinhalten, die Nagios gemäß Eventhandler-Definition an check_nrpe übergibt.restart_proc=cscript.exe //NoLogo scripts\restart_proc.vbs $ARG1$
command-Objekt an. Achtet auf -t 15; das vbscript enthält sleep-Kommandos, die die Ausführung des Scriptes verzögern. Der Default-Timeout von 10 Sekunden ist in diesem Fall auf 15 Sekunden verlängert worden.
# (als Argument ARG1 wird die "problemanwendung.exe" übergeben)
# eh_win_restart_proc
define command{
command_name eh_win_restart_proc
command_line $USER1$/check_nrpe -H $HOSTADDRESS$ -p 5666 -t 15 -c restart_proc -a "$SERVICESTATE$ $SERVICESTATETYPE$ $SERVICEATTEMPT$ $ARG1$"
}
define service{
use templ_s_urservice
service_description s_converter
host_name win_therex
check_command check_converter!60000!300000!28120
contact_groups cg_edv_email
**event_handler eh_win_restart_proc!converter.exe**
}
Wir starten den NSClient++ neu durch, um das neu definierte Kommando zu laden. Zunächst testen wir manuell:
nagios@vmnagios:/usr/local/nagios/libexec$ ./check_nrpe -H 192.168.0.45 -p 5666 -c restart_proc -a "WARNING SOFT 1 converter.exe"
Die Anwendung (egal, ob sie läuft oder nicht, bzw. abgestürzt ist oder nicht) sollte ggf. beendet und in jedem Fall neu gestartet werden.
Im Fehlerfall besser mal ein
nagios@vmnagios:/usr/local/nagios/libexec$ ./check_nrpe -H 192.168.0.45 -p 5666 -c check_ok
absetzen, um die NRPE-Funktion generell zu testen.
Das folgende Script restart_proc.vbs ist unter C:\programme\nsclient\scripts abzulegen. Wenn Ihr Anregungen oder auch Kritik habt, immer nur her damit ![]()
' Region Description
' Arguments:
' 1) Status (ok, warning, critical, unknown)
' 2) Statetype (hard, soft)
' 3) Attempt (1...n)
' 4) Process name
' EndRegion
'full path to runasspc (get from
runasspc="c:\programme\runasspc\runasspc.exe"
'directory of the spc-crypt files
cryptfile="C:\programme\nsclient\scripts\"
'runasspc available?
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FileExists(runasspc) Then
WScript.Echo "ERROR: runasspc.exe not found. Check file path on destination host."
WScript.Quit
End If
On Error Resume Next
i = 0
' Servicestate (ok, warning, critical, unknown)
state = LCase(WScript.Arguments(i))
i = i + 1
' Servicestatetype (hard, soft)
statetype = LCase(WScript.Arguments(i))
i = i + 1
' Serviceattemt (1...n)
attempt = LCase(WScript.Arguments(i))
i = i + 1
' Process name
' Win2k only displays the first 15 chars of the process name in task manager
procname = LCase(WScript.Arguments(i))
If Len(procname) > 15 Then
procname2kill = Left(procname, 15)
Else
procname2kill = procname
End If
If Err.number > 0 Then
WScript.Echo "ERROR: invalid (number of) arguments."
WScript.Quit
End If
On Error Goto 0
' modify this section to your needs
Select Case state
Case "ok" ' nothing to do
Case "warning"
if statetype = "soft" then restartProcess procname,procname2kill
Case "critical" ' nothing to do
if statetype = "soft" then restartProcess procname,procname2kill
Case "unknown" ' nothing to do
End Select
Sub restartProcess(instrProcessName,instrProcess2kill)
' search for running instances of the process
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = '" & instrProcessName & "' OR Name = '" & instrProcess2kill & "'")
For Each objItem In colItems
objItem.terminate
Next
' Wait a few seconds before restarting process
WScript.Sleep(5000)
' restart process
Dim shell, command
command = runasspc & " /cryptfile:" & Chr(34) & cryptfile & procname & "_runasspc.spc" & Chr(34) & " /quiet"
Set shell = CreateObject("WScript.Shell")
On Error Resume Next
shell.Run command
If Err.number = 0 Then
WScript.Echo "OK: Process " & instrProcessName & " successfully restarted."
Else
WScript.Echo "ERROR: restarting process " & instrProcessName & " failed."
End If
On Error Goto 0
' tidy up
Set objWMIService = Nothing
Set colItems = Nothing
Set shell = Nothing
End Sub