PRTG - HTTP Push-Sensoren

Ein PRTG-Server nutzt lokale und verteilte Probes, um mit diesen lokale und entfernte Systeme zu überwachen. Die Probes können verteilt werden, holen ihre Konfiguration vom PRTG-Server, arbeiten die Jobs an und melden an den Server. So kann ein skalierbares und performantes System aufgebaut werden. Es bleibt aber ein "Polling" durch die Probes mit ein eingebauten Sensoren oder Custom Sensoren. Diese Seite beschreibt die HTTP-Push-Sensoren.

Die Sensoren habe ich erstmals in der Version 15.2.16.2229 als Beta gesehen. Angeblich gibt es den aber seit 14.2.9 den Adv Sensor und seit 13.4.7 den einfachen HTTP Push Count. Man sollte doch häufiger mal die Release Notes lesen. Er ist aber aktuell immer noch Beta und enthält eine Warnung:

Currently, this sensor type is in beta status. The methods of operating can change at any time, as well as the available settings. Do not expect that all functions will work properly, or that this sensor works as expected at all. Be aware that this type of sensor can be removed again from PRTG at any time.
This sensor type cannot be used in cluster mode. You can set it up on a local probe or remote probe only, not on a cluster probe.

Einschränkungen des klassischen Monitoring

Das passive Monitoring unterliegt mehreren Einschränkungen, die per HTTP-Push-Probe besser gelöst werden können.

  • Überwachbarkeit
    Zuerst muss das zu überwachende Objekt auch per PRTG-Sensor "überwachbar" sein, sei es dass ein Dienst per LAN angesprochen werden kann, ein Performance Counter ausgelesen oder ein anderes Kriterium nutzbar ist.
    Mit der HTTP Push-API kann aber ein Skript oder Prozess auch selbst aktiv Meldungen senden ohne auf eine Probe zu warten. Das ist für Alarme o.ä. besonders interessant oder Skripte, die einen eigenen Scheduler haben und das Ergebnis dann ohne Verzug melden können.
  • Stichproben/Intervall
    Eine PRTG-Probe kann nicht permanent überwachen sondern führt den Check regelmäßig in voreingestellten Intervallen aus. Hier ist ein Kompromiss zwischen Aktualität und Belastung zu finden. Viele Checks laufen daher einmal pro Minute, alle 5 Minuten oder noch seltener ab.
    Ein HTTP Push-Sensor ist hier für die PRTG-Plattform viel schonender, insbesondere wenn die Werte aufwändig per Custom Sensor (PowerShell o.ä.) ermittelt werden müssen
  • Zeitverzug
    Durch das Intervall werden natürlich Werte nicht ein "Realtime" übermittelt, sondern immer etwas verzögert. Das ist natürlich schlecht wenn Grenzwerte überschritten werden.
    Ein HTTP Push-Sensor kann alleine z.B. bei bestimmten Bedingungen "schnell" senden.
  • Skalierbarkeit der Probe
    Je mehr aktive Tests eine PRTG Probe gegen den lokalen Server oder remote Systeme unternehmen muss, desto mehr Leistung muss bereit gestellt werden. Gewisse Aufrufe (WMI, PowerShell etc.) sind sogar sehr kostspielig und können eine zeitnahe Überwachung erschweren oder gar unmöglich machen.
    Ein HTTP Sensor verteilt die Last weg von der Probe auf den Server oder Service.
  • Feste IP-Adresse oder DNS-Name und NAT
    Wenn ein Server "aus der Ferne" überwacht wird, dann muss er von der Probe erreichbar sein. Das ist knifflig, wenn das System keine feste IP-Adresse hat oder hinter einem NAT-Router steht. Denkbar schlechte Aussichten für IoT-Geräte, die gegen ein PRTG in der Cloud laufen
  • Energiesparen
    Immer mehr Geräte sind Batteriebetrieben oder schalten sich nur sehr kurz ein (Solarbetrieb, Piezo). Sie sind kurz wach, können ein paar Pakete senden und legen sich dann wieder tief schlafen. So ein Gerät können Sie schlecht aus der Ferne abfragen aber es kann Daten an eine Stelle melden. Denken Sie an Wasserstandsmelder, Feuchtigkeitssensoren in Pflanzkübeln etc.
  • Berechtigungen
    Wenn PRTG aus der Ferne einen Server überwachen soll, dann muss er sich an dem Server authentifizieren, oft sogar als Administrator. Damit ist so ein "Monitoring-Programm" am Ende mächtiger als Der "Domänen-Administrator". Da ist es schon eleganter, wenn der PRTG-Server einfach Daten annimmt, erfasst und deren Ausbleiben ermittelt aber der Dienstadministrator die Überwachung vor Ort kontrolliert.
  • Erreichbarkeit des Systems und Sicherheit
    Alle Prüfungen, die von einer Probe gegen ein Device ausgeführt werden, bedingen die Erreichbarkeit des Device für die Probe. Firewalls oder gar NAT sind dabei natürlich hinderlich. Jedes Device muss auch über einen "Port" erreichbar sein und je "einfacher" ein Device ist, desto rudimentärer sind hierbei die Möglichkeiten zur Absicherung (SourceIP-Filter, Kennwort-Verschlüsselung).

Allerdings bedeutet der Einsatz der "HTTP Push"-Funktion natürlich, dass die Probe von dem Endpunkt aus erreichbar ist und auf dem zu überwachenden System entsprechender Code addiert wird.

Sie können diese Technik wunderbar nutzen, um auch einfach den Status von beliebigen Skripten auf verschiedenen Servern an PRTG als zentrale Überwachungsinstanz zu melden.

HTTP Push Data und Push Data Advanced

PRTG enthält genau genommen drei dieser "Push"-Sensoren, bei denen per HTTP-GET oder HTTP-POST Daten an eine Probe zur Ablage in PRTG gesendet werden können.

  • HTTP Push Count sensor
    Dieser einfache Sensor "zählt" einfach nur jede empfangene Information. Wer also ein Skript gebaut hat, welches eine gewissen Event "zählen" will, dann ist dieser einfache Sensor passend.
  • HTTP Push Data sensor
    Der Data Sensor übernimmt die Zahl, die mit dem Request übermittelt wird. Wenn also nur ein einziger Wert zu senden ist, ist dieser Sensor der Richtige
  • HTTP Push Data Advanced sensor
    Zuletzt gibt es noch die Möglichkeit mehrere Werte als XML-Struktur an PRTG zu übergeben (Siehe auch PRTG:Custom Sensor)

Insofern haben wir mit dem Push-Sensor eine Möglichkeit aktiv vom überwachten System Daten in PRTG einzustellen, ohne das PRTG selbst aktiv werden müsste.

Leider hat PRTG bislang nicht vorgesehen, dass z.B. beim "Advanced Sensor" auch ein Zeitstempel mitgeliefert wird. Das wäre aus meiner Sicht sehr wünschenswert um gepufferte Daten zeitgenau zugeordnet werden können. Nebenbei könnte man so auch alte Daten importieren.

Der Sensor wird wie alle Sensoren einfach an ein Gerät addiert:

Sie können ein oder mehrere HTTP-Push-Sensoren pro Gerät anlegen. Wer ein Gerät abbilden will, welche keine IP-Adresse hat, kann z-B 0.0.0.0 als IP-Adresse eintragen und darunter dann ein oder mehrere HTTP-Push-Sensoren konfigurieren. Es ist dabei kein Problem, wenn alle Push-Sensoren den gleichen Port (Default 5050) nutzen, da das sendende Gerät eine eindeutige Kennung mit senden muss. "Sicher" ist das aber nur bedingt. Wer auf dem LAN so einen Push mitschneiden kann, kennt zumindest eine Geräteidentifikation und kann falsche Daten einschleusen. Es gibt hier kein Handshake, USN o.ä. oder gar SSL-Verschlüsselung. Das könnte man sicher besser machen aber dann wird der Aufwand beim Sender wieder größer.

Da fehlt dann ja nur noch, dass man auch per UDP einfach Daten an PRTG senden kann. für viele ganz kleine Gerät (PIC, Arduino etc.) sind TCP-Verbindungen schon viel aufwändiger als ein UDP-Paket. Aber das ist so kein Problem, denn diese Lücke kann man einfach selbst schließen.

Ein einfacher Test können Sie mit jedem Browser machen. Ich habe mir dazu einfach einmal einen "Count" und einmal einen "Data"-Sensor angelegt. Eine XML-Datei sende ich später per PowerShell. Im Browser reicht dann die Eingabe einer URL

GET http://<probe_ip>:<port_number>/<token>?value=<integer_or_float> &text= <text message>

# Advanced Sensor mit GET
GET http://<probe_ip>:<port_number>/<token>?content=<valid XML_or_JSON>

Als Antwort bekommt man eine JSON-Meldung. Hier ein Beispiel mit einem ungültigen Token.

Achtung: Das Token ist "Case sensibel".

Solange die Sensoren noch nichts bekommen haben, ist der Status nur beim "Counter" auf Grün mit 0 und die beiden anderen auf "Unknown"

Sobald Daten gesendet werden, sind diese auch alle in PRTG zu sehen:

Wer hier also im Sekundentakt Daten sendet, kann sehr fein auflösen aber füllt auch sehr schnell die PRTG-Datenbank. Obwohl es ein "Push-Sensor" ist, kann man ein "Scanning-Intervall" angeben. Ich habe testweise die 60 Sek stehen lassen. Sendet der Sensor mehrere Werte pro Minute wird anscheinend ein Mittelwert erstellt und nur dieser aufgetragen.

Andererseits werden aber ausbleibende Werte innerhalb des Intervalls nicht als "Downtime" gewertet oder als Fehler geliefert. Dies ist der Default. Wenn Sie ausbleibende Werte als Fehler haben wollen, dann sollten Sie dies in den Einstellungen ändern.

Dann aber sieht man auch in der PRTG-Übersicht sofort, welche Push-Sensoren gerade nicht senden:

Auch wenn noch nicht alles perfekt ist, ist der Push-Sensor ein wichtiger Weg neue Werte in PRTG zu integrieren.

Der HTTP-Push-Sensor ist schon ein sehr interessanter Sensor für die aktive Meldung von Systeme an PRTG. Allerdings sollte vielleicht der Defaults Status bei fehlenden Daten auf "Unknown" gehen und Value-Typ neben Integer und Float auch noch die Unterscheidung nach Absolut und Differenziell erlauben. Auch wäre die Auswahl  von "Mittelwert/Min/Max/Extremwert" wünschenswert. So könnten Geräte sofort einen "Ausschlag" senden, der dann nicht im Mittelwert untergeht.

HTTP-Push und Sicherheit

Soweit ich gesehen habe, kann der HTTP-PushSensor seitens PRTG nur "unverschlüsselt" kommunizieren. Insofern ist es durchaus möglich, dass jemand auf der Leitung "mitschneidet" und so die URL und auch das Token erhält. Er kann über den Weg dann eigene "falsche" Daten in das System mit einspeisen. Je nach dem, welche "Actions" Sie in PRTG dann hinterlegt haben, kann etwas ungewolltes passieren.

Aus Sicherheitsgründen sollten Sie den Weg über HTTPPush nur auf gesicherten geschlossenen Netzwerken wählen.

Nun wäre der Wechsel auf HTTPS eine Option aber auf der anderen Seite gibt es gerade viele kleine Geräte, die gerade kein SSL können. Teilweise weil es einfach keine Libraries gibt oder die CPU oder Speicher das nicht hergeben (z.B. Arduino oder ESP8266 SoC). Oft ist hier aber sogar HTTP schon zu "fett".

Aktuell gibt es das noch nicht aber statt einem HTTP-Push könnte man ja auch einen TCP-Push oder sogar UDP-Push bereitstellen. Damit das dann aber auch sicher ist, könnte man ja ein "einfaches Protokoll" dazu verwenden. Der Client verbindet sich mit dem PRTG-Server und bekommt ein asynchrones Einmalkennwort übermittelt. Der Sensor verschlüsselt seine Daten mit diesem Kennwort und nur der PRRG-Server hat quasi den "private Key" dazu. Ein anderes Verfahren wäre ein Zufallskennwort zu nutzen, welches der Client zusammen mit seinem Token zur Verschlüsselung nutzt. Auch hier ist der Aufwand auf dem Client als auch dem Server geringer, da es kein vollwertiges SSL/TLS ist aber immer noch besser als unverschlüsselt.

HTTP hat natürlich den Vorteil, dass es auch Proxy-Tauglich ist und mit SSL/TLS bewährte Protokolle kennt. Allerdings scheiden die kleinsten Netzwerkteilnehmer damit oft aus.

Interessant ist aber schon die Verschlüsselung der Daten selbst z.B. nach Diffie-Hellmann.

Diese relativ einfachen Operationen sollten auch mit Mini-Rechnern möglich sein.

Wenn das schon nicht geht, dann wäre ein "Rolling Code"-Mechanismus durchaus auch interessant. Als eine mit jeder Verbindung zu ändernden Nummer, ähnlich den RSA-Tokens. Man müsste nur einen Startwert oder einen Device-spezifischen Code hinterlegen und beide rechnen für sich die gleiche Nummer. Da Datagramme ja verloren gehen können, muss der Empfänger im schlimmsten Fall einen zweiten Code abwarten, um wieder InSync zu sein.

HTTP-Push mit MSTask

Es gibt viele schöne Auswertungen, die am Ende einen Status oder numerische Antworten liefern. Das Problem dabei ist aber, dass diese Auswertungen manchmal bestimmte Laufzeitumgebungen benötigen oder an sich relativ lange dauern. Bei PRTG wird normal immer nur die PRTG-Probe aktiv und damit liegt auch die Last auf der Probe. Wenn dann die Abfrage der Daten von der Probe auf dem Zielsystem noch viel Netzwerklast produziert oder eine langsamere WAN-Verbindung dazwischen ist, dann kann man nur eine Probe auf dem Zielserver installieren. Das ist nicht sonderlich schwer, aber in der Hierarchie ist eine Probe natürlich weiter oben angesiedelt als ein Device unter einen Probe.

WMI-Abfrage, Exchange Messagetracking-Auswertungen und andere Dinge kosten Zeit, CPU und Speicher. Interessant ist hier, dieses Skript direkt auf dem Server selbst ausführen zu lassen. für die Meldung an PRTG gibt es nun drei Wege

  1. Ablegen als Datei und der "PRTG File Content Sensor" liest ein
    So ein Skript könnte das Ergebnis einfach als Datei ablegen, die dann vom "PRTG File Content Sensor" eingelesen und auf einen String überprüft wird.
  2. Ablegen als Datei und ein "PRTG Custom Sensor" liest ein
    Pfiffiger sehe ich ein Skript, welches als Ausgabe das gleiche Format nutzt, wie ein Custom Sensor das direkt zurück geben würde. Dann kann ein Custom Sensor in PRTG die Datei sehr einfach "einlesen". Quasi eine CMD-Box mit einem einfachen "type <datename>". So könnte man auch mehrere Kanäle erlauben. Leider macht das PRTG noch nicht alleine
  3. HTTP-Push
    Mit dem HTTP-Push-Sensor und insbesondere dem "HTTPS- Push Advanced Server" kann das analysierende Skript aber auch direkt die Daten zum PRTG melden. Dann kostet es fast keine Last auf der PRTG-Probe

Hier ist die letzte Option besonders interessant, um die Daten per HTTP an PRTG zu senden. Das ist mit Powershell besonders einfach, wie folgende Beispiel dokumentiert:

$prtgresult = '<?xml version="1.0" encoding="UTF-8" ?>
<prtg>
   <result>
      <channel>Demo Minimum Example</channel>
      <value>3.2</value>
      <float>1</float>
   </result>
</prtg>'

$Answer=Invoke-Webrequest `
   -method "GET" `
   -URI ("http://192.168.100.59:5050/12345?content=$prtgresult")
if ($answer.Statuscode -ne 200) {
   write-warning "Request to PRTG failed"
   exit 1
}

Damit ist die Tür offen, um mit beliebigen Skripten, die z.B. durch den Taskplaner direkt auf den Server ausgeführt werden, Daten zu sammeln und an PRTG zu übergeben.

Aktuell habe ich noch kein Skript für diesen Zweck aufgesetzt. Diese Option halte ich mir aber offen.

HTTPPush mit Exchange

Um die Leistungsfähigkeit von HTTPPush exemplarisch zu zeigen, habe ich hier ein ganz triviales Skript, welches aus dem MessageTracking ein paar Statistiken ermittelt und per HTTPPush an enien Server sendet

write-host "PRTG Exchange Messagetracking"
 
[long]$ndrcount=0
[long]$incount =0
[long]$insize =0
[long]$outcount =0
[long]$outsize =0
 
 
set-psdebug -strict
 
write-host " Loading Messagetracking files"
get-messagetrackinglog `
   -resultsize unlimited `
   -start (get-date).addminutes(-5) `
| % {
   if ($_.sender -eq "") {
      write-host "NDR Found"
      $ndrcount++
   }
   if ($_.source -eq "Storedriver" -and $_.eventid -eq "deliver") {
      write-host "IN Mail"
      $incount++
      $insize += $_.totalbytes
   }
   elseif ($_.source -eq "SMTP" -and $_.eventid -eq "SEND" -and $_.connectorid -ne "Intra-Organization SMTP Send Connector") {
      write-host "OutMail"
      $outcount++
      $outsize += $_.totalbytes
   }
}
 
$prtgresult = '<?xml version="1.0" encoding="UTF-8" ?>
<prtg>
   <result>
      <channel>NDR Count</channel>
      <value>'+$ndrcount+'</value>
      <float>0</float>
   </result>
   <result>
      <channel>Anzahl eingehende Mail</channel>
      <value>'+$incount+'</value>
      <float>0</float>
   </result>
   <result>
      <channel>KBytes eingehend</channel>
      <value>' + [math]::round($insize/1024) + '</value>
      <float>0</float>
   </result>
   <result>
      <channel>Anzahl ausgehende Mail</channel>
      <value>'+$outcount+'</value>
      <float>0</float>
   </result>
   <result>
      <channel>KBytes ausgehend</channel>
      <value>' + [math]::round($outsize/1024) + '</value>
      <float>0</float>
   </result>
</prtg>'


#$prtgresult 

write-host "Sending Data"
$URL = "http://prtg.msxfaq.net:5050/12345678?content=$prtgresult"
$httprequest=[system.Net.HttpWebRequest]::Create($URL);
$data = $httprequest.getresponse();
$stat = $data.statuscode;
$data.Close();
# no errorhandling here
write-host "done"

Das Skript muss natürlich in Exchange PowerShell gestartet werden und enthält kein Logging, kein Alerting und auch keinen Taskplaner. Es soll als Muster aber zeigen, wie einfach per Skript ein paar Statistiken (Anzahl NDRs, eingehende und ausgehende Mails mit Anzahl und Größe) erfasst und an PRTG gemeldet werden können.

HTTP-Push mit IoT und CURL

Kennen Sie NodeMCU und die Programmierung mit LUA?. Wenn nein, dann sollten sie mal einen Blick auf NodeMCU und andere "IoT-Devices" richten. Diese Geräte nutzen natürlich kein Windows, so dass die Installation einer PRTG-Probe nicht möglich ist. Aber die Geräte sind auch nicht immer "wach" und mit einer festen IP-Adresse versehen, sondern haben eine dynamische IP-Adresse, verbergen sich hinter einem NAT-Router und wachen nur alle paar Minuten auf um ihren Status zu melden. Damit scheidet auch die aktive Abfrage durch eine Probe auf einem anderen System aus. Für diese Fälle ist ein HTTP-Push-Sensor einfach genial.

Eine entsprechende Seite auf Basis von NodeMCU und PRTG ist in Vorbereitung.

HTTP-Push mit Unix (CURL und CronTab)

Viele IoT Systeme nutzen im Innersten ein UNIX-Derivat und meist ist CURL verfügbar, ein Kommandozeilen-Tools zum Abfragen von URL. Wie ich auf SSH-Sensor ist ein HTTP-Push-Sensor auch eine Option für Systeme, die kein SSH können oder dürfen. Hier ein Beispiel eines Aufrufs um einen Wert per sysctl zu lesen und per curl an PRTG zu senden.

Beachten Sie, dass ein "?" ein Platzhalter ist und ein & als Verkettung von Befehlen gilt. Sie müssen diese Zeichen in der URL entsprechend ein "\" voranstellen. Der unter Windows liebgewonnene Backslash "\" muss aber zu einem "/" werden. Für einen Start mit CURL als Task sollten sie die Pfade absolut angegeben.

Ein Beispielskript könnte wie folgt aussehen:

#!/bin/sh
 
wert=$(sysctl -n dev.amdtemp.0.core0.sensor0``| tr -d C)
/usr/local/bin/curl http://prtg.example.com:5050/temp-pfsense\?value=$wert\&text=OK 

Das Skript müssen Sie nur noch per CRON regelmäßig starten. Folgender Eintrag startet einen Echo alle 5 Minuten

*/5 * * * * /home/prtg/push.sh

Eventuell müssen Sie nach Änderungen den Crontab neu starten.

/etc/init.d/crond restart

Sie müssen dann nur ein paar Durchläufe abwarten, bis PRTG die Daten nach und nach als Grafik aufbauen kann:

Was mir fehlt

Damit die Story aber perfekt wird, wäre es aus meiner Sicht sehr nützlich, wenn man PRTG über die XML-Datei nicht nur die Werte übergeben könnte, sondern auch den Zeitpunkt der Messung. So könnte ein Gerät auch nach einer Verbindungsunterbrechung die zwischengespeicherte Daten nachreichen.

Aktuell protokolliert PRTG die erhaltenen Daten immer als "Echtzeit", d.h. der Zeitpunkt des Empfangs ist auch der Zeitpunkt im Diagramm. Damit scheidet jede Möglichkeit aus, Daten von früher nachträglich einzuspeisen. für den Client ist es beim HTTP-Request kein Problem zu erkennen, dass die Versendung nicht erfolgreich war. Es kommt dann einfach kein "200 OK" von PRTG zurück. für jeden etwas pfiffigen Programmierer sollte es aber kein Problem sein, die zu meldenden Werte irgendwo temporär zu speichern und einfach beim nächsten Versuch den Request zu wiederholen.

Dazu müsste aber PRTG den Zeitstempel nicht anhand des aktuellen Empfangszeitpunkts festmachen, sondern eben aus den Nutzdaten extrahieren.

Weitere Links