checkbot

Bot für Checkmk. Er liest den Zustand per REST-API, lässt Probleme von einem externen Ollama analysieren und meldet sie in Telegram und/oder Element (Matrix). Betrieb und Einstellungen laufen über eine deutsche Web-UI. Gedacht für einen Debian-LXC.

Stand: Entwicklung. Der Code ist geschrieben, aber noch nicht ausgeführt oder gegen eine echte Checkmk-, Ollama- oder Telegram-Instanz getestet. Die Statusspalte unten sagt, was woran ist.

Was der Bot kann

Alarme melden

  • Fragt Checkmk alle 30 s ab (einstellbar) und erkennt neue Probleme, Statuswechsel (WARN/CRIT/UNKNOWN), Recoveries und Flapping.
  • Meldet nur Hard-States, optional erst nach einer Mindestdauer.
  • Respektiert Downtimes: Services in Downtime lösen keine Nachricht aus und erscheinen im Verlauf als "unterdrückt".
  • Bündelt Alarme eines Hosts zu einer Nachricht und begrenzt den Durchsatz, damit eine Alarmflut den Chat und Ollama nicht überrollt.
  • Fällt Ollama aus, kommt der Rohalarm trotzdem sofort. Die Analyse wird nachgereicht oder als "KI nicht verfügbar" markiert.

KI-Analyse

  • Pro Problem kurze Analyse auf Deutsch (max. 8 Zeilen): Zusammenfassung, wahrscheinliche Ursache, nächster Prüfschritt.
  • Kontext: Host, Service, Plugin-Output, letzte Statuswechsel, Downtime-Info.
  • Plugin-Output gilt als nicht vertrauenswürdig. Er wird abgegrenzt, gekürzt und bereinigt, und die KI kann nichts auslösen.

Chat (Telegram und Element)

  • Beide Backends parallel, einzeln abschaltbar.

  • Matrix läuft direkt über die Client-Server-API (httpx, kein matrix-nio, keine E2EE-Abhängigkeiten). Der Alarmraum muss unverschlüsselt sein, der Bot-User braucht einen Access-Token und muss dem Raum beigetreten sein. Die Analyse kommt per m.replace-Edit.

  • Routing (UI /routing): Regeln mit Host-/Service-Glob, Mindest-Schweregrad, Alarmarten und Zielen (Backend plus Chat-ID bzw. Raum-ID). Regeln gelten von oben nach unten, jede passende fügt ihre Ziele hinzu, optional mit Stopp nach Treffer. Passt keine Regel, gehen Alarme an die Standardziele aller aktivierten Backends. Alarme eines Hosts mit gleicher Zielmenge werden zu einer Nachricht gebündelt.

  • Stummschaltung (UI /mutes): Host-/Service-Glob mit Ablauf (30 min bis 24 h oder freie Minuten) und Grund. Passende Probleme, Flapping und Recoveries werden nicht gemeldet und im Verlauf als unterdrückt (Stummschaltung) geführt. Abgelaufene Stummschaltungen räumt der Bot selbst auf.

  • Der Versand läuft über eine Warteschlange (max. 1000 Events, bei Überlauf wird das älteste verworfen), ein langsames Chat-Backend bremst den Poller nicht.

  • Rohalarm zuerst, die Analyse ersetzt oder ergänzt die Nachricht per Edit.

  • Befehle für Allowlist-User (Telegram mit /, Element mit !):

    Befehl Wirkung
    help, status, problems Hilfe, Zähler, Liste der Probleme
    host <name> Services eines Hosts
    explain <host> <service> KI-Analyse über den Agenten
    ask <frage> freie Frage an den Agenten
    mute <host> [service] <dauer> [grund] Bot-lokale Stummschaltung
    downtime <host> <service> <dauer> [kommentar] Checkmk-Downtime, nur nach Bestätigung
    confirm <code>, cancel <code> Downtime bestätigen oder abbrechen (vor allem für Element)

    Dauer: 30m, 2h, 1d, 1h30m oder 90 (Minuten). Als Antwort auf eine Alarmnachricht genügt /mute 2h bzw. !mute 2h, der Bot ordnet die Nachricht über den Verlauf dem Host und Service zu. Enthält die Nachricht mehrere Services, nennt der Bot den Befehl mit expliziten Angaben.

  • Telegram: Der Bot liest per getUpdates (Long-Polling, Offset persistent) mit Nachrichten und Button-Klicks. Beim allerersten Start wird der Rückstand ignoriert. Antworten kommen als Reply auf die Befehlsnachricht.

  • Element: Der Bot liest per /sync nur den konfigurierten Raum. Beim ersten Start wird nur das Sync-Token geholt (keine Historie), das Token liegt danach in der Datenbank. Eigene Nachrichten, Edits und Reply-Zitate werden ignoriert bzw. entfernt.

  • Alarm-Buttons (Telegram, nur mit gefüllter Allowlist): "2 h stumm" und "Tiefenanalyse", dazu "Downtime 2 h" wenn die Downtime-Funktion aktiv ist. Sie erscheinen bei Einzelalarmen, nicht bei gebündelten Nachrichten und nicht bei Recoveries. In Element steht stattdessen der Hinweis "Antwort mit !mute 2h zum Stummschalten".

  • Ruhigstellen:

    • mute: der Bot meldet einen Service für eine Dauer nicht mehr (maximal 7 Tage). Checkmk bleibt unberührt.
    • downtime: setzt eine echte Service-Downtime in Checkmk und ist die einzige Schreibaktion des Bots. Absicherung:
      1. Standardmäßig aus, Schalter in der UI unter "Downtime".
      2. Eigener Checkmk-User und eigenes Secret (verschlüsselt gespeichert), getrennt vom Lese-User.
      3. Maximaldauer einstellbar (Standard 24 h, harte Obergrenze 168 h), längere Anfragen werden abgelehnt.
      4. Der Bot zeigt Host, Service, Dauer und Kommentar und wartet 120 s auf die Bestätigung durch denselben Absender (Telegram: Buttons, Element: !confirm <code>). Der Code ist zufällig und nur einmal gültig.
      5. Nur Allowlist-User, Agent und KI haben keinen Zugriff.
      6. Anfrage, Bestätigung, Abbruch, Ablauf, Ablehnung und Checkmk-Fehler stehen im Audit-Log (Sender, Backend, Host, Service, Dauer).

Agent für Fragen

  • /ask, /explain und der Alarm-Button "Tiefenanalyse" nutzen einen Tool-Loop mit fünf festen Lese-Tools (get_service_status, get_host_services, get_state_history, get_downtimes, get_problems).
  • Maximal 6 Schritte und 90 s pro Anfrage. Jeder Tool-Aufruf steht im Audit-Log (agent.tool).
  • Agent-Ansicht (UI /agent, nur Admins): Liste der letzten Läufe mit Zeit, Absender, Befehl, Frage, Schrittzahl und Ergebnis. Die Detailseite zeigt pro Lauf Frage, Antwort und jeden Schritt (Tool, Argumente, gekürztes Ergebnis, Dauer, Fehler) sowie den Abbruchgrund. Tokens und Secrets werden vor dem Speichern maskiert.

Web-UI

  • Anmeldung mit lokalen Nutzern (Argon2), optional TOTP. Rollen admin und viewer.
  • Einstellungen mit Verbindungstest: Checkmk, Ollama, Telegram, Matrix, Checkmk Downtime. Dazu der Bereich Alarmierung (Abfrageintervall, Mindestdauer, Bündelungsfenster, KI-Analysen pro Minute).
  • Setup-Assistent beim ersten Start, Dashboard mit Live-Status, Alarmverlauf, Audit-Log, Benutzerverwaltung.
  • Routing und Stummschaltungen (Admins bearbeiten, Viewer sehen). Geplant: Prompts mit Versionierung, Rollback und Testbereich.
  • Tokens und Secrets liegen verschlüsselt in der Datenbank und werden in der UI nie wieder angezeigt.

Architektur

Checkmk (REST-API)  <----  Poller  ---->  Alarm-Pipeline  ---->  Telegram / Element
                                                |
                                                +---->  Ollama (extern)

Web-UI (FastAPI, Jinja2)  ----  SQLite (Einstellungen, Verlauf, Audit, Nutzer)
  • Der Bot hört nur mit der UI (hinter Caddy mit HTTPS). Alarme kommen per Polling herein, es gibt keinen offenen Alarm-Port.
  • Ausgehend: Checkmk, Ollama, Telegram, Matrix.

Status

Bereich Stand
Phase 1: Secret-Verschlüsselung, SQLite, Checkmk- und Ollama-Client, /health Code geschrieben, ungetestet
Phase 2: Login, Rollen, TOTP, Einstellungen mit Verbindungstest, Audit, CLI Code geschrieben, ungetestet
Phase 3: Poller, Alarm-Pipeline, Telegram, Alarmverlauf Code geschrieben, ungetestet
Phase 4: Matrix-Adapter, Routing, Stummschaltung in der UI Code geschrieben, ungetestet
Phase 5: Befehle, mute/downtime, Agent-Loop, Listener, Agent-Ansicht Code geschrieben, ungetestet
Phase 6: Prompt-Versionierung, Testbereich, Retention geplant
Phase 7: Deployment (setup-lxc.sh, Caddy, systemd, Backup, Checkmk-Local-Check) Dateien geschrieben, nicht auf einem System ausprobiert
Phase 8: Integrationstests geplant

Die Checkmk-Spaltennamen und der Downtime-Endpunkt sind Annahmen aus der Dokumentation und noch nicht an einer echten Instanz geprüft.

Deployment

Betrieb im Debian-LXC (Proxmox) mit Caddy, systemd, täglichem Backup und Checkmk-Local-Check: siehe deploy/README.md. Einstieg: sudo deploy/setup-lxc.sh aus einem Checkout, Updates mit sudo deploy/update.sh.

Schnellstart (manuell, ohne Setup-Skript)

Voraussetzung: Python 3.11+, Zugriff auf Checkmk 2.3+ (Automation-User mit Lese-Rolle) und auf einen Ollama-Host.

python3 -m venv .venv && .venv/bin/pip install -r requirements.txt

export CHECKBOT_CONFIG_DIR=./etc CHECKBOT_DB=./checkbot.db CHECKBOT_SECURE_COOKIES=0
.venv/bin/python -m app.cli gen-keys
.venv/bin/python -m app.cli create-admin
.venv/bin/uvicorn app.main:create_app --factory --host 127.0.0.1 --port 8080

Danach http://127.0.0.1:8080 öffnen, anmelden und im Setup Checkmk und Ollama eintragen.

CHECKBOT_SECURE_COOKIES=0 gehört nur in lokale Tests ohne HTTPS. Im Betrieb läuft die UI hinter Caddy mit HTTPS.

Dateien und Umgebungsvariablen

Variable Standard Bedeutung
CHECKBOT_CONFIG_DIR /etc/checkbot enthält master.key und session.secret (chmod 600)
CHECKBOT_DB /var/lib/checkbot/checkbot.db SQLite-Datenbank
CHECKBOT_BIND_HOST 127.0.0.1 Bind-Adresse
CHECKBOT_BIND_PORT 8080 Port
CHECKBOT_SECURE_COOKIES 1 Session-Cookie nur über HTTPS

Alles andere (Checkmk, Ollama, Chat-Backends, Limits) wird in der UI gesetzt.

CLI

Befehl Zweck
python -m app.cli gen-keys legt master.key und session.secret an, überschreibt nichts
python -m app.cli create-admin [name] legt den ersten Admin an
python -m app.cli set-password <name> setzt ein Passwort zurück

Geht master.key verloren, sind alle in der Datenbank gespeicherten Secrets unbrauchbar. Sichere die Datei getrennt von der Datenbank.

Sicherheit

  • Der Bot liest Checkmk standardmäßig nur. Die einzige Schreibaktion ist die optionale Downtime, mit eigenem Checkmk-User, Bestätigung und Audit-Eintrag.
  • KI und Agent haben keine Schreib-Tools.
  • CSRF-Schutz, Sicherheits-Header mit strenger CSP, Rate-Limit beim Login, Sitzungen werden beim Passwortwechsel ungültig.
  • Das Audit-Log enthält nie Secret-Werte.

Entwicklung

  • Tests: pip install -r requirements-dev.txt, dann pytest.
  • Der Plan und alle Entwurfsentscheidungen stehen in CLAUDE.md.
  • Code-Kommentare nur bei echtem WHY, Konstanten statt Magic Strings.
S
Description
No description provided
Readme
822 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 91.2%
HTML 4.6%
Shell 3.3%
CSS 0.7%
JavaScript 0.2%