checkmk query language als root via consolen script nutzen

reinhard@finalmedia.de Sun 27 Mar 2022 01:04:34 PM CEST

Zur Automatisierung ist es oft notwendig, nicht nur die CheckMK WebGui einsehen zu können, sondern die Auswertung scriptbasiert weiterzuverarbeiten. Dafür gibt es die check_mk query languange.

Zunächst sorgen wir dafür, dass wir auch als root einen eingeschränkten checkmk user account und dessen site verwenden können. dazu erstellen wir eine envdir und installieren die daemontools.

Dabei nehmen wir nun an, der OMD User hieße "erbsen". Das musst du natürlich überall anpassen.

Los gehts...

apt-get update && apt-get install daemontools

site="erbsen"

mkdir /root/checkmk_env_configdir
echo "/omd/sites/$site/" > /root/checkmk_env_configdir/HOME
echo "/omd/sites/$site/" > /root/checkmk_env_configdir/OMD_ROOT
echo "$site" > /root/checkmk_env_configdir/OMD_SITE
echo "$site" > /root/checkmk_env_configdir/USER
echo "/omd/sites/$site/lib/perl5/bin:/omd/sites/$site/local/bin:\
/omd/sites/$site/bin:/omd/sites/$site/local/lib/perl5/bin:\
/usr/local/sbin:/usr/local/bin:/usr/sbin:\
/usr/bin:/sb" > /root/checkmk_env_configdir/PATH

Nun können wir das nachfolgende Script verwenden, damit root mit dem alias "ckmk" Query Language Befehle als OMD site user ausführen kann.

cat << :::EOF::: > /root/chk_beispiele
#!/bin/sh
alias ckmk='envdir /root/checkmk_env_configdir envuidgid erbsen /bin/bash -c'

# alle tabellenspalten
ckmk 'lq "GET columns\nFilter: table = hosts\nColumns: name"'

# alle service ausgeben, deren status nicht OK ist (also ungleich 0)
ckmk 'lq "GET services\nColumns: state host_name description\nFilter: state != 0"'

# alles services listen, die "APT Updates" heißen (z.b. wenn das mk-apt plugin installiert ist)
ckmk 'lq "GET services\nColumns: host_name description state\nFilter: description = APT Updates"'

# aus dem plugin nur nur ausstehende normale listen
ckmk 'lq "GET services\nColumns: host_name description state\nFilter: description = APT Updates\nFilter: state = 1"'

# aus dem plugin nur ausstehende sicherheitsrelevante updates listen
ckmk 'lq "GET services\nColumns: host_name description state\nFilter: description = APT Updates\nFilter: state = 2"

:::EOF:::

Mit obigen Beispielen kannst du dir dann bauen, was du brauchst.

Du kannst dann wiederum so ein Script oder einen Befehle via ssh forced command auch an einen ssh pubkey finden und somit deine automatisierung vom monitoring abhängig machen. letztlich ohne die check_mk api zu benötigen.

Als Output-Format wird standardmäßig CSV verwendet. Du kannst aber auch json oder python und python3 wählen.

Hier eine Beispiel-Ausgabe für json, die sich dann z.B. mit jq weiterprozessieren lässt:

ckmk 'lq "GET services\nColumns: host_name description state\nFilter: description = APT Updates\nOutputFormat: json"'

Weiterführende Doku zur Query Language findest du unter: https://docs.checkmk.com/latest/en/livestatus.html

Weiterführend - Automatisch apt-updates ausrollen

Wenn du sicher bist, was du tust, kannst du das hier in deiner /root/.ssh/authorized_keys auf deinem checkmk OMD monitoring Server verwenden

restrict,command="unshare -n envdir /root/checkmk_env_configdir envuidgid erbsen /bin/bash -c 'lq \"GET services\nColumns: host_name\nFilter: description = APT Updates\nFilter: state != 0\"'" ssh-ed25519 AAAAC3... beispiel@beispiel 

Dann kannst du bei dir auf dem Host mit dem zugehörigen private key eine Verbindung zum monitoring aufbauen und bekommst damit letztlich die hostnamen als liste, auf der du wiederum z.b. mit parallel ssh befehle ausführen kannst

apt-get install pssh

ssh -T -i dein_beispielkey root@dein_monitoring_server | tr -dc "\n0-9a-z." | \
parallel-ssh --timeout 600 -i -h /dev/stdin "apt-get update && apt-get -y upgrade"

Hostgruppen

Zusätzlich kannst du im checkmk auch Hostgruppen definieren und diese Zuteilung dort im checkmk automatisiert an gewissen Tags, Ordner, Labels, und andere Bedingungen knüpfen. Nun kann es sein, dass du auch Hosts einer gewissen Gruppe listen willst. Das geht auch ohne query language:

Nehmen wir an, du hast eine Gruppe "intern" und "spezial" definiert und einen Regelsatz dazu. Dann listet dir das hier alle Hosts, die dieser Gruppe angehören.

Das ist z.B. Sinnvoll, wenn du dann darauf Updates oder weitere Scriptbasierte Änderungen über beide Gruppen ausrollen willst.

echo intern spezial | envdir /root/checkmk_env_configdir envuidgid erbsen /bin/bash -c 'tr -dc "0-9.a-z " | head -c 128 | xargs cmk -l

Farbe ins Spiel

Mit nachfolgendem Snippit kannst du alle Services listen und rot,grün,orange zeilenweise einfärben. Nach dem Status ERR,WARN,OK.

Beispiel in deiner authorized keys auf dem Monitoring Server

restrict,command="unshare -n envdir /root/checkmk_env_configdir envuidgid erbsen /bin/bash -c 'lq \"GET services\nColumns: state host_name description plugin_output perf_data\"'" ssh-ed25519 AAAAC...

Beispiel auf deinem Query Host, der über den privatekey verfügt

ssh -i ./all_services_key -T monitoring_server | \
tr ";" "\t" | cut -f 1,2,3,4 | \
sed 's/^2/\o33[31m/g;s/$/\o33[0m/g' | \
sed 's/^1/\o33[33m/g;s/$/\o33[0m/g' | \
sed 's/^0/\o33[32m/g;s/$/\o33[0m/g'

Wenn du generell Traffic sparen willst und nur fail services abfragen willst, dann verwende in deiner authorized keys:

restrict,command="unshare -n envdir /root/checkmk_env_configdir envuidgid erbsen /bin/bash -c 'lq \"GET services\nColumns: state host_name description plugin_output perf_data\nFilter: state != 0\"'"  ssh-ed25519 AAAAC...

Auf deinem Query Host kannst du das gleiche Script wie oben verwenden.

Hostmatrix in Console visualisieren

Eintrag in deiner authorized_keys

Matrix anhand des Host States (up/down/unknown)

restrict,command="unshare -n envdir /root/checkmk_env_configdir envuidgid erbsen /bin/bash -c 'lq \"GET hosts\nColumns: state host_name\"'" ssh-ed25519 AAAAC3...

Matrix anhand des Service States pro Host (ok/warn/fail)

restrict,command="unshare -n envdir /root/checkmk_env_configdir envuidgid erbsen /bin/bash -c 'lq \"GET hosts\nColumns: worst_service_state host_name\"'" ssh-ed25519 AAAAC3...

Script auf deinem Query-Host. Ausgabe in Konsole als 12er Matrix

echo
ssh -i ./dein_passendes_keyfile -T monitoring_server | \
cut -d";" -f1 | tr -d "\n" | fold -w 12 | tr "0123" "ABCD" | \
sed 's/A/\o33[42m \o33[0m/g' | \
sed 's/B/\o33[43m \o33[0m/g' | \
sed 's/C/\o33[41m \o33[0m/g' | \
sed 's/D/\o33[44m \o33[0m/g'
echo -e "\033[0m"
echo

Hostmatrix als PNG Grafik

Script auf deinem Query-Host. Ausgabe als PNG Grafik auf stdout. Realisiert mit den netpbm tools. (max. 16x16=256 Hosts)

apt-get install netpbm
#!/bin/bash
# reinhard@finalmedia.de
# So 27. Mär 19:42:33 CEST 2022
(
echo P2
echo 16 16
echo 6
ssh -i ./dein_hostmatrix_key -T monitoring_server | \
cut -d ";" -f1 | tr -dc "012" | fold -w 1 | tr "\n" " "
echo -n " "
yes 5 | head -n 524 | tr "\n" " "
) | head -c 524 | fold -w 32 | \
pgmtoppm -map <(echo P3 5 1 255 0 255 0 0 255 255 255 0 0 0 0 0 255 255 255) | \
pnmscale 16 | ppmtopcx -24bit | pcxtoppm | ppmmix 0.8 <(
# schachbrett, um daraus raster maske zu erzeugen und mit bild zu mixen
cat << EOF | ppmtopgm | pnmscale 16 | pgmtopbm -threshold | pgmedge | ppmtopcx -24bit | pcxtoppm
P1
16 16
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
EOF
) /dev/stdin | pnmtopng -

Das Ergebnis sieht dann Beispielsweise so aus, bei 24 fehlerfreien Hosts: