Individuelle Lösungen zur Systemüberwachung und -kontrolle

Aus LinuxUser 12/2015

Individuelle Lösungen zur Systemüberwachung und -kontrolle

© Lightwise, 123RF

Fest im Blick

Überwachungstools von der Stange bieten oft viel zu viele Funktionen oder gerade nicht das Gewünschte. Mithilfe konventioneller Shellskripte bauen Sie sich individuelle Überwachungsroutinen aber leicht selbst.

Egal, ob Sie eine Heizungsanlage, einen Webserver, Datenbanksysteme, Netzwerkverbindungen, Benutzer, Lüfter oder die Rechnertemperatur automatisch überwachen und steuern möchten: Mit einfachen Shell-Routinen funktioniert das in der Regel zuverlässig und schnell. Einmal erstellte Skripte lassen sich dabei leicht für unterschiedliche Distributionen und Situationen anpassen.

Doch die Überwachung will durchdacht sein: Im Falle der eingangs erwähnten Überwachung eines Webservers genügt es nicht, nur zu prüfen, ob der Dienst läuft – schon der Fragestellung fehlt jegliche Präzision. Läuft die Hardware? Um das festzustellen, reicht ein schlichtes ping. Eine positive Antwort bedeutet aber noch lange nicht, dass der Webserver-Daemon funktioniert. Dafür müssten Sie zum Beispiel lokal auf dem Server den Prozessstatus abfragen (ps -C Dienst oder etwa service Dienst status).

Doch damit wissen Sie immer noch nicht, ob Nutzer die Daten des Webservers auch wirklich abrufen können. Dies müssten Sie regelmäßig manuell per Browser oder besser automatisch mit einem Kommandozeilenwerkzeug kontrollieren – und zwar idealerweise von außerhalb der eigenen geschützten Netzwerkinfrastruktur. Andernfalls riskieren Sie, sich durch Fehlinterpretationen in falscher Sicherheit zu wiegen – wenn etwa ein Router nicht mehr funktioniert.

Sensoren

Beim Überwachen von Programmausführungen gilt es, auf die Exit-Codes zu achten, die Terminalanwendungen und Kommandos in der Regel nach dem planmäßigen oder unplanmäßigen Ende des Programms ausgeben. Der Wert 0 steht dabei in der Regel für einen erfolgreichen Durchlauf, andere Codes für einen mehr oder weniger gravierenden Fehler. Die Tabelle “Prüfwerkzeuge” stellt eine kleine Auswahl von gängigen Tools zur Systemüberwachung vor.

Prüfwerkzeuge

Prüfziel Werkzeug
Erreichbarkeit von Webseiten httping(1)
Datenbank-Shellclient für PostgreSQL-RDBMS psql
Erreichbarkeit von Rechnern ping
Namensauflösung host
Angemeldete Benutzer users
Dienstestatus (SysVinit) /etc/init.d/Dienst status
Dienstestatus (Systemd) systemctl status Dienst
Plattenspeicherplatz df
Temperatur sensors
Lüfteraktivität sensors(2)
Portzugriffe netread(3)
(1) Paket httping; (2) Paket lm-sensors; (3) Paket netrw

Wie das Beispiel der Überwachung eines Webservers zeigt, verursacht das Monitoring in manchen Fällen ein wenig Aufwand (Abbildung 1). In diesem Fall läuft idealerweise die Überwachung nicht innerhalb des Hauses, sondern außerhalb der eigenen IT-Infrastruktur, sodass Ausfälle nicht auch gleich das Überwachungssystem lahmlegen. Damit decken Sie aber auch fast alle Fälle von Störungen ab: Websperren, Überlastungsangriffe, allgemeine Netzüberlastung und selbst den Fall einer physikalischen Netzabtrennung durch den sprichwörtlichen Bagger.

Abbildung 1: Ablaufschema der Funktionsüberwachung eines Webservers.

Abbildung 1: Ablaufschema der Funktionsüberwachung eines Webservers.

Als Reaktion könnten Sie (automatisch) das Anfahren einer redundanten Anlage an anderer Stelle beziehungsweise mit anderer Anbindung an das Internet veranlassen. Listing 1 zeigt einen Ansatz, der als erste Reaktion zur Fehlereingrenzung bereits weitere Fragen abklärt (DNS-Problem, Netzwerkanbindung und mehr). Das Skript lässt sich bei Bedarf sehr einfach erweitern. Beachten Sie dabei die Stolperfalle, dass manche Internetanbieter beim Aufruf einer nicht erreichbaren Internetseite versuchen, Ihnen mit einer Navigationshilfe unter die Arme zu greifen. Werten Sie hier unbedingt den HTTP-Statuscode mit aus.

Listing 1

#! /bin/sh
HOST=www.example.com
IP=93.184.216.34
while true; do
  # Webseite abrufen, Ausgabe in Variable
  B=$(httping -G -g $HOST -c 1 -s -m)
  # Exit-Code in Variable speichern
  A=$?
  # Ausgabe von httping aufteilen
  C=$(echo $B  | cut -d \  -f1)
  D=$(echo $B  | cut -d \  -f2)
  # Ausgabe der Variablen
  echo "Exit-Code: $A"
  echo "STATUS: $C"
  # Namensaufloesung pruefen
  if [ "$C" = "-1" ]; then
    host $HOST
    # Exit-Code speichern ...
    NA=$?
    # ... und auswerten
    if [ $NA = 0 ]; then
      echo "Namensaufloesung ok"
    else
      echo "Fehler bei Namensauflösung"
      # Erreichbarkeit per IP-Adresse?
      ping -c 1 -q $IP
      # Exit-Code speichern ...
      E=$?
      # ... und auswerten
      if [ $E -eq 0 ]; then
        echo "Rechner im Netzwerk erreichbar"
      else
        echo "Rechner nicht im Netzwerk erreichbar"
      fi
    fi
  fi
  # Hinweis, falls Seite nicht abrufbar
  if [ $D -ne 200 ]; then
    echo "Seitenfehler $D"
  fi
  sleep 15
done

Das im Skript ausgeführte Kommando httping (meist im Paket httping) ruft die angegebene Webseite ab und zeigt zusätzliche Informationen an, wie etwa die Latenz (siehe Kasten “Webserver anpingen”). So lässt sich ein Webserver sehr leicht auf seine Funktion hin überwachen. Das gezeigte Systemüberwachungsskript stellt die Sensorikseite der Überwachung dar, üblicherweise ist die Reaktionsseite in ein zweites Skript ausgelagert.

Webserver anpingen

Das Programm Httping hilft, den Zugriff auf einen Webserver zu prüfen. Optional ermittelt es auch das Antwortzeitverhalten, sofern Sie die Verbindung nicht über einen Proxyserver führen oder mittels der Option -G den kompletten Seiteninhalt übertragen lassen; das würde die Antwortzeiten verfälschen. Der grundsätzliche Aufruf erfolgt in der Form httping -g URL, wobei Sie mit der Option -p Port einen anderen Port also den üblichen Port 80 angeben.

Httping erzeugt auf Wunsch neben den Exit-Codes (0 = Funktion, 127 = Fehler) noch weitere Ausgaben wie die Antwortzeit, die im Fehlerfall den Wert -1 annimmt. Einer Variable übergeben, lösen Sie auf Basis dieser Ergebnisse entsprechende Alarme oder Reaktionen aus. Zum besseren Verständnis der Funktion starten Sie das kleine Beispielskript aus Listing 2 auf einem Rechner. Die entsprechenden Ausgaben zeigt Listing 3.

Der erste Aufruf zielt auf eine allgemein funktionierende Webseite. Dabei zeigt Httping die Antwortzeit und den HTTP-Statuscode 200 an. Richten Sie Httping auf eine funktionierende Domain, aber eine nicht existierende Webseite, gibt das Prüfwerkzeug den klassischen 404-Fehler mit der Antwortzeit -1 aus. Gibt es schon die Domain nicht, dann leitet in unserem Beispiel der Internetanbieter auf eine eigene Navigationshilfe mit integrierter Suchfunktion weiter. Daher meldet Httping auch nicht ein “Resolving beischpiel.de failed”, sondern gibt mit 302 den entsprechenden Status-Code für die Umleitung aus.

Listing 2

#! /bin/sh
echo "Diese Webseite funktioniert:"
httping -g http://www.example.com -c 1 -s -m
echo "-------------------------------------------------"
echo "Domain vorhanden, aber Seite nicht gültig:"
httping -g http://example.com/seite-gibts-nicht.html -c 1 -s -m
echo "-------------------------------------------------"
echo "Domain nicht vorhanden, Umleitung durch Provider:"
httping -g http://beischpiel.com -c 1 -s -m

Listing 3

$ ./listing2.sh
Diese Webseite funktioniert:
206,761122 200
-------------------------------------------------
Domain vorhanden, aber Seite nicht gültig:
-1 404
-------------------------------------------------
Domain nicht vorhanden, Umleitung durch Provider:
-1 302

Datenbanken überwachen

Neben Webservern bilden Datenbanken einen weiteren wichtigen Baustein einer IT-Infrastruktur, den es ebenfalls zu überwachen gilt. Sehr häufig kommen hier MySQL, MariaDB oder PostgreSQL zum Einsatz; auf Letzteres konzentrieren wir uns in diesem Beispiel. Zum Überwachen des Dienstes legen Sie einen eigenen Benutzer und für diesen eine Datenbank mit einer Tabelle darin an. Dadurch versetzen Sie das Shellskript in die Lage, die Abfrage automatisch vorzunehmen. Im Beispiel trägt die Datenbank den Namen waechter, in dieser findet sich die Tabelle wacht mit der Spalte zahl sowie ein Datensatz (Abbildung 2).

Abbildung 2: Einfache Datenbank für die Funktionskontrolle eines PostgreSQL-Servers.

Abbildung 2: Einfache Datenbank für die Funktionskontrolle eines PostgreSQL-Servers.

Der Shell-Client psql verwendet die klassischen Exitcodes 0 bei Funktion und 1 für einen Fehlschlag. Das Shellskript im Listing 4 unterscheidet nun, ob lediglich aus irgendeinem Grund die Daten nicht zugänglich sind oder der Dienst überhaupt nicht arbeitet. Abbildung 3 zeigt den Ablauf, wobei wir probehalber einmal die Daten löschten und das andere Mal den Dienst stoppten. Sofern das Skript auf dem gleichen Rechner läuft wie das relationale Datenbankmanagementsystem, können Sie auch andere Aktionen ausführen lassen.

Listing 4

#! /bin/sh
while true; do
  # Datum und Zeit in Variable legen
  ZEIT=$(date +%d.%m.%Y:%H:%M:%S)
  # Datenbankabfrage für Exit-Code-Gewinnung
  M=$(psql -q -d waechter -c "select * from wacht;")
  # Exitcode speichern und auswerten
  A=$?
  if [ $A -eq 0 ]; then
    echo "$ZEIT Datenbank arbeitet"
  elif [ $A -eq 1 ]; then
    echo "$ZEIT Daten nicht gefunden"
  elif [ $A -eq 2 ]; then
    echo "$ZEIT Datenbank inaktiv"
  fi
  sleep 60
done

Abbildung 3: Ablauf der Prüfung eines PostgreSQL-Servers auf Funktion.

Abbildung 3: Ablauf der Prüfung eines PostgreSQL-Servers auf Funktion.

Dienste überwachen

Zahlreiche Dienste verrichten still und leise ihre Aufgabe im Hintergrund, ohne dass sie sich wie ein Web- oder Datenbankserver direkt ansprechen ließen. Die Verfügbarkeit eines solchen Dienstes lässt sich daher nicht so einfach mit einer Abfrage überprüfen. In diesen Fällen müssen Sie darauf vertrauen, dass der Dienst bei einem aktiven Prozess auch seine Aufgabe erfüllt.

Die Abfrage des Status erfolgt anhand der Beispiele aus der Tabelle “Dienstekontrolle”. Das einfachste Werkzeug für diese Aufgabe ist das Kommando ps. Mit dem Schalter -C Prozess beschränken Sie die Suche nach dem entsprechenden Prozess auf den angegebenen Namen (Listing 5). Die von Ps gelieferten Exit-Codes lassen sich gut in Skripten weiterverarbeiten. Alternativ greifen Sie auf die Ausgaben der per service-Kommando aufgerufenen Initskripte (Listing 6) oder – bei Distributionen mit Systemd – auf systemctl (Listing 7) zurück.

Dienstekontrolle

Methode Aufruf Exit-Codes
Prozessstatus, mit Angabe des Diensts ps -C Prozess 0 = existiert; 1 = existiert nicht
Initskript mit Option status service Startskript status keine, stattdessen individuelle Meldungen
Abfrage mit Systemctl systemctl status Dienst 0 = aktiv, 3 = deaktiviert
Kommunikation mit dem Dienst siehe Beispiele für Web- und Datenbankserver

Listing 5

$ ps -C ntpd
  PID TTY          TIME CMD
 1054 ?        00:00:01 ntpd
$ echo $?
0
# Dienst stoppen, hier via Systemd
$ sudo systemctl stop ntpd.service
$ ps -C ntpd
  PID TTY          TIME CMD
$ echo $?
1

Listing 6

$ service ntp status
 * NTP server is running
$ sudo service ntp stop
 * Stopping NTP server ntpd             [ OK ]
$ service status
 * NTP server is not running

Listing 7

$ systemctl status ntp
|- ntp.service - LSB: Start NTP daemon
   Loaded: loaded (/etc/init.d/ntp)
   Active: active (running) since Mo 2015-10-26 19:22:03 CET; 43s ago
[...]
$ echo $?
0
$ sudo systemctl stop ntp
$ systemctl status ntp
|- ntp.service - LSB: Start NTP daemon
   Loaded: loaded (/etc/init.d/ntp)
   Active: inactive (dead) since Mo 2015-10-26 19:23:04 CET; 4s ago
[...]
$ echo $?
3

Während Sie beim herkömmlichen SysVinit die Ausgaben des aufgerufenen Init-Skripts mit einigem Aufwand auswerten müssten, liefert der aktuelle Systemd handlichere Exit-Codes. Je nach Aufgabenstellung, Anforderungen und System kommen Sie bei der Überwachung eines Diensts mit einer der drei vorgestellten Methoden zum Ziel.

Auf Logins reagieren

Aus diesen Bausteinen realisieren Sie mit einfachen Mitteln kleine Skripte, die auf Ereignisse im System reagieren. So lassen sich beispielsweise Logins gut als Auslöser für Aktionen nutzen – etwa, um die abendlichen Diskussionen mit den Kindern zu umgehen, wenn diese zu lange am Computer sitzen. Mit dem Glockenschlag verbannen Sie sie dann, ob sie wollen oder nicht, automatisiert aus dem System.

Das Skript in Listing 8 ermittelt mithilfe von users die aktuell auf dem System angemeldeten Benutzer und filtert die Ausgabe mit grep. Damit erhalten Sie den Exit-Code 0 bei einem Treffer und 1 bei Fehlanzeige. Entsprechend des Ergebnisses und der aktuellen Zeit (untersagt sind die Stunden zwischen 21 und 7 Uhr) lässt das Skript den User simon im System oder wirft ihn kurzerhand hinaus (Abbildung 4).

Listing 8

#! /bin/sh
while true; do
  # Aktuelle Stunde ermitteln
  STUNDE=$(date +%H)
  # Ist Simon angemeldet?
  users | grep -q simon
  # Exitcode auswerten
  A=$?
  if [ $A -eq 0 ]; then
    # Simon ist angemeldet
    if [ $STUNDE -le 7 ]  || [ $STUNDE -ge 21 ]; then
    # vor 7 bzw. nach 21 Uhr
      killall -u simon
    fi
  fi
  sleep 60
done

Abbildung 4: Den Benutzer bei Überschreiten des Zeitfensters automatisch ausloggen.

Abbildung 4: Den Benutzer bei Überschreiten des Zeitfensters automatisch ausloggen.

Das Prinzip lässt sich auf Komfort- und Automatisierungsfunktionen übertragen. So starten Sie etwa mit einem leicht abgewandelten Skript (Listing 9) einen Webserver, sobald sich ein bestimmter Nutzer (im Beispiel jefe) anmeldet. In diesem Fall ist das Skript für den Einsatz auf einem Systemd-System abgestimmt, eventuell müssen Sie auch den Namen des Webserver-Diensts (im Beispiel httpd.service) anpassen.

Listing 9

#! /bin/sh
while true; do
  # Ist jefe angemeldet?
  users | grep -q jefe
  # Exitcode auswerten
  A=$?
  if [ $A -eq 0 ]; then
    # jefe angemeldet
    # Status des Webservers prüfen
    systemctl status httpd.service
    # Exitcode auswerten
    B=$?
    # Webserver bei Bedarf starten
    if [ $B -gt 0 ]; then
      systemctl start httpd.service
    fi
  else
    # jefe nicht angemeldet
    # Status des Webservers prüfen
    systemctl status httpd.service
    # Exitcode auswerten
    C=$?
    if [ $C -eq 0 ]; then
      # Webserver bei Bedarf beenden
      systemctl stop httpd.service
    fi
  fi
  sleep 60
done

Der Nutzer muss keine Kommandos eingeben oder Aktionen starten. Dabei müssen Sie nicht einmal Änderungen an den Home-Verzeichnissen der Benutzer vornehmen etwa in der ~/.profile oder ~/.bashrc) – es genügt eine aktive Sitzung. Mit diesem Vorgehen übertragen Sie wichtige Aufgaben, wie etwa den Start eines Diensts oder einer Datensicherung, auf unprivilegierte Benutzer. Dafür müssen Sie das Shellskript jedoch noch beim Hochfahren des Rechners automatisch aufrufen. Dabei gehen Sie je nach Init-System unterschiedlich vor.

Generell legen Sie das ausführbare Shellskript im Verzeichnis /usr/local/sbin ab. Bei älteren Systemen wie Debian 7 mit SysVinit kopieren Sie unter /etc/init.d die meist vorinstallierte Vorlage skeleton in eine neue Datei mit passendem Namen – im Beispiel webanmeldung. Anschließend bearbeiten Sie das Init-Skript nach Ihren Vorstellungen, speichern die Änderungen ab und machen die Datei mit chmod +x ausführbar. Mit update-rc.d webmeldung defaults aktivieren Sie sie für die üblichen Runlevel.

Arbeiten Sie auf einem Rechner mit Systemd, legen Sie entsprechend Listing 10 unter dem eventuell neu anzulegenden Verzeichnis /usr/local/lib/systemd/system eine neue Unit-Datei mit dem Namen webmeldung.service an und führen die Anweisungen aus Listing 11 aus. Diese verlinken die Anweisung im System und sorgen beim Booten für einen automatischen Start.

Listing 10

[Unit]
Description=Start Webserver bei Anmeldung jefe
Documentation=man:users(1)
[Service]
ExecStart=/usr/local/sbin/webmeldung.sh
IgnoreSIGPIPE=false
[Install]
WantedBy=multi-user.target

Listing 11

$ sudo systemctl enable webmeldung.service
Created symlink from /etc/systemd/system/multi-user.target.wants/webmeldung.service to /usr/local/lib/systemd/system/webmeldung.service.
$ sudo systemctl start webmeldung.service 
$ sudo systemctl status webmeldung.service
* webmeldung.service - Start Webserver bei Anmeldung jefe
   Loaded: loaded (/usr/local/lib/systemd/system/webmeldung.service; enabled; vendor preset: disabled)
   Active: active (running) since Di 2015-10-27 14:16:13 CET; 6s ago
[...]

Meldungen per E-Mail

Optional lassen Sie sich über wichtige Ereignisse per E-Mail informieren. Dafür benötigen Sie einen Mail-Transport-Agent (MTA) wie etwa Ssmtp [1] auf dem Rechner. Er leitet E-Mails über einen regulären SMTP-Server weiter, sodass die Server-Mails nicht gleich vom empfangenden E-Mail-Dienst als Spam aussortiert werden.

Im Listing 12 finden Sie ein einfaches Shellskript, das Sie über alle um 22 Uhr noch angemeldeten Benutzer per E-Mail informiert. Das Skript erstellt für diese Aufgabe die Hilfsdatei mail.txt, die ssmtp dann als Eingabe für die zu versendende E-Mail nutzt.

Listing 12

#!/bin/sh
EMPFAENGERADRESSE=papa@beispiel.com
ABSENDERADRESSE=kinderzimmer@heim.netz
while true; do
  stunde=$(date +%H)
  if [ $stunde -eq 22 ]; then
    echo "To: $EMPFAENGERADRESSE" > mail.txt
    echo "From: $ABSENDERADRESSE" >> mail.txt
    echo "Subject: Benutzerabfrage" >> mail.txt
    echo "" >> mail.txt
    users >> mail.txt
    ssmtp $EMPFAENGERADRESSE < mail.txt
    sleep 15
    #sleep 3600
  fi
done

Vor dem Start des Skripts müssen Sie Ssmtp jedoch noch einrichten. Dies geschieht über die Konfigurationsdateien ssmtp.conf (Listing 13) und revaliases (Listing 14) aus dem Verzeichnis /etc/ssmtp. Je nachdem, welchen E-Mail-Anbieter Sie ansprechen möchten, müssen Sie an dieser Stelle unterschiedliche Konfigurationen eintragen. Haben Sie Schwierigkeiten, die richtigen Angaben zu finden, hilft in der Regel eine Internetrecherche mit den Begriffen “Provider ssmtp” weiter.

Listing 13

root=papa@beispiel.com
mailhub=smtp.beispiel.com:25
hostname=Kinderzimmer
UseTLS=Yes
UseSTARTTLS=YES
AuthUser=Login für SMTP-Server
AuthPass=Passwort für SMTP-Server
FromLineOverride=NO

Listing 14

root:papa@beispiel.com:smtp.beispiel.com:25

Die Beispiele in den Konfigurationsdateien beziehen sich auf einen normalen Freemail-Anbieter. Zu Testzwecken versehen Sie den Aufruf von ssmtp im Shellskript mit der Option -v. Das Programm gibt sich so deutlich auskunftsfreudiger, sodass Sie Fehler bei der Übertragung schnell erkennen und die notwendigen Anpassungen vornehmen können.

Sicherheit

Achten Sie darauf, dass sich die Ssmtp-Konfigurationsdatei nur von Root oder demjenigen Benutzer einsehen lässt, in dessen Kontext Ssmtp ausgeführt wird. Entsprechende Hinweise zur Konfiguration liefert die Dokumentation der genutzten Linux-Distribution, wie zum Beispiel das Wiki von Arch Linux [2].

Ausblick

Die hier gezeigten Beispiele bilden nur einen Bruchteil der Möglichkeiten ab. Zum Erstellen von Skripten benötigen Sie keine großen Programmierkenntnisse, Erfahrungen mit Terminalanwendungen und einfachen Konstrukten wie While-Schleifen und If-Unterscheidungen genügen in der Regel. 

Der Autor

Harald Zisler beschäftigt sich seit den frühen 90er-Jahren mit FreeBSD und Linux. Er verfasst Artikel und Bücher zu Technik- und EDV-Themen. Kürzlich erschien die dritte Auflage seines Buchs “Computer-Netzwerke” beim Rheinwerk Verlag. Rund um den Themenbereich Linux und Datenbanken führt er auch Kleingruppenkurse durch.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 12/2015 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben