Samstag, 21. Januar 2017

Linux Monitoring: "dfmon"

Im letzten Post hatte ich anhand des "updmon"-Agenten beschrieben, wie mein Monitoring aufgebaut ist.
Hier gehe ich nun auf den weiterentwickelten Agenten "dfmon" ein, der den Plattenplatz meldet.
Patche brauche ich nur einmal am Tag. Aber der Platz auf den Platten sollte schon öfter gemessen werden.
Daher war im vorangegangenen Beitrag auch schon in der crontab zu sehen, daß alle 17 Minuten ein Lauf stattfindet.
-----------------------------------------------------------------
*/17 * * * * root /var/monitor/dfmon.sh
-----------------------------------------------------------------

Gemessen wird mit dem Befehl
"df -h"
der eine Ausgabe ähnlich dieser bringt:
------------------------------------------------------------------------------
Filesystem Size Used Avail Use% Mounted on
/dev/root 7.3G 2.3G 4.8G 33% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 98M 236K 97M 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 195M 0 195M 0% /run/shm

------------------------------------------------------------------------------
Jetzt wäre es natürlich fatal, wenn alle 17 Minuten eine Mail gesendet wird, welche diese Tabelle zum Inhalt hat. Das ist wenig sinnführend.
Also muss man sich etwas einfallen lassen, wann die Ausgabe "kritisch" wird und gemeldet werden sollte. Klar, hier springt einem sofort die Spalte "Use%" ins Auge, welche die prozentuale Auslastung darstellt. Naja, es gibt aber keinen Befehl, der nur Laufwerke mit einem Wert von über 50% als Beispiel in den STDOUT sendet.
Also müssen wir basteln.
Zunächst die Frage, was bekommen wir von df -h geliefert.
Es ist eine mehrzeilige Textausgabe, die mit Leerzeichen in Spalten getrennt ist.
In der ersten Zeile stehen die Spaltenüberschriften, danach die einzelnen "Mountpoints".
Wie kontrolliere ich aber jetzt in jeder Zeile die Schwellwerte?
Naja, als erstes packen wir die Ausgabe in eine Datei:
"df -h >/tmp/killme"
Jetzt kann man in der bash (dem Linux Kommandointerpreter) die Datei Zeilenweise einlesen:
------------------------------------------------------------------------------
while read f;
do
echo $f
done </tmp/killme
------------------------------------------------------------------------------
$f gibt nun Zeile für Zeile wieder.
Als nächstes brauchen wir nur die Werte der 1. und der 5. Spalte. Also einmal den "Mountpoint" oder "das Laufwerk" und die "Use%" also die Spalte mit der prozentualen Benutzung.
Hier gibt es jetzt wieder unendliche viele Wege und alle sind irgendwie richtig.
Ich habe mich für den Gebrauch von "awk" entschieden, da mir der technische Vorgang am verständlichsten erschien:
------------------------------------------------------------------------------
drive=$(echo $f|awk '{print $1}')
------------------------------------------------------------------------------
Hier die Erklärung zu dem Befehl.
{print $1} ist das Kommando, welches awk hier ausführt. Es wird ein einfaches "print" ausgeführt, welches mit einem "echo" identisch ist. Das $1 ist der erste Parameter, welche dem awk übergeben wird. Der Parameter wird dem aufrufenden "echo $f" entnommen. $f ist die eine der Zeilen aus dem "df -h" Kommando. Also steht da als Beispiel:
"echo '/dev/root 7.3G 2.3G 4.8G 33% /' | awk '{print "/dev/root"}'"Die Ausgabe ist also für diese Zeile "/dev/root", was in der Variable "$drive" abgelegt wird.
Als Nächstes brauchen wir die prozentuale Benutzung. Es kommt wieder die gleiche Sequenz zur Ausführung:
------------------------------------------------------------------------------
usage=$(echo $f|awk '{print $5}')
------------------------------------------------------------------------------
Jetzt bekommen wir aus dem o.g. Beispiel "33%" in die Variable "$usage" geschrieben.
ups... wenn wir nun aber mit einer Zahl "33" weitermachen wollen, wird das schwierig, da das "%" Zeichen als String erkannt wird. Das müsste also noch weg.
Das kann man mit einem "sed -r s/%//g" erreichen. Sinngemäß steht da: Suche alle "%"-Zeichen und ersetze sie mit "nichts". Bevor ich "sed" jetzt anfange zu erklären, bitte im Netz nach den "SED-Enzeklopädien" suchen -also nicht die der Partei... öhm... also nicht DDR und so. Ein "man sed" oder "sed --help" kann auch schon etwas bringen.
Den Befehl müssen wir nicht separieren, den können wir oben einbauen, so daß wir nun diese Zeile bekommen:
------------------------------------------------------------------------------
usage=$(echo $f|awk '{print $5}'|sed -r "s/%//g")
------------------------------------------------------------------------------
Nun haben wir in der "$usage" eine "33" stehen und können auf Intergerbasis weitermachen.
Hier noch einmal die Entwicklung des Scriptes:
------------------------------------------------------------------------------
df -h >/tmp/killme
while read f;
do
drive=$(echo $f|awk '{print $1}')
usage=$(echo $f|awk '{print $5}'|sed -r "s/%//g")
echo "$drive usage is $usage %"
done </tmp/killme
------------------------------------------------------------------------------
Bezogen auf das Eingangsbeispiel ist die Ausgabe zu diesem Script nun:
---------------------------------------------------------------------------------
Filesystem usage is Use %
/dev/root usage is 33 %
devtmpfs usage is 0 %
tmpfs usage is 1 %
tmpfs usage is 0 %
tmpfs usage is 0 %
---------------------------------------------------------------------------------
Ok, jetzt erkennt man noch, daß die erste Zeile natürlich Schwachsinn ist. Diese kann man überspringen, indem man auf den Befehl "tail" zurückgreift, wenn man die "killme" in die Schleife sendet:
---------------------------------------------------------------------------------
done < <(tail -n +2 /tmp/killme)
---------------------------------------------------------------------------------
Soweit mitgekommen? Nicht? Dann einfach noch einmal von Oben anfangen. Ne' Tasse Tee dabei oder mal 10 Minuten Pause schaden auch nicht.
Wie geht es weiter? Naja, ich habe ja schon geschrieben, das wir Schwellwerte benötigen, anhand derer wir entscheiden, ob eine Meldung gesendet wird, oder nicht.
Zusammen mit den Kopfzeilen aus der "updmon.sh" könnte man mit so etwas starten:
---------------------------------------------------------------------
#!/bin/bash
#Carsten Lahme
#2017-01-21
#dfmon.sh
#check disk space status
agent="dfmon"
mdata="/var/tmp/$(hostname)_"$agent"_mail"
cdata="$(dirname $0)/$agent.cfg"
source $cdata
if [ "$active" == true ] ; then
 logger "$agent started"
---------------------------------------------------------------------
und die passende "dfmon.cfg" dabei:
-------------------------------------------------------------------------
#!/bin/bash
active=true
thissend=false
warning=80
critical=90
--------------------------------------------------------------------------
Hier definiere ich zwei Variablen "warning" und "critical", und habe nun einen integer Vergleich für die "usage".
--------------------------------------------------------------------------
if [ $usage -gt $warning ]
then
 thissend=true;
 if [ $usage -gt $critical ]
 then
  echo "CRITICAL: $drive usage is $usage %"
 else
  echo "WARNING: $drive usage is $usage %"
 fi
fi
--------------------------------------------------------------------------
Eine zweistufige "IF" Abfrage. Auch hier gilt, daß man das unterschiedlich lösen kann. Das ist nur meine Lösung.
Im Grunde wären wir hier schon fertig. Aber ich bin da über etwas gestolpert, was die o.g. Lösung sehr schwierig macht. Schauen wir mal auf diesen Output von einer anderen Maschine:
-------------------------------------------------------------------
Filesystem Size Used Avail Use% Mounted on
rootfs 7.3G 1.5G 5.6G 21% /
/dev/root 7.3G 1.5G 5.6G 21% /
devtmpfs 486M 0 486M 0% /dev
tmpfs 98M 228K 97M 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 195M 46M 149M 24% /run/shm
/dev/sda2 211G 188G 13G 94% /var/cache/zoneminder
/dev/sda1 9.4G 238M 8.7G 3% /var/lib/mysql
--------------------------------------------------------------------------------------
Autsch. 94% Auslastung? Und das dauerhaft. Wenn ich hier Schwellwerte von 95% für alle Laufwerke angebe, dann habe ich eventuell zu wenig Platz auf den systemrelevanten (/dev/root) Verzeichnissen, wenn die mal voll werden. Zoneminder ist hier tatsächlich so eingestellt, die Platte voll zu nutzen. Die Daten werden zwar noch redundant an anderen Stellen gespeichert, aber die primäre Platte soll ruhig geben, wozu ich sie bezahlt habe.
Die Konsequenz daraus? Ich benötige "Ausnahmen".
Wie müssen diese Aussnahmen nun aufgebaut sein? Identifizieren kann ich die Ausnahme am Namen des "Filesystem". Und dann muss ich noch zwei Schwellwerte mitgeben. Also in etwa so:
"/dev/sda2,95,98"
Aber wie bilde ich so etwas in einer Variable ab, wenn ich auch mal mehr als eine Ausnahme habe -ich will ja offen für später bleiben?
Da hilft ein "array". In der "dfmon.cfg" sieht das dann so aus:
----------------------------------------------------------------
special=(
'dummy,10,20'
'/dev/sda2,95,99'
)
----------------------------------------------------------------
Aber wie lese ich das im Script ein? Naja, im Grunde muss ich ja für jede Zeile der "df -h" einmal alle Werte des Arrays "$special" vergleichen und dann die mitgegebenen Schwellwerte anpassen.
Der Mechanismus ist im Prinzip identisch zu dem, was wir mit dem "df -h" und der "killme" machen. "$special" ist die Textdatei und die müssen wir Zeile für Zeile und Spalte für Spalte auseinander nehmen.
Zunächst mal Zeile für Zeile:
---------------------------------------------------------------------
# check special handlings
for specials in "${special[@]}"
do
echo $specials
done
---------------------------------------------------------------------
Hier wird die Notation in der Bash ganz fies und man muss aufpassen, wo welche Klammer hinkommt. Auf jedenfall haben wir jetzt Zeile für Zeile in "$specials" die Werte so stehen:
"dummy,10,20"
Jetzt müssen wir die Werte trennen. Das wird jetzt mit einer recht merkwürdig anmutenden Zeile erreicht. Auch hier bitte "Tante Google" zu Rate ziehen, da eine vollständige Erklärung den Rahmen sprengt, und andere das viel besser können, als ich:
------------------------------------------------------------------
IFS=',' read -r -a specialsub <<<"$specials"
------------------------------------------------------------------
Hier wird die Zeile aus "$specials" in ein neues Array "$specialsub" geschrieben, wobei die Spalten mit einem Komma unterschieden werden. In ${specialsub[0]} steht nun "dummy" und in ${specialsub[1]} und [2] die beiden neuen Schwellwerte.
Im letzten Schritt muss also noch verglichen werden, ob das aktuelle "Laufwerk" mit dem Eintrag der "$specials" übereinstimmt, und wenn ja, die neuen Schwellwerte eingetragen werden.
Zusammen sieht das nun so aus:
---------------------------------------------------------------------
df -h >/tmp/killme
while read f;
do
 twarning=$warning
 tcritical=$critical
 drive=$(echo $f|awk '{print $1}')
 usage=$(echo $f|awk '{print $5}'|sed -r "s/%//g")
 # check special handlings
 for specials in "${special[@]}"
 do
  IFS=',' read -r -a specialsub <<<"$specials"
  if [ $drive == ${specialsub[0]} ]
  then
   twarning=${specialsub[1]}
   tcritical=${specialsub[2]}
  fi
 done
 if [ $usage -gt $twarning ]
 then
  thissend=true;
  if [ $usage -gt $tcritical ]
  then
   echo "CRITICAL: $drive usage is $usage %"
  else
   echo "WARNING: $drive usage is $usage %"
  fi
 fi
done < <(tail -n +2 /tmp/killme)
---------------------------------------------------------------------
Zu beachten, daß ich hier die Schwellwerte über die Variablen $twarning und $tcritical nach jedem Lauf wieder mit "$warning" und "$critical" zurücksetze. Außerdem gibt es hier jetzt die Abweichung, das die CFG Datei für jeden Server eigenständig zu sehen ist. Aber das ist ja im Sinne der Sache. Das Script ist immer gleich, nur die Konfiguration für jeden Server eigenständig.
Im letzten Schritt muss das Script jetzt nur noch mit dem Mail-Korpus versehen werden, und ein zusammenfassender "df -h" wird  angehangen, wenn eine Alarmmeldung verschickt wird.
-------------------dfmon.sh----------------------------------------
#!/bin/bash
#Carsten Lahme
#2017-01-21
#dfmon.sh
#check disk space status

agent="dfmon"
mdata="/var/tmp/$(hostname)_"$agent"_mail"
cdata="$(dirname $0)/$agent.cfg"
source $cdata
if [ "$active" == true ] ;
then
 logger "$agent started"
 echo "Subject: $agent: Diskspace status on $(hostname)" >>$mdata
 echo "" >>$mdata
 df -h >/tmp/killme
 while read f;
 do
  twarning=$warning
  tcritical=$critical
  drive=$(echo $f|awk '{print $1}')
  usage=$(echo $f|awk '{print $5}'|sed -r "s/%//g")
  # check special handlings
  for specials in "${special[@]}"
  do
   IFS=',' read -r -a specialsub <<<"$specials"
   if [ $drive == ${specialsub[0]} ]
   then
    twarning=${specialsub[1]}
    tcritical=${specialsub[2]}
   fi
  done
  if [ $usage -gt $twarning ]
  then
   thissend=true;
   if [ $usage -gt $tcritical ]
   then
    echo "CRITICAL: $drive usage is $usage %" >>$mdata;
   else
    echo "WARNING: $drive usage is $usage %" >>$mdata;
   fi
  fi
 done < <(tail -n +2 /tmp/killme)
 if [ $thissend == true ];
 then
  echo "--------------------------------------------------------------------" >>$mdata
  echo "Full df -h output:" >>$mdata
  echo "--------------------------------------------------------------------" >>$mdata
  df -h >>$mdata
  scp $mdata monitor@derdapp002:~/mails/
 fi
 logger "$agent finished"
 rm $mdata
fi
----------------------------------------------------------------------
-------------------dfmon.cfg----------------------------------------
#!/bin/bash
active=true
thissend=false
warning=80
critical=90
special=(
'dummy,10,20'
'/dev/root,50,75'
)
----------------------------------------------------------------------
Aufgabe für Euch:
Wenn ein Laufwerk bereits gemeldet wurde, soll es nicht sofort wieder gemeldet werden.
Außer der Meldestatus ändert sich von "warning" auf "critical" oder umgekehrt.


Have Fun!!

Linux Monitoring

Nagios, Tivoli, Open View, OMSA, CIM und und und und....

Das und noch viel mehr Tools findet man, wenn man anfängt darüber nachzudenken, wie man seine Umgebung zu Hause überwachen könnte.

Wahrscheinlich wird man am Ende sogar bei einem dieser Tools landen, wenn man sich ein wenig einarbeitet und "seinen Weg" gefunden hat.
Was aber bis dahin? Wie fängt man an, und was will man überhaupt?

Ich möchte hier einmal versuchen, meine ersten Lösungen für ein recht einfaches Monitoring zu beschreiben.

Wo bin ich gestartet?
Zunächst habe ich mehrere kleine Zwerge (Banana PI und Raspberry PI) zu Hause laufen, die in einem gekapselten Netz sind, welches nicht unmittelbar an meinem DSL Anschluss hängt.

Ein Weg nach "draußen" ist daher nur sehr eingeschränkt möglich.
Am einfachsten ist da immer noch SMTP -also Mails senden.
Nachteil: Man muss also von vorne herein in Kauf nehmen, daß bei Ausfall der DSL Leitung oder des Mailproviders keine Meldungen mehr rausgehen.

Wie war also mein Ansatz?

Die erste Frage, welche sich stellt, ist im Grunde, was will ich beobachten.
Ich für meinen Teil habe mich immer darüber geärgert, daß ich auf jede Maschine drauf musste, um zu schauen, welche Updates gerade wieder verfügbar sind. Natürlich könnte ich auch einfach alle Aktualisierungen automatisch installieren, aber die Erfahrung lehrt, wenn etwas schief geht, kommt man schlechter dran, als wenn man es manuell macht. Außerdem ist nicht jedes Update immer auch mit der laufenden Software kompatibel.
Also reicht mir im Grunde eine regelmäßige Meldung, was an Paketen offen ist.

Eine passende Ausgabe erzeugt man durch ein
apt-get update
und dann ein
apt-get -s upgrade.
Das "-s" simuliert nur und schmeißt die Installations- und Konfigurationszeilen einfach in den STDOUT.
Das Ergebnis kann man dann per Mail verschicken.
Wie... jetzt einfach so?
Nein, natürlich nicht.
Benötigt wird das Paket "sendmail" in der einfachsten Form und ein Mail Account, an den man Mails versenden kann. Wie "sendmail" installiert und konfiguriert wird, kann man sich in allen Sprachen im Netz recht anschaulich anlesen.

Am Ende steht dann bei meinen Lösungen immer die Zeile:
"cat $mdata | /usr/sbin/sendmail -t"

Aber wie komme ich dahin?
Ok, also, wir haben den STDOUT von "apt-get -s upgrade" und wollen den per sendmail verschicken.
Die Variable $mdata, welche oben verwendet wurde, sieht in meinem Fall zum Beispiel so aus:
------------------------------------------------
From: monitor@[meinedomäne].de
To: [ichselber]@[meinedomäne].de
Subject: Availabe Updates on derdapp003

Reading package lists...
Building dependency tree...
Reading state information...
The following packages have been kept back:
  linux-image-3.4-bananian
The following packages will be upgraded:
  base-files bash bind9 bind9-host bind9utils ca-certificates dnsutils
  e2fslibs e2fsprogs file libbind9-90 libc-bin libc-dev-bin libc6 libc6-dev
  libcairo2 libcomerr2 libdbus-1-3 libdns-export100 libdns100 libgd3
  libgnutls-deb0-28 libgnutls-openssl27 libhogweed2 libirs-export91
  libisc-export95 libisc95 libisccc90 libisccfg-export90 libisccfg90
  liblwres90 libmagic1 libmpg123-0 libmysqlclient18 libnettle4 libpam-modules
  libpam-modules-bin libpam-runtime libpam0g libpcsclite1 libpng12-0
  libpng12-dev libss2 libtiff5 libudev1 libxml2 libxml2-dev linux-libc-dev
  locales mpg123 multiarch-support mysql-common sed tzdata udev
55 upgraded, 0 newly installed, 0 to remove and 1 not upgraded.
Inst base-files [8+deb8u6] (8+deb8u7 Debian:8.7/stable [armhf])
[....ganzVielText....]
------------------------------------------------
Hier kann man schon erkennen, das zunächst 3 Zeilen in die Variable geschrieben werden müssen, die den Mailheader, also wer an wen über was, enthalten.
Danach kommt die Ausgabe des "apt-get" Kommandos.
In Befehlszeilen sieht das bei mir so aus:
-----------------------------------------------
echo "Subject: Availabe Updates on $(hostname)" >>$mdata
echo "" >>$mdata

apt-get update
apt-get -s upgrade >>$mdata
-----------------------------------------------
Öhm... da fehlt doch was... ja... richtig. Die beiden ersten Zeilen kommen später.

Warum?
Naja, was wollte ich anfänglich noch mal? Mehrere Hosts überprüfen, aber keiner von denen darf direkt ins Internet.
Was muss ich also machen? Rischtisch.... die Nachrichten müssen von den einzelnen Hosts an einen zentralen Satelliten geschickt werden, der dann das mit der Mail übernimmt.
Was aber, wenn sich irgendwann mal die Mailaddresse ändert? Soll ich dann auf jedem Server die Scripte anpassen? Nö. Im Grunde braucht also nur das Mail Relay Absender und Empfänger zu kennen. Der betreffende Host steht ja dann im Betreff.
Das Mailerscript dazu sieht so aus:
------------------------------------------------------------------
for f in ~/mails/*_mail
 do
  logger "MAILIT detected $f"
  echo "From: $mfrom" >$mdata
  echo "To: $mto" >>$mdata
  cat $f >>$mdata
  cat $mdata | /usr/sbin/sendmail -t
  rm $f
  rm $mdata
 done
---------------------------------------------------------------------
Ihr seht, da werden Dateien mit einem bestimmten Namen eingelesen und dann mit dem Header versehen und abgeschickt.
Das passiert auf dem Mail Relay.
Wie kommen die Dateien da hin?
Viele Wege führen nach Rom. Ich habe mich für SCP (ssh) entschieden:
--------------------------------------------------------
if [ $thissend == true ]; then
 scp $mdata monitor@derdapp002:~/mails/
fi
----------------------------------------------------------
Damit werden alle Ausgaben des "apt-get" Scriptes an eine zentrale Stelle kopiert.
Um das so wie oben abgebildet funktionieren zu haben, muss man mit einem rsa-Schlüsselpaar unter ssh arbeiten. Im Grunde recht einfach: Mit ssh-keygen wird ein Schlüsselpaar erzeugt.
Es ist im Grunde völlig egal, wo und unter welchem Benutzer die Schlüssel erzeugt werden.
Wichtig ist nur, daß der öffentliche Schlüssel auf dem ZIELSYSTEM in der ~/.ssh/authorizied_keys eingetragen wird:
"cat id_rsa.pub >> ~./.ssh/authorized_keys"
und der private Schlüssel (id_rsa) auf dem Ausgangsystem im Verzeichnis ~/.ssh liegt.
Für diesen Fall also einmal der öffentliche Schlüssel auf dem Mail Relay und auf jedem Host der private Schlüssel. Den Rest erkennt scp/ssh von selber.
Aber auch hier gibt es umfangreiche Doku im Netz.

Vielleicht kann man anhand der Variablen schon erahnen, daß die Scripte doch etwas weiter gedacht sind, als nur eine Aufgabe zu erfüllen. Ja. Zunächst muss klar sein, daß nicht auf jedem Server ein individuelles Script läuft. Es ist auf allen Maschinen das selbe Script. Und nach Möglichkeit sollten die Scripte auf jedem Server auch identisch behandelt werden.
Alle meine Module (Agenten) beginnen so:
------------------------------------------------------
#!/bin/bash
#check update status

agent=updmon
mdata="/var/tmp/$(hostname)_"$agent"_mail"
cdata="$(dirname $0)/$agent.cfg"

source $cdata
if [ "$active" == true ] ; then
 logger $agent" started"
--------------------------------------------------------
Der "Agent" bekommt seinen Namen und zusammen mit dem Hostnamen der Maschine seine $mdata Datei/Variable. Ebenso wird die Konfigurationsdatei eingelesen.
Für den "updmon" sieht die "updmon.cfg"so aus:
------------------------------------------------------
#!/bin/bash
active=true
thissend=true
--------------------------------------------------------
Nicht viel, aber hier gründen sich die Ideen für andere Agenten.

Das komplette "updmon.sh" sieht also so aus:
--------------------------------------------------------------------
#!/bin/bash
#Carsten Lahme
#2017-01-21
#updmon.sh
#Monitoring/Reporting Agent for available updates

agent=updmon
mdata="/var/tmp/$(hostname)_"$agent"_mail"
cdata="$(dirname $0)/$agent.cfg"

source $cdata
if [ "$active" == true ] ; then
 logger $agent" started"
 echo "Subject: Availabe Updates on $(hostname)" >>$mdata
 echo "" >>$mdata
 apt-get update
 apt-get -s upgrade >>$mdata
 if [ $thissend == true ]; then
  #die mails werden zentral vom derdapp002 über den benutzer "monitor" versendet
  scp $mdata monitor@derdapp002:~/mails/
 fi
 logger $agent" finished"
 rm $mdata
fi
------------------------------------------------------------------
Ich habe mir angewöhnt, alles im Verzeichnis /var/monitor abzulegen.
Aber im Grunde können die Dateienpaare überall abgelegt werden.
Die Ausführung steuere ich per CRONTAB.
Und zwar habe ich im Verzeichnis /etc/cron.d die Datei "monitor" angelegt. Hier kommen alle Einträge für die Agenten rein:
------------------------------------------------------------------------
1 0 * * * root /var/monitor/updmon.sh
*/17 * * * * root /var/monitor/dfmon.sh
------------------------------------------------------------------------
updmon wird also einmal um 00:01 morgens jeden Tag ausgeführt. Und man sieht schon, da gibt es noch eine dfmon.sh, welche alle 17 Minuten ausgeführt wird. Aber wir bleiben noch ein wenig bei der updmon.
Jetzt ist die updmon.sh also morgens gelaufen und hat die Mail-Datei auf das Relay geschoben.
Dort liegt sie in einem Verzeichnis eines Benutzers "monitor".
Da das Mail Relay ein halbes Bein in meinem "normalen" Netzwerk hat, wird hier das Benutzerrecht stark eingeschränkt, und "root" spielt nicht mehr mit.
Per CRONTAB wird das mailit.sh alle 3 Minuten getriggert:
-------------------------------------------------------------------------
*/3 * * * * monitor ~/scripts/mailit.sh
-------------------------------------------------------------------------
Hier einmal das mailit.sh komplett:
-------------------------------------------------------------------------
#!/bin/bash

#Carsten Lahme
#2017-01-21
#mailit.sh
#send incoming reports from monitoring agents

agent="mailit"
active=false
mdata="/var/tmp/$(hostname)_$agent\_mail"
cdata="$(dirname $0)/$agent.cfg"

source $cdata

if [ $active == true ] ; then
 shopt -s nullglob
 for f in ~/mails/*_mail
 do
  logger "MAILIT detected $f"
  echo "From: $mfrom" >$mdata
  echo "To: $mto" >>$mdata
  cat $f >>$mdata
  cat $mdata | /usr/sbin/sendmail -t
  rm $f
  rm $mdata
 done
fi
-------------------------------------------------------------------------
Auch hier wieder eine passende mailit.cfg
-------------------------------------------------------------------------
#!/bin/bash
active=true
mto=[ichselber]@[MeineDomäne].de
mfrom=monitor@[MeineDomäne].de
-------------------------------------------------------------------------
Damit habe ich einmal täglich eine Mail in meinem Postfach, die mir anzeigt, was meine Maschinen zu Hause an Updates haben möchten und ich kann gezielt planen.

Vieleicht bringt es ja jemanden von Euch dazu, so etwas selber anzuwenden. Ihr könnt die o.g. Scripte auch für Eure Versuche übernehmen und anpassen. Wenn es jemandem hilft, freut mich das.