Kontakt

Carsten Rieger IT Services
Am Danglfeld 8 | 83132 Pittenhart
Telefon: 08624.9009794
E-Mail: info@c-rieger.de

Checkmk Monitoring für Nextcloud und BigBlueButton

System-Monitoring mit Checkmk

Checkmk für Nextcloud und BigBlueButton – überwachen Sie Nextcloud KPI’s wie die Anzahl der Nextcloud- Benutzer, den verwendeten Storage, die Nextcloud Version u.v.m..

Diese IT-Monitoring Software setzt neue Standards für effektives IT-Monitoring. Einfaches Aufsetzen, beste Skalierbarkeit und ein hoher Funktionsumfang begeistern immer mehr Anwender. Der Clou aber sind die über mehr als 1800 mitgelieferten Check-Plugins, die sich vollautomatisch konfigurieren.

Unter https://checkmk.de/videos.html wird sehr ausführlich und eindrucksvoll in Videos dargestellt, welche Möglichkeiten des Checkk-Monitorings bestehen. Ich zeige Ihnen in dieser Anleitung, wie Sie Checkmk auf einem Ubuntu Server 20.04.x installieren, einen ersten Host im Monitoring erstellen und diesen Host (Server) hinsichtlich seines System-Status und der eingesetzten Nextcloud-Version überwachen.

Um Checkmk für Nextcloud einzurichten wechseln Sie in den privilegierten Benutzermodus und laden sich die aktuelle Checkmk-Software herunter: Ggf. müssen Sie den Link anpassen, da ich diesen nicht permanent aktuell halten kann.

sudo -s
wget https://download.checkmk.com/checkmk/2.2.0p18/check-mk-raw-2.2.0p18_0.mantic_amd64.deb

Um das Paket installieren zu können aktualisieren wir das System und installieren dann check_mk mittels dpkg -i:

apt update && apt upgrade -V
dpkg -i check-mk-raw-*.deb

Abschließend überprüfen wir die check-mk-Version mittels

omd version

Um Checkmk verschlüsselt, also mittels https (SSL) verwenden zu können, fügen wir das Repository „universe“ hinzu:

apt update
apt install -y software-properties-common python3 python-is-python3 
add-apt-repository universe
apt update

und installieren die certbot Software, um die Let’s Encrypt Zertifikate requestieren zu können:

sudo apt install certbot python3-certbot-apache

Zudem erstellen wir das Verzeichnis für die Zertifikate und einen Diffie-Hellman-Schlüsselaustausch, um die Sicherheit des Monitoring-Systems zu erhöhen:

mkdir -p /etc/apache2/ssl
openssl dhparam -dsaparam -out /etc/apache2/ssl/dhp-4096.pem 4096

Konfigurieren Sie den Webserver Apache2 für Ihre Domäne – passen Sie unbedingt die Werte für „ihre.domain.de“ und „ihre.email.de“ an:

nano /etc/apache2/sites-available/000-default.conf
ServerName ihre.domain.de
ServerAlias ihre.domain.de
ServerAdmin ihre@email.de

Testen Sie die Konfiguration und starten dann den Webserver Apache2 neu

apache2ctl configtest && systemctl restart apache2

Ordern Sie jetzt die SSL-Zertifikate für Ihre Domäne von Let’s Encrypt mittels certbot:

certbot --apache

Wählen Sie Ihre Domäne (1) und dann den redirect (2) im certbot-Dialog aus:

Öffnen Sie die SSL-Konfiguration von Apache2 und tragen sowohl den „dhp-4096.pem“, als auch den RequestHeader im <VirtualHost> Block unter den „SSL Certificate“-Einträgen ein:

nano /etc/apache2/sites-available/000-default-le-ssl.conf
SSLOpenSSLConfCmd DHParameters "/etc/apache2/ssl/dhp-4096.pem"
RequestHeader set X-Forwarded-Proto "https"

Sichern Sie nun noch den Apapche2 Webserver etwas ab:

a2dismod status && nano /etc/apache2/conf-available/security.conf
ServerTokens Prod
ServerSignature Off
TraceEnabled Off

Tragen Sie noch Ihren Servernamen in die Apache2-Konfigurationsdatei (/etc/apache2/apache2.conf)

nano /etc/apache2/apache2.conf

ein, indem Sie die nachfolgende Zeile in die erste Zeile der Konfiguration kopieren. Bitte ersetzen Sie ihre.domain.de mit Ihrer „echten“ Domain!

ServerName ihre.domain.de

Aktivieren Sie die Apapche2 HEADER-Module, überprüfen dann die Konfiguration und starten zuletzt den Webserver neu:

a2enmod ssl headers && apache2ctl configtest && systemctl restart apache2

Um Checkmk nun im Web nutzen zu können muss eine Instanz (bspw. „IT_SERVICES„) instanziiert werden:

omd create it_services

Starten Sie die neue Checkmk-Site (it_services) und rufen diese dann im Web auf:

omd start it_services

Bevor Sie sich anmelden ändern Sie noch das in der Konsole angezeigte Standardpasswort. Dazu wechseln Sie mit „su – it_services“ die Session und führen dann den Passwortbefehl aus:

su - it_services
htpasswd -m ~/etc/htpasswd cmkadmin

Im Anschluss daran können Sie sich als cmkadmin und dem zuvor geänderten Passwort sicher am Monitoring-System anmelden:

https://<ihre-domäne.de>/it_services

Richten Sie noch das automatische Erneuern der SSL-Zertifikate mittels cron-job ein:

crontab -e

Fügen Sie die nachfolgende Zeile der crontab-Datei hinzu, um bspw. immer Sonntags um 02:05 Uhr die Zertifikate zu erneuern und im Fall einer Erneuerung auch den Webserver neu starten zu lassen:

5 2 * * 6 /usr/bin/certbot renew --renew-hook 'service apache2 restart'

Wechseln Sie nun auf Ihren Host, also den zu überwachenden Nextcloud-Server und laden den Checkmk-Agent herunter:

wget https://<ihre.domain.de>/it_services/check_mk/agents/check-mk-agent_2.2.0p18-1_all.deb

und installieren das Paket auf dem Nextcloud-Server:

sudo -s
apt install -y python jq
dpkg -i check-mk-agent_*.deb

Erstellen Sie nun den Nextcloud-Check im Verzeichnis „/usr/lib/check_mk_agent/plugins/“ und passen ggf. die Variable „$baseDir“ an, sofern Nextcloud nicht unter „/var/www/nextcloud“ installiert wurde:

nano /usr/lib/check_mk_agent/local/check_nextcloud_update.php
#! /usr/bin/env php
<?php
$baseDir = "/var/www/nextcloud";
function getNewVersion($baseDir)
{
    require $baseDir . "/config/config.php";
    $pdo = new PDO(sprintf("mysql:host=%s;dbname=%s", $CONFIG["dbhost"], $CONFIG["dbname"]), $CONFIG["dbuser"], $CONFIG["dbpassword"]);
    $query = $pdo->query("
        SELECT `configvalue`
        FROM `oc_appconfig`
        WHERE `appid` = 'core' AND `configkey` = 'lastupdateResult'
    ");
    if (!$query->rowCount()) {
        return null;
    }
    $json = json_decode($query->fetchObject()->configvalue, true);
    if ($json === null) {
        return null;
    }
    if (!is_array($json)) {
        return null;
    }
    if (empty($json)) {
        return true;
    }
    if (!isset($json["version"])) {
        return null;
    }
    if (!is_string($json["version"])) {
        return null;
    }
    return $json["version"];
}
function getCurrentVersion($baseDir)
{
    require $baseDir . "/version.php";
    return implode(".", $OC_Version);
}
function output($state, $message)
{
    printf("%d Nextcloud_Version - %s\n", $state, $message);
}
$newVersion = getNewVersion($baseDir);
$currentVersion = getCurrentVersion($baseDir);
if ($newVersion === null) {
    output(1, "Unable to read new version");
} elseif (!is_string($currentVersion)) {
    output(1, "Unable to read current version");
} elseif ($newVersion === true or $newVersion === $currentVersion) {
    output(0, sprintf("No update available (installed version: %s)", $currentVersion));
} else {
    output(1, sprintf("An update to version %s is available (installed version: %s)", $newVersion, $currentVersion));
}

Der Check muss nun noch als ausführbar markiert werden:

chmod +x /usr/lib/check_mk_agent/local/check_nextcloud_update.php

Nach einem Scan bzgl. neuer Services in Checkmk für den Nextcloud-Server (Host) werden verschiedene Systemchecks sowie dieser Nextcloud-Check angezeigt. Nach der Übernahme und Aktivierung der Services wird Ihr Nextcloud-Server mittels Checkmk bereits überwacht.

Mit einem weiteren, etwas umfangreicher einzurichtenden Check, lassen sich die KPIs der Nextcloudinstanz im Monitoring überprüfen. Erstellen Sie zuerst einen Ordner bspw. namens 300, der die implizite Durchführung des lokalen CHecks alle 300 Sekunden (5 Minuten) initiiert.

mkdir -p /usr/lib/check_mk_agent/local/300/

Legen Sie dann ein Bashskript an, dass wie folgt zu befüllen ist:

nano /usr/lib/check_mk_agent/local/300/nextcloudbenutzer.sh

Kopieren Sie alle nachfolgenden Zeilen hinein und passen nur die rot markierten Parameter an, Wichtig hierbei ist, dass der verwendete Benutzer (monitoring-benutzer) Mitglied der Administratorengruppe ist und aus Sicherheitsgründen 2FA aktiviert und ein App-Passwort verwendet wird!

#!/bin/bash
function NCUser1h () {
/usr/bin/curl -s https://<monitoring-benutzer>:"<APP-Password>"@<ihre-domain.de>/ocs/v2.php/apps/serverinfo/api/v1/info?format=json | /usr/bin/jq ".ocs.data.activeUsers.last1hour"
}

if [ $(NCUser1h) -lt 10 ]; then
        echo "0 \"Cloudbenutzer\" - In der letzten Stunde waren $(NCUser1h) Nextcloudbenutzer aktiv"
else
        echo "1 \"Cloudbenutzer\" - In der letzten Stunde waren $(NCUser1h) Nextcloudbenutzer aktiv"
fi
exit 0

Aktivieren Sie den lokalen Check im Checkmk:

chmod +x /usr/lib/check_mk_agent/local/300/nextcloudbenutzer.sh

Sobald Sie den Check am Host aktiviert haben wird es bspw. wie folgt im Monitoring dargestellt:

Ein Beispiel für BigBlueButton – Monitoring könnte wie folgt aussehen.

nano /usr/lib/check_mk_agent/local/bbb.py

Kopieren Sie den nachfolgenden text hinein:

#!/usr/bin/python3
import os
import sys
import socket
import hashlib
import requests
from collections import defaultdict
from xml.dom.minidom import parse, parseString
def getApiChecksum():
    # get API Scret and strip newline
    stream = os.popen('bbb-conf --secret | grep Secret: | awk -F":" \'{print $2}\' | sed -e "s/\s*//g" | sed -e "s/\\n//g"')
    sharedsecret = stream.read().rstrip()
    # assemble querystring + apisecret
    qstringwithsecret = "getMeetings" + sharedsecret
    # return SHA1 hash as API checksum
    return hashlib.sha1(qstringwithsecret.encode('utf-8')).hexdigest()
def getMeetingData(checksum):
    fqdn = socket.getfqdn()
    fullQueryUri = "https://"+fqdn+"/bigbluebutton/api/getMeetings?checksum="+checksum
    result = requests.get(fullQueryUri)
    return(result.status_code, result.text)
(status, xml) = getMeetingData(getApiChecksum())
checkName    = "BBB"
nagiosState  = 3
numMeetings  = 0
numAttendees = 0
numWithVideo = 0
numWithVoice = 0
numListeners  = 0
if status != 200:
    checkstring = str(nagiosState) + ' ' + checkName + " HTTP return code was not 200/OK"
    print(checkstring)
    sys.exit(nagiosState)
meetingdata = parseString(xml)
returncode=meetingdata.getElementsByTagName("returncode")[0]
returncode=returncode.firstChild.wholeText
if returncode != "SUCCESS":
    checkstring = str(nagiosState) + ' ' + checkName + " API returncode was not SUCCESS"
    print(checkstring)
    sys.exit(nagiosState)
# Dict for origins
origins = defaultdict(dict)
# get numbers from active meetings
#    p = m.getElementsByTagName("bbb-origin-server-name")[0]
meetings=meetingdata.getElementsByTagName("meeting")
for m in meetings:
    p = m.getElementsByTagName("meetingID")[0]
    origin = str(p.firstChild.wholeText)
    if ( str(dict(origins[origin])) == "{}" ): 
        origins[origin]['meetings'] = 0
        origins[origin]['attendees'] = 0
        origins[origin]['video'] = 0
        origins[origin]['voice'] = 0
        origins[origin]['listen'] = 0
    numMeetings += 1
    origins[origin]["meetings"] +=1
    p = m.getElementsByTagName("participantCount")[0]
    numAttendees += int(p.firstChild.wholeText) 
    origins[origin]['attendees'] += int(p.firstChild.wholeText)
    p = m.getElementsByTagName("listenerCount")[0]
    numListeners += int(p.firstChild.wholeText) 
    origins[origin]['listen'] += int(p.firstChild.wholeText)
    p = m.getElementsByTagName("voiceParticipantCount")[0]
    numWithVoice += int(p.firstChild.wholeText) 
    origins[origin]['voice'] += int(p.firstChild.wholeText)
    p = m.getElementsByTagName("videoCount")[0]
    numWithVideo += int(p.firstChild.wholeText) 
    origins[origin]['video'] += int(p.firstChild.wholeText)
perfdata = 'numMeetings=' + str(numMeetings) + '|numAttendees=' + str(numAttendees)
perfdata += '|numWithVoice=' + str(numWithVoice) + '|numWithVideo=' + str(numWithVideo)
perfdata += '|numListeners=' + str(numListeners)
checkstring  = "0 " + checkName + " " + perfdata 
checkstring += " [ServerSum M:" + str(numMeetings) 
checkstring += " Att:" + str(numAttendees) 
checkstring += " Vid:" + str(numWithVideo) 
checkstring += " Voi:" + str(numWithVoice)
checkstring += " Lis:" + str(numListeners)
checkstring += "] "
originstats = ""
for key in origins:
    originstats += "[" + key + " M:" +str(origins[key]["meetings"])
    originstats += " Att:" + str(origins[key]["attendees"])
    originstats += " Vid:" + str(origins[key]["video"])
    originstats += " Voi:" + str(origins[key]["voice"])
    originstats += " Lis:" + str(origins[origin]["listen"])
    originstats += "] "
checkstring += originstats
print(checkstring)
sys.exit(0)

gefolgt von

chmod +x /usr/lib/check_mk_agent/local/bbb.py

Im Monitoring stellt es sich dann wie folgt dar:

Achten Sie darauf, dass Ihre Hosts standardmäßig den TCP-Port 6556 benötigen, um mit dem Checkmk-Server zu kommunizieren. Die Verwendung von SNP oder SSH ist zudem auch möglich.

Viel Spaß und viel Erfolg mit Checkmk. Über Ihre Unterstützung (diese wird ordnungsgemäß versteuert!) würden Sich meine Zwillinge, meine Frau und ich sehr freuen!