Öffnet in einem neuen Tab

Linux mit PRTG überwachen: SSH-Key, v2-Sensoren und drei praktische Skripte

Linux-Server sind in PRTG-Umgebungen oft die Stiefkinder: SNMP halb konfiguriert, ein paar Ping-Sensoren und bei Docker-Hosts ein TLS-Port, den keiner mehr pflegt. Dabei lässt sich Linux mit PRTG überwachen, ohne dafür eine komplizierte Monitoring-Struktur aufzubauen.

Unser Ansatz für ein zuverlässiges Linux-Monitoring mit PRTG: ein eigener Monitoring-User, ein SSH-Key, die aktuellen v2-Sensoren von PRTG und einige Skripte für alles, was die Standardsensoren nicht abdecken.

In diesem Erfahrungsbericht zeigen wir, wie wir unseren Standard für das PRTG-Linux-Monitoring neu aufgebaut haben – inklusive Docker-Monitoring über SSH.

PRTG Dashboard für Linux Monitoring

Linux mit PRTG überwachen: Warum wir SSH statt SNMP nutzen

SNMP auf Linux funktioniert. Aber es kostet: Auf jeder VM einen snmpd konfigurieren, Community oder v3-User pflegen, MIBs für alles, was über Standard-Metriken hinausgeht. Und sobald man etwas Eigenes messen will – Zombie-Prozesse, Docker-Container, das Ablaufdatum der Distribution – ist SNMP am Ende.

SSH ist auf jeder Linux-VM schon da. PRTG bringt seit einigen Versionen die SSH-v2-Sensoren mit (Meminfo, Load Average, Disk Free, INodes Free, Script), die stabiler sind als ihre Vorgänger und auch auf der Multi-Platform Probe laufen. Und mit dem SSH Script v2 lässt sich alles messen, was ein Bash-Skript ausgeben kann. Kein Agent, kein zusätzlicher Port, ein User, ein Key.

Der Monitoring-User für PRTG unter Linux

Zuerst legen wir den Monitoring-User an:

sudo useradd -m -s /bin/bash prtg
sudo mkdir -p /home/prtg/.ssh

Bevor der Public Key hinterlegt werden kann, muss zunächst ein SSH-Schlüsselpaar erstellt werden. Wie Sie einen SSH-Key erstellen und einrichten, zeigen wir in diesem Beitrag.

Anschließend wird der Public Key für den Monitoring-User hinterlegt:

echo "ssh-rsa AAAA… prtg-monitoring" | sudo tee /home/prtg/.ssh/authorized_keys > /dev/null
sudo chmod 700 /home/prtg/.ssh && sudo chmod 600 /home/prtg/.ssh/authorized_keys
sudo chown -R prtg:prtg /home/prtg/.ssh

Die v2-Sensoren lesen /proc, rufen df und uptime auf – dafür braucht niemand sudo. Wer später Docker überwachen will, bekommt eine eng gefasste sudoers-Regel, dazu unten mehr.

PRTG per SSH-Key mit Linux verbinden

Beim Key gibt es eine Falle, über die fast jeder einmal stolpert: PRTG will einen RSA-Key im PEM-Format ohne Passphrase. Moderne ssh-keygen-Versionen erzeugen standardmäßig das neuere OpenSSH-Format, das PRTG trotz gegenteiligem Hinweistext im Dialog nicht liest. Also:

ssh-keygen -t rsa -b 4096 -m PEM -N "" -f ~/.ssh/prtg_linux

Der Private Key kommt in PRTG in die Anmeldedaten für Linux/Solaris/macOS – am besten auf Gruppenebene, damit alle Geräte darunter ihn erben. Der Public Key auf die VMs. Und ein Test vom Admin-Rechner aus (ssh -i ~/.ssh/prtg_linux prtg@host uptime), bevor man in PRTG nach Fehlern sucht.

PRTG Linux Monitoring: Diese Sensoren bilden unsere Basis

SSH Meminfo v2, SSH Load Average v2, SSH Disk Free v2 und SSH INodes Free v2. Die ersten drei erklären sich selbst; der vierte ist der, den alle vergessen, bis /var voll ist, obwohl df noch 40 % frei zeigt – ein Mailserver oder ein Log-Verzeichnis mit Millionen kleiner Dateien braucht keine Blöcke, sondern Inodes.

Dazu Ping v2 und, je nach Rolle der VM, ein Port-v2-Sensor auf den Dienst, den sie anbietet. Das ist die Grundausstattung. Sie deckt vielleicht 70 % dessen ab, was man über eine Linux-VM wissen will.

Eigene Linux-Werte mit dem PRTG SSH Script v2 überwachen

Für den Rest gibt es den SSH Script v2. Er führt ein Skript auf dem Zielsystem aus und erwartet JSON zurück. Klingt einfach – und hat uns einen halben Vormittag gekostet, weil das PRTG-Handbuch auf das falsche JSON-Format verlinkt.

Wir hatten ein altes Skript für den klassischen SSH-Script-Sensor: eine Textzeile 0:3:Active Users, fertig. Der v2 will JSON. Das Handbuch verweist auf das seit Jahren bekannte „Advanced“-Format mit prtg/result-Struktur. Wir bauten das nach, und der Sensor antwortete:

Das abgefragte Feld „version“ ist leer.

Der v2-Sensor validiert gegen ein eigenes Schema, Version 3, das nur in einem Knowledge-Base-Artikel von Paessler dokumentiert ist. Es ist deutlich sauberer als das alte Format:

{
  "version": 3,
  "status": "warning",
  "message": "2 Benutzer angemeldet (Warnschwelle 1)",
  "channels": [
    { "id": 10, "name": "Active Users", "type": "integer", "kind": "count",
      "value": 2, "limits": { "warning": { "upper": 1 } } }
  ]
}

status steuert den Sensorstatus direkt (ok, warning, error), message den Text, und jeder Kanal hat eine eindeutige id ab 10, einen type (integer, float, counter, lookup) und eine Einheit kind (count, percent, size_bytes_memory, time_seconds …). Limits werden beim ersten Scan in den Kanal übernommen und sind danach in PRTG editierbar.

Was man außerdem wissen muss, weil es nirgends prominent steht:

  • Ablageort: /opt/paessler/share/scripts, nicht mehr /var/prtg/scripts. Das Skript muss ausführbar sein, sonst erscheint es nicht in der Auswahlliste.
  • Parameter kommen per stdin, nicht als $1. Ein Skript, das nur $1 liest, meldet „Parameter fehlt“, obwohl das Feld in PRTG gefüllt ist. Robust ist: $1 lesen, wenn leer read -t 2 von stdin.
  • Minimaler PATH. PRTG startet das Skript ohne Login-Shell. Alles, was nicht in /usr/bin liegt, mit absolutem Pfad aufrufen. Der beste Test ist deshalb nicht ./script.sh, sondern: sudo -u prtg env -i /bin/bash --noprofile --norc -c '/opt/paessler/share/scripts/script.sh'.
  • Counter-Kanäle (PRTG rechnet die Rate) erlauben nur Grundeinheiten. size_bytes-per-second_disk an einem Counter ergibt ein Schema-Fehler – der aber immerhin Kanal, Feld und Grund nennt. Der alte Sensor hätte „Keine Daten“ gezeigt.

Drei Skripte für unser Linux-Monitoring mit PRTG

Linux Health

Linux Health liefert, was die Basissensoren nicht liefern: Zombie-Prozesse (ein Frühwarnsignal für hängende Dienste), Swap-Nutzung, Load pro Kern in Prozent (4.0 auf einem 8-Kerner ist harmlos, auf einem 2-Kerner ein Problem), den vollsten Mountpoint statt nur /, offene TCP-Verbindungen, Uptime, angemeldete Benutzer. Zwei Details, die den Unterschied machen: RAM wird über MemAvailable gerechnet, nicht MemFree – letzteres ist wegen des Page-Cache fast immer erschreckend klein und fast nie ein Problem. Und die Benutzer werden mit who | wc -l gezählt, nicht mit w | head -1 | awk '{print $6}', weil die Spaltenposition von w je nach Locale und Uptime-Format wandert.

Linux Health Monitoring mit PRTG SSH Script v2
Der Linux-Health-Sensor zeigt unter anderem Auslastung, Arbeitsspeicher, Prozesse, Swap und Uptime.

OS Lifecycle

OS Lifecycle meldet Distribution, Tage bis End-of-Life, ausstehende Sicherheitsupdates und Reboot-Bedarf. Die EOL-Daten stehen als Tabelle im Skript; unbekannte Versionen ergeben eine Warnung statt Stille. Der Sensor hat sich beim allerersten Lauf bezahlt gemacht: Er meldete Debian 12, die installierten Docker-Pakete hießen aber ~bullseye. Das Linux-System war von Debian 11 auf Debian 12 gehoben worden, die Repo-Datei von Docker zeigte noch aufs alte Release. Seitdem installierte apt Bullseye-Builds auf einem Bookworm-System – läuft, weil Docker statisch gelinkt ist, will man aber nicht.

Linux Lifecycle Monitoring mit PRTG für Updates und End of Life

Docker Health und Docker Container – dazu der nächste Abschnitt, weil Docker eigene Regeln hat.

Docker über SSH statt über Port 2376

PRTG hat einen nativen Sensor „Docker Container Status“. Er braucht den Docker-Daemon per TCP mit TLS-Zertifikaten auf Port 2376 – also eine eigene PKI, einen offenen Port und Konfiguration in der systemd-Unit. Wir hatten das jahrelang im Einsatz. Und genau diese PKI lag unter /root/, wo sie beim Aufräumen umbenannt wurde, woraufhin dockerd zwei Wochen lang nicht startete.

Der SSH-Weg braucht nichts davon. Der Monitoring-User bekommt eine sudoers-Regel für vier lesende Befehle:

Cmnd_Alias DOCKER_RO = /usr/bin/docker ps, /usr/bin/docker ps *, /usr/bin/docker images, /usr/bin/docker images *, /usr/bin/docker system df, /usr/bin/docker system df *, /usr/bin/docker stats *, /usr/bin/docker inspect *
Defaults:prtg !requiretty
prtg ALL=(root) NOPASSWD: DOCKER_RO

Warum nicht einfach die Gruppe docker? Weil die faktisch Root-Rechte bedeutet – wer den Socket hat, kann einen Container mit / als Volume starten. Die sudoers-Regel erlaubt genau die vier Befehle und sonst nichts. Wichtig: Befehle mit und ohne Argumente eintragen; ob docker ps * auch docker ps ohne Argument matcht, hängt von der sudo-Version ab.

Damit laufen zwei Skripte:

Docker Health

Docker Health zeigt die Host-Übersicht: Container nach Zustand (running, exited, restarting, paused, unhealthy), Images, dangling Images, Plattenverbrauch. Das ist der Sensor, der „7 Container, 0 laufen“ sagt – was ein Container-Sensor nie kann, weil er nur seinen einen Container kennt.

Docker Health Monitoring mit PRTG über SSH
Docker Health in PRTG: Übersicht über Container-Zustände, Images und Speicherverbrauch.

Docker Container

Docker Container nimmt einen Containernamen als Parameter und liefert pro Container: Status, Exit-Code, Restart-Zähler, Uptime, CPU, RAM, PIDs, Netz- und Disk-I/O. Und den Healthcheck-Status – den der native Paessler-Sensor gar nicht ausgibt, obwohl es die aussagekräftigste Information ist, die ein Container liefern kann: „läuft“ heißt nichts, „healthy“ heißt etwas. Referenziert wird per Name statt Container-ID; wird der Container neu gebaut, bleibt der Sensor gültig.

Eine Falle für alle, die es nachbauen: Docker-Templates sind strikt. {{.State.Health.Status}} bricht bei Containern ohne Healthcheck mit „map has no entry for key Health“ ab. Der sichere Weg ist {{with index .State "Health"}}{{.Status}}{{else}}none{{end}}.

Was unser PRTG Linux Monitoring direkt gefunden hat

Ein Container in einer Restart-Schleife. Ursache: Sein Bind-Mount zeigte auf einen Ordner, der nicht mehr existierte. Und hier steckt das fieseste Docker-Verhalten, das wir kennen: Docker legt fehlende Bind-Mount-Pfade stillschweigend als leere Verzeichnisse an. Ein gelöschter Projektordner fällt nicht beim Start auf, sondern erst, wenn die Anwendung im Container ihre Dateien sucht. Bei einem Datei-Mount (index.html) entsteht sogar ein Verzeichnis mit dem Dateinamen. Compose verweigert das inzwischen; alte docker run-Container nicht.

Die Rettung war elegant: Der Inhalt war im Image eingebacken, der Bind-Mount verdeckte ihn nur. docker create aus dem Image, docker cp zurück auf den Host, docker rm – und der Container lief wieder. Dazu eine Restart-Policy (docker update --restart unless-stopped), damit das nach dem nächsten Daemon-Neustart nicht wieder passiert.

PRTG für mehrere Linux-Server ausrollen

Die erste VM ist Handarbeit: User, Key, Skripte, Sensoren anlegen, grün bekommen. Aus dieser VM wird eine Gerätevorlage. Die restlichen VMs bekommen per Auto-Discovery mit dieser Vorlage dasselbe Set – die Docker-Skripte nur dort, wo Docker läuft. Die Anmeldedaten liegen auf der Gruppe, die Skripte in einem Ordner, der sich mit scp oder Ansible verteilen lässt.

Linux mit PRTG überwachen: unsere Kurzfassung

Wer Linux mit PRTG überwachen möchte, kann bereits mit wenigen Komponenten eine solide Basis schaffen:

  • SSH statt SNMP für Linux: ein User, ein Key, kein Agent, kein Port.
  • RSA-Key im PEM-Format (-m PEM), sonst liest PRTG ihn nicht.
  • Vier v2-Sensoren als Basis, INodes nicht vergessen.
  • SSH Script v2 braucht JSON-Schema v3, Skripte in /opt/paessler/share/scripts, Parameter per stdin, absolute Pfade. Das Handbuch hilft nicht, die Paessler-KB schon.
  • Drei Skripte decken den Rest ab: Health, Lifecycle, Docker.
  • Docker per SSH mit enger sudoers-Regel statt TLS-Port und PKI – und mit Healthcheck.
  • Docker legt fehlende Mount-Pfade leer an. Restart-Policies setzen, Bind-Mounts prüfen.

Und ein Satz, der über allem steht: Ein Sensor misst, was er misst – nicht, was sein Name verspricht. Der Container-Sensor, der jahrelang einen toten Container beobachtete, das Bullseye-Paket auf Bookworm, der Mount-Pfad, der nur noch aus einem leeren Ordner bestand: Erst der Blick auf das, was tatsächlich abgefragt wird, macht so etwas sichtbar. Genau dafür lohnt sich der Aufwand, die Skripte einmal richtig zu bauen.

Die vollständigen Skripte stellen wir auf Anfrage zur Verfügung.