Entfernte CheckMK-Agents überwachen (ssh/tls)

UPDATE 09.01.2021: Fix für „curl: Argument list too long“
Details: https://git.ichalsroot.de/erdo/Check_MK/commit/4640354834f6db445a9ec150e49ec1bdeb8fc268


CheckMK-Agents sind auf Pull ausgelegt, sprich der CheckMK-Server baut eine Verbindung zum Client auf und fragt die Daten ab. Dies geschieht unter Linux traditionell per xinetd oder ssh.

Das Verfahren funktioniert aber nicht, wenn der Agent nicht im Intranet hängt und keine SSH-Verbindung hergestellt werden kann/soll. (oftmals. aus Security-Gründen).

check_mk_remote

Hierfür wurde die Community-Erweiterung „check_mk_remote“ entwickelt, welche den Agent-Output in eine Datei umleitet und diese per scp auf den CheckMK Server überträgt. Die Auswertung erfolgt dann durch einen Host-spezifischen Datasource.

https://github.com/FlorianHeigl/nagios/tree/master/check_mk/check_mk_remote

Für das Verfahren von check_mk_remote ist eine passwortlose Authentifizierung, sowie ein öffentlich zugängiger SSH-Server erforderlich. Beides kann sicher betrieben werden, jedoch ist der Konfigurationsaufwand nicht zu unterschätzen und sicherheitstechnisch bedenklich, vor allem weil es 100 Kleinigkeiten zu bedenken gibt.

check_mk_push

Als Alternative habe ich eine Methode entwickelt, um den Agent-Output per https statt ssh zu übertragen.
Das Prinzip ist identisch, nur der Übertragungsweg ein ganz anderer.

Vorteile gegenüber check_mk_remote

  1. Keine aufwendige SSH-Konfiguration.
  2. keine spezielle Firewall-Freischaltung (es wird nur Port 443 benötigt, ssh ist oftmals gesperrt)
  3. Firmeninterner Web-Proxy kann benutzt werden (inkl. Authentifizierung)

Sonstige Features (beide Methoden)

  1. User-Authentifizierung
  2. verschlüsselte Übertragung (TLS/SSH)
  3. Host Status (down bei ausbleibender Übertragung)
  4. Volle checkMK-Plugin/local checks Unterstützung
  5. Sicherstellen der Übertragung
  6. extrem flexibel

Vorraussetzung:

  1. Ein öffentlich erreichbarer Webserver, dieser muss nicht der OMD sein, in diesem Fall ist ein Cronjob notwendig, welcher die Daten per scp auf den OMD kopiert. Siehe „Abschottung durch DMZ“
  2. Ein SSL-Zertifikat (optional, aber definitiv empfehlenswert, kann selbst erstellt sein.)
  3. (Apache-)User für Authentifizierung, kann über OMD-Authentifizierung erfolgen

Bestandteile

check_mk_push besteht aus 2 Bestandteilen (im Gegensatz zu check_mk_remote)

  1. dem Client-Script cmk_send_agentdata.sh, welches die Agent-Daten verschlüsselt und an CheckMK überträgt.
  2. dem php-Script mk_agentdata.php, welches Serverseitig die Daten entgegen nimmt und in eine Host-Status-Datei schreibt. (cmkresult.$HOSTNAME$)

Technisch gesehen wird der Agentoutput für die Übertragung per Base64 codiert (nicht verschlüsselt!), anschließend wird per curl eine TLS-Verbindung zum Remote-Webserver aufgebaut und die Daten werden per HTML-POST an das PHP-Script übergeben. Dieses dekodiert die Daten und schreibt sie in eine Host-spezifische Status-Datei. Das PHP-Script prüft den Schreibvorgang und liefert einen Returnstring zur Clientseitigen Auswertung.

Konfiguration von CheckMK

Die Auswertung seitens CheckMK ist in beiden Verfahren identisch.

Datasource Program

Als „Datasource Program“ wird  „Individual program call instead of agent access“ für den/die Hosts deklariert. Über die spezielle Commandline kann man eine Regel für Hosts machen (und zB. über Order/Hoststags spezifizieren)

Commandline: cat $OMD_ROOT/var/tmp/cmkresult.<HOST>

Hierbei ist darauf zu achten, dass der Host so heißt wie die Datei!
Der Hostname der cmkresult.* Datei wird hierbei Clientseitig definiert und mit an das PHP-Script übertragen.

Hoststatus

Um den Hoststatus aktuell zu halten wird weiterhin ein „Host Check Command“ angelegt. Dieser gilt wiederum für alle entsprechend getagte Hosts…

Ich empfehle einen zeitlichen Buffer, wenn eine Übertragung ausbleibt muss der Server nicht zwangsweise down sein! Das Internet ist erfahrungsgemäß relativ anfällig für temporäre Störungen …

Host Check Command -> Use a custom check plugin...
check_file_age -w  900 -c 1800 ~/var/tmp/cmkresult.$HOSTNAME$

Alternativ kann man auch einen Service pro Host anlegen und diesen überwachen, hierfür ist jedoch eine Host-Check-Command-Regel pro Host notwendig (Stand OMD 1.2.8b12), sowie ein manueller Service (kein manual Check“!).

Service Check -> Size and age of single files:

Maximal age: Warning->15min, Crit->30min (Beispiel)
File-Name: /opt/omd/sites/monitoring/var/tmp/cmkresult.
Host Check Command -> Use the status of the service... :
-> File /opt/omd/sites/monitoring/var/tmp/cmkresult.DUMMYHOST

Wobei DUMMYHOST immer dem entsprechendem Host angepasst werden muss… $HOSTNAME$ funktioniert hier leider nicht!

ACHTUNG! Hoststatus ist UP oder DOWN! Host-Status Warning gibt es nicht… Service-Status Warning bedeutet hier Host-Status UP.

User für Remote-Agent (optional)

Wenn der OMD-Server aus dem Internet heraus erreichbar ist (siehe „Abschottung durch DMZ“) ist ein Benutzer zur Authentifizierung erforderlich.

Hierfür kann ein CheckMK-User mit Authentication „machine account“ und Passwort erstellt werden. Der Zugriff klappt in einer Standart-OMD Installation auch ohne Rollen, wenn das PHP-Script im Standartpfad liegt.

Abschottung durch DMZ

Wenn der OMD-Server nicht aus dem Internet heraus erreichbar sein soll, kann man das PHP-Script auf einen Webserver in der DMZ betreiben und die Daten von dort abrufen. Hierfür kann zB. ein automatischer Cronjob auf dem OMD eingerichtet werden, welcher die Status-Dateien per SCP abholt.

screenshot-area-2016-05-03-083325

Betrieb ohne DMZ

screenshot-area-2016-05-03-084049

Betrieb mit DMZ

Crontab für DMZ-Webserver

Falls der Webserver in der DMZ stehen soll, hier ein Beispiel für einen Cronjob.

[root@omd omd]# cat /etc/crontab
*/5 * * * * monitoring mk-job scp_phppush rsync -pr --remove-source-files --delete -e "ssh -i /omd/sites/monitoring/.ssh/id_dsa_cmkremote" remoteuser@remotehost:/var/cache/check_mk_phppush/cmkresult.*  /omd/sites/monitoring/var/tmp/

–remove-source-files ist wichtig, da die Hostdateien sonst IMMER aktuell sind!

Notwendige Dateien

cmkserver.cfg (Agent)

Die Konfigurations-Datei cmkserver.cfg liegt standardmäßig unter /etc/check_mk/ und beinhaltet URL, Benutzername & Passwort. Bitte keine Apostrophs benutzen!

## Don't use inverted comma!
OMDURL=https://www.meinhost.de/omd/mk_agentdata.php
OMDUSER=remoteuser
OMDPASS=abC123supergeheimesPassWort

cmk_send_agentdata.sh (Agent)

Das Übertragungssript cmk_send_agentdata.sh wird standardmäßig unter /usr/local/bin/ abgelegt.

  • Der Aufruf erfolgt per crontab.
  • Zu Testzwecken kann der Parameter „–debug“ mit angegeben werden.
  • Das Script liefert einen boolschen Returncode.
#!/bin/bash
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Jonas Nickl 2021             development@ichalsroot.de |
# +------------------------------------------------------------------+
#
# This file is an addon for Check_MK.
# The official homepage for this check is at https://blog.ichalsroot.de
#
# check_mk is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

HOSTNAME=`hostname`
MK_CONFDIR=/etc/check_mk

temp_file=$(mktemp)
 
## DEBUG Level (BOOL)
if [ "$1" == "--debug" ] ; then DEBUG="1"; fi
 
be_done()
{
    rm ${temp_file}
    echo "RC=$STATUS"
    ## bad returncode if status nok
    if [ "$STATUS" != "OK" ]; then exit 1; fi
}
 
validate()
## Verify config dir exists and that the config file exists
{
    if [ -d $MK_CONFDIR ]                                    && 
       [ -r $MK_CONFDIR/cmkserver.cfg ]                      &&
         OMDURL=`grep OMDURL      $MK_CONFDIR/cmkserver.cfg | cut -f2 -d\= | sed 's/"//g'` &&
         OMDUSER=`grep OMDUSER    $MK_CONFDIR/cmkserver.cfg | cut -f2 -d\= | sed 's/"//g'` &&
         OMDPASS=`grep OMDPASS    $MK_CONFDIR/cmkserver.cfg | cut -f2 -d\= | sed 's/"//g'`    
    then
        export OMDURL OMDUSER OMDPASS
    else
        echo "Please set OMDURL, OMDUSER and OMDPASS in"
        echo "$MK_CONFDIR/cmkserver.cfg"
        exit 1
    fi
    if ! `which check_mk_agent >/dev/null`; then
        echo "check_mk_agent was not found in path, please install it." 
        exit 1
    fi
    if ! `which curl >/dev/null`; then
        echo "curl was not found in path, please install it." 
        exit 1
    fi
 
}
 
get_result()
{
   ## decode agent output with base64, remove line breaks and replace plus with html +
   export DATA=`check_mk_agent | base64 --wrap=0 | sed 's/+/%2b/g' > ${temp_file}`
}
 
send_result()
{
    [ $DEBUG ] && echo '$(echo "HOSTNAME=$HOSTNAME&DEBUG=$DEBUG&DATA=cat1 ${temp_file}" | curl -X POST --silent --user $OMDUSER:$OMDPASS --data @- $OMDURL'
    STATUS=$(echo "HOSTNAME=${HOSTNAME}&DEBUG=${DEBUG}&DATA=`cat ${temp_file}`" | curl -X POST --silent --user ${OMDUSER}:${OMDPASS} --data @- ${OMDURL} )
    
    if [ $? != 0 ]; then
        echo "Failed to submit agent output via CURL"
    fi
}

   ## main :)
   validate    &&
   get_result  &&
   send_result 
   ## print return
   be_done

mk_agentdata.php (OMD)

Das serverseitige Script nimmt die Daten entgegen und schreibt diese in lokale Host-Status-Dateien.
Standart-Pfad Script:                      $OMDROOT/var/www/
Standart-Pfad Host-Status-Dateien: $OMDROOT/var/tmp/

<?php
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Jonas Nickl 2016             development@ichalsroot.de |
# +------------------------------------------------------------------+
#
# This file is an addon for Check_MK.
# The official homepage for this check is at https://blog.ichalsroot.de
#
# check_mk is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

## just for debug
#error_reporting(E_ALL);

## read given data
$HOSTNAME = $_POST["HOSTNAME"];
$MESSAGE = base64_decode($_POST["DATA"]);
$DEBUG = $_POST["DEBUG"];

## Check if data given
if (!$HOSTNAME){ die( "No hostname!"); }
if (!$MESSAGE){ die( "No data!"); }

## get omd path
$FULLPATH = getcwd();
$SITEROOT = str_replace("var/www", "", "$FULLPATH");

## debug output
if ($DEBUG){ echo "[DEBUG] SITEROOT = $SITEROOT"; }

## open filehandle
$FILEHANDLE = fopen( $SITEROOT."var/tmp/cmkresult.".$HOSTNAME,"w");

## write agentoutput
fwrite($FILEHANDLE, $MESSAGE );

## check if file written correctly
if ($FILEHANDLE === false) {
        die("ERROR: Unable to write cmkresult_".$HOSTNAME);
} else {
        if ($DEBUG){ echo "DEBUG=$MESSAGE"; }
        echo "OK";

}
fclose($FILEHANDLE);

?>
Kommentar schreiben

8 Kommentare.

  1. Hallo,
    leider bekomme ich den Client nicht zu laufen.
    Als Output bekomme ich immer
    Failed to submit agent output via CURL
    RC=

    Woran könnte das liegen ?

    Dankeschön

    • Hi Steffen,

      versuch doch mal „cmk_send_agentdata.sh –debug“ aufzurufen.
      Wenn das noch nicht weiterhilft dann führ den curl-Befehl aus der Debug-Meldung mal direkt aus.
      Wenn das noch nicht hilft dann lass mal –silent weg, dann siehst du auch die Fehler 😉

      Grüße
      erdo

      • Hallo Erdo,

        vielen Dank für die schnelle Antwort.

        Momentan sieht die Fehlermeldung so aus:

        cmk_send_agentdata.sh: line 74: /usr/bin/curl: Argument list too long
        Failed to submit agent output via CURL
        RC=

        Leider ist mir nicht ganz klar wieso ?

        • Sorry für die späte Antwort,sehr stressig derzeit.
          Entweder wird der Befehl falsch zusammengesetzt oder es liegt an deiner curl-Version…

          Prüf mal:
          bash -x cmk_send_agentdata.sh | grep curl

          • Ich anworte mir einmal selbst:
            Ich habe meine ZyXel Nas 325v2 auf Debian 10 umgestellt und nun habe ich den Fehler „curl: Argument list too long“ selbst bekommen.

            Die Lösung steht am Anfang des Artikels.

  2. Hi Neeloj,

    vielen Dank für deine Rückmeldung (privat dokumentiere ich offenbar besser wie beruflich 🙄 )

    Zu deinen Fragen:
    1. Muss ich manuell den Host auf Check_MK server erstellen?
    -> ja, der Host muss manuell angelegt werden, sollte ich in der Dokumentation ergänzen…

    2. Was wenn ich als Agent Windows hab und nicht Linux?
    -> bei Windows bin ich leider raus, Powershell sollte das wohl auch können,
    aber keine Ahnung wie

    • Vielen Dank Erdo für deine Antwort.

      Also besser kann man nicht erklären 😀

      Super dann kümmere ich mich um die beide Punkte, ich mag Windows auch nicht aber naja :mrgreen:

      Danke schön noch mal

  3. Vielen Dank für die ausführliche Erklärung 🙂

    Eine von den besten den ich je gesehen habe :-).

    Ich habe 2 fragen bitte:

    1. Muss ich manuell den Host auf Check_MK server erstellen?
    2. Was wenn ich als Agent Windows hab und nicht Linux?

Antwort an Neeloj ¬
Antwort abbrechen


Hinweis - Du kannst dies benutzenHTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.