# checkbot in einer VM oder im Debian-LXC (Proxmox) betreiben Alle Dateien in diesem Ordner sind geschrieben, aber noch auf keinem System ausprobiert. Beim ersten Lauf Meldungen genau lesen und Fehler zurückmelden. ## Überblick ``` Browser --443--> Caddy (TLS, HSTS, /health nur intern) --127.0.0.1:8080--> uvicorn (1 Worker) --> SQLite | Checkmk-REST, Ollama, Telegram, Matrix <-+ (nur ausgehend) ``` | Pfad | Inhalt | Rechte | | --- | --- | --- | | `/opt/checkbot` | Code und `.venv` | root, für `checkbot` nur lesbar | | `/etc/checkbot` | `checkbot.env`, `master.key`, `session.secret` | Ordner 0750 root:checkbot, `checkbot.env` 0640, Schlüssel 0600 checkbot | | `/var/lib/checkbot` | SQLite-Datenbank | 0750 checkbot | | `/var/backups/checkbot` | tägliche DB-Backups | 0700 checkbot, Dateien 0600 | | `/etc/caddy/Caddyfile` | aus `Caddyfile.template` gerendert | root | | Datei | Zweck | | --- | --- | | `setup-lxc.sh` | Erstinstallation in VM oder LXC (idempotent; der Dateiname bleibt) | | `lib/preflight.sh` | Preflight-Prüfungen, genutzt von `setup-lxc.sh` und `first-run.sh` | | `update.sh` | Update nach `git pull` mit Backup und Health-Check | | `backup.sh`, `systemd/checkbot-backup.*` | tägliches Backup | | `checkbot-cli` | CLI als Benutzer `checkbot` (wird als `/usr/local/sbin/checkbot-cli` verlinkt) | | `systemd/checkbot.service`, `systemd/checkbot-lxc-relaxed.conf` | Dienst und Drop-In nur für unprivilegierte LXCs (in einer VM nicht nötig) | | `Caddyfile.template` | Reverse-Proxy | | `checkmk/checkbot-local-check` | Local Check für den Checkmk-Agent | | `nftables.conf` | optionale Firewall | | `checkbot.env.example` | Umgebungsdatei ohne Secrets | ## Installation in VM oder LXC Das Skript läuft ohne Zusatzoptionen in einer normalen Debian-12/13-VM (auch Ubuntu ab 22.04, Caddy kommt aus dem Distributions- oder dem offiziellen Caddy-Repository). Die strenge systemd-Sandbox der Unit gilt in der VM unverändert. LXC-Besonderheiten sind nur bei Bedarf aktiv: - Das Drop-In `checkbot-lxc-relaxed.conf` wird ausschließlich mit `--lxc-relaxed` installiert, nie automatisch. Das Skript erkennt Container über `systemd-detect-virt` (Fallback: `/run/systemd/container`, `/proc/1/environ`, CPU-Flag `hypervisor`) und gibt den Hinweis auf `--lxc-relaxed` nur im Container aus. In einer VM warnt `--lxc-relaxed` vor der Sandbox-Lockerung. - Zeitzone: `timedatectl`, sonst direkte Dateien; nur wenn beides scheitert, warnt das Skript. - Für eine VM entfällt Abschnitt 1 (Proxmox-LXC anlegen) und die Abschnitte zu unprivilegierten LXCs; `nftables.conf` ist in einer VM normal ladbar. ### Preflight `setup-lxc.sh` und `first-run.sh` prüfen vor der Arbeit (ohne Änderungen am System, ohne Secrets) und schreiben je Check `[ok]`, `[WARNUNG]` oder `[FEHLER]` mit Abhilfe. FEHLER bricht ab, WARNUNG nicht: | Check | FEHLER bei | WARNUNG bei | | --- | --- | --- | | Python | `python3` älter als 3.11 oder unlauffähig; `python3`/`venv`/`ensurepip` fehlt (bei `first-run.sh`) | `python3` oder `venv` fehlt bei `setup-lxc.sh` (wird per apt installiert) | | Freier Platz | weniger als 500 MB im Zielverzeichnis oder in `/tmp` (Konstante `PF_MIN_DISK_MB`) | Platz nicht ermittelbar | | Betriebssystem | nie | nicht Debian 12/13 oder Ubuntu ab 22.04 | | Umgebung | nie (nur Anzeige: VM, Container, Hardware) | nie | | pypi.org per HTTPS | nie | nicht erreichbar (Proxy-Hinweis) | | `CHECKMK_URL`, `OLLAMA_URL` (optional) | nie | Host:Port per TCP nicht erreichbar; ohne Variable übersprungen, ausgegeben wird nur Host:Port | Optionen beider Skripte: `--skip-preflight` (Prüfung überspringen) und `--preflight-only` (nur prüfen, nichts installieren). `first-run.sh` legt das Ergebnis als `preflight.txt` ins Archiv. ```bash CHECKMK_URL=https://checkmk.example.lan/site OLLAMA_URL=http://office.sysops.de:11434 deploy/first-run.sh --preflight-only sudo deploy/setup-lxc.sh --preflight-only ``` ## 1. LXC in Proxmox anlegen (entfällt bei einer VM) Auf dem Proxmox-Host (Template-Name vorher mit `pveam available --section system` prüfen, Container-ID, Storage, Bridge und Adressen anpassen): ```bash pveam update && pveam download local debian-12-standard_12.7-1_amd64.tar.zst pct create 210 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \ --hostname checkbot --unprivileged 1 --features nesting=1 \ --cores 1 --memory 1024 --swap 512 --rootfs local-lvm:8 \ --net0 name=eth0,bridge=vmbr0,ip=192.168.1.50/24,gw=192.168.1.1 \ --nameserver 192.168.1.1 --searchdomain example.lan \ --onboot 1 --start 1 ``` `nesting=1` braucht systemd für die Sandbox-Direktiven (PrivateTmp, ProtectSystem) in unprivilegierten Containern. Debian 13 funktioniert genauso (anderes Template). Der FQDN der UI (z.B. `checkbot.example.lan`) muss im DNS auf die Container-IP zeigen. ## 2. Installation Im Container als root: ```bash apt-get update && apt-get install -y git git clone /root/checkbot && cd /root/checkbot CHECKBOT_FQDN=checkbot.example.lan CHECKBOT_MONITOR_IP=192.168.1.10 deploy/setup-lxc.sh ``` `deploy/setup-lxc.sh --help` zeigt alle Optionen. Wichtige Parameter: | Parameter | Bedeutung | | --- | --- | | `CHECKBOT_FQDN` / `--fqdn` | Hostname der UI (Standard `hostname -f`) | | `CHECKBOT_MONITOR_IP` / `--monitor-ip` | Monitoring-Server(n), die `/health` per HTTPS abrufen dürfen (Komma-getrennt) | | `CHECKBOT_TLS_MODE` / `--tls-mode` | `internal` (Caddy-interne CA, Standard) oder `files` | | `CHECKBOT_TLS_CERT`, `CHECKBOT_TLS_KEY` | PEM-Dateien für `files` (Zertifikat der Unternehmens-CA, mit Kette) | | `CHECKBOT_TZ` / `--tz` | Systemzeitzone des LXC (Standard `Europe/Berlin`, geprüft gegen `/usr/share/zoneinfo`). Die UI zeigt Zeiten samt Kürzel (CET/CEST). Lässt sich die Zeitzone im unprivilegierten LXC nicht setzen, warnt das Skript und fährt fort | | `--lxc-relaxed` | gelockertes systemd-Drop-In (siehe unten) | | `--no-prompt` | nie nachfragen | Das Skript installiert Pakete (inkl. Caddy), legt Benutzer und Verzeichnisse an, kopiert den Code, baut die venv, erzeugt `master.key` und `session.secret` (bestehende bleiben), legt `checkbot.env` an (bleibt bestehen), installiert die Units, rendert das Caddyfile und startet den Dienst erst danach. Der erste Admin: mit Terminal fragt das Skript, sonst: ```bash checkbot-cli create-admin ``` Danach `https:///` öffnen, anmelden und den Setup-Assistenten durchlaufen. Ist Caddy nicht im Debian-Repository, richtet das Skript das offizielle Caddy-Repository mit Signaturprüfung ein und gibt den Fingerabdruck des Schlüssels aus. Mit `CHECKBOT_CADDY_KEY_FPR=` kann er fest vorgegeben werden. Scheitert das, bricht das Skript mit dem Verweis auf die manuelle Installation ab. ### TLS-Modi - `internal`: Caddy erzeugt eine eigene CA und stellt das Zertifikat aus. Browser und Clients müssen das Root-Zertifikat einmalig akzeptieren (siehe Fehlersuche). - `files`: eigenes Zertifikat der Unternehmens-CA. Das Skript kopiert die Dateien nach `/etc/caddy/certs/checkbot.{crt,key}` (Schlüssel 0640 root:caddy). Bei Erneuerung neue Dateien bereitstellen und `setup-lxc.sh` mit denselben Parametern erneut laufen lassen (oder die Dateien tauschen und `systemctl reload caddy`). ### Logging Der Bot schreibt Zeilen nach stderr, journald stempelt die Zeit (`journalctl -u checkbot`). Das Level steht in `/etc/checkbot/checkbot.env` als `CHECKBOT_LOG_LEVEL` (`DEBUG`, `INFO`, `WARNING`, `ERROR`, Standard `INFO`; ungültige Werte ergeben `INFO` plus Warnung), Änderung wirkt nach `systemctl restart checkbot`. Bekannte Secrets (Tokens, Checkmk-Secrets) sowie Muster wie `/bot/` und `Bearer ` werden aus Meldungen und Exception-Texten maskiert. Die Zeitzone (`CHECKBOT_TZ`) wird nur beim Setup gesetzt, siehe oben. ## 3. Erste Konfiguration in der UI - **Checkmk**: In Checkmk (Setup, Benutzer) einen Automation-User mit Rolle "Guest" bzw. einer Rolle mit reinem Lesezugriff auf Hosts und Services anlegen, Secret kopieren. In der UI URL der Site (inkl. Site-Name, z.B. `https://checkmk.example.lan/`), User und Secret eintragen und den Verbindungstest ausführen. - **Downtime (optional, standardmäßig aus)**: eigener Automation-User, der nur Downtimes setzen darf, mit eigenem Secret. Niemals das Secret des Lese-Users wiederverwenden. - **Telegram**: Bei `@BotFather` mit `/newbot` einen Bot anlegen und den Token eintragen. Chat-ID ermitteln: dem Bot (oder der Gruppe, in der er Mitglied ist) eine Nachricht schreiben und `https://api.telegram.org/bot/getUpdates` im Browser öffnen, `message.chat.id` ablesen (Gruppen-IDs sind negativ). Danach den Token aus dem Browserverlauf löschen. Allowlist der Telegram-User-IDs füllen, sonst sind Befehle und Buttons aus. - **Matrix**: Auf dem Homeserver einen Bot-User anlegen, Access-Token erzeugen (z.B. per Login-API oder Element unter Einstellungen, Hilfe, Access-Token), unverschlüsselten Raum anlegen, den Bot einladen und beitreten lassen, Raum-ID (`!abc:server`) eintragen. - **Ollama**: Host-URL (z.B. `http://office.sysops.de:11434`), bei Reverse-Proxy mit Authentifizierung das Token, bei interner CA das CA-Feld. Die beiden Modelle (Alarmtext, Agent) einstellen und testen. ## Erster Testlauf Vor dem ersten echten Betrieb die Tests im Test-LXC laufen lassen. `deploy/first-run.sh` braucht kein root, legt eine eigene Dev-venv an (nicht unter `/opt/checkbot`, dort liegen weder Tests noch Dev-Abhängigkeiten) und erledigt alles in einem Lauf: ```bash apt-get install -y python3-venv python3-pip # einmalig, als root cd ~/checkbot deploy/first-run.sh # optional: --venv --out ``` Ablauf: Preflight (siehe oben, `--skip-preflight` / `--preflight-only`), venv (Standard `$HOME/checkbot-test-venv`) anlegen, `pip install -r requirements-dev.txt`, `import app.main`, alle Jinja-Templates mit der App-Umgebung kompilieren, danach `pytest -q` **ohne** `-x`, damit alle Fehler in einer Runde zusammenkommen. Zum Schluss packt das Skript `first-run-.tar.gz` (in `--out`, Standard das aktuelle Verzeichnis) mit Preflight-Ergebnis (`preflight.txt`), pytest-Log, Import- und Template-Log, Python-Versionen, `pip freeze`, `uname -a` und der Git-Revision (falls ein Checkout vorliegt). Das Archiv enthält keine Umgebungsvariablen, Datenbanken, Schlüsseldateien und nichts aus `/etc/checkbot`. Das Archiv geht unverändert an den Entwickler zurück. Integrationstests (`-m integration`) laufen nie versehentlich mit, sie sind standardmäßig ausgeschlossen. ## 4. Update ```bash cd /root/checkbot && git pull && deploy/update.sh ``` Ablauf: DB-Backup, rsync, `pip install -r`, geänderte systemd-Units, Neustart, `/health`-Check mit bis zu 60 s Wartezeit. Der Check wertet die Datenbankprüfung aus. Nicht konfigurierte Teilchecks gelten nicht als Fehler. Schlägt das Update fehl, nennt das Skript das letzte Backup und den zuletzt ausgerollten Commit. Rollback: im Checkout `git checkout `, `deploy/update.sh` erneut. Reicht das nicht (Schema-Migration lief schon), Datenbank aus dem Backup zurückspielen (Abschnitt 5). Die Migrationen sind vorwärts gerichtet, ein altes Programm kann eine neuere Datenbank unter Umständen nicht lesen, deshalb ist das Backup vor jedem Update Pflicht. ## 5. Backup und Restore > **WICHTIG: `master.key` gehört nicht zusammen mit der Datenbank in dasselbe Backup.** Ohne `master.key` sind alle gespeicherten Secrets (Tokens, Passwörter) unbrauchbar, mit `master.key` neben der DB hebt jeder Zugriff aufs Backup die Verschlüsselung auf. Sichere `/etc/checkbot/master.key` und `session.secret` separat (Passwortmanager, Tresor) und die DB-Backups an einem anderen Ort. - `checkbot-backup.timer` läuft täglich um 03:15 (zufällig bis 15 min versetzt, holt Versäumtes nach) und schreibt `/var/backups/checkbot/checkbot-YYYYmmdd-HHMMSS.db` (0600) über die SQLite-Backup-API, also konsistent bei laufendem Dienst. Es bleiben 14 Stück (`CHECKBOT_BACKUP_KEEP`). - Manuell: `/opt/checkbot/deploy/backup.sh`. Status: `systemctl list-timers checkbot-backup.timer`, Log: `journalctl -u checkbot-backup`. - Kopiere die Backups zusätzlich aus dem Container heraus (Proxmox-Backup des gesamten LXC reicht, ist aber dann inklusive `master.key`, siehe oben). Restore: ```bash systemctl stop checkbot install -m 0600 -o checkbot -g checkbot /var/backups/checkbot/checkbot-.db /var/lib/checkbot/checkbot.db rm -f /var/lib/checkbot/checkbot.db-wal /var/lib/checkbot/checkbot.db-shm systemctl start checkbot ``` Restore-Test (ohne den Betrieb zu stören), auf einer Kopie: ```bash python3 -I -c "import sqlite3,sys; c=sqlite3.connect(sys.argv[1]); print(c.execute('PRAGMA integrity_check').fetchone()[0], c.execute('SELECT COUNT(*) FROM users').fetchone()[0], 'Benutzer')" \ /var/backups/checkbot/checkbot-.db ``` Erwartet: `ok` und eine plausible Benutzerzahl. Einen vollständigen Test machst du in einem zweiten Container oder lokal mit derselben `master.key`: DB und Schlüssel einspielen, Dienst starten, in der UI anmelden und prüfen, dass die Verbindungstests laufen (das beweist, dass die Secrets entschlüsselbar sind). Diesen Test nach der Einrichtung einmal durchführen. ## 6. Monitoring im Checkmk Den Checkmk-Agent installiert `setup-lxc.sh` nicht. **Variante A: Agent mit Local Check** (zeigt jeden Teilcheck als Service) 1. In der eigenen Checkmk-Site: Setup, Agents, Linux, das `.deb`-Paket herunterladen und im Container mit `apt-get install ./check-mk-agent_*.deb` installieren. 2. Host im Checkmk anlegen (IP des Containers), Service-Discovery ausführen. 3. Local Check installieren: ```bash install -m 0755 /opt/checkbot/deploy/checkmk/checkbot-local-check /usr/lib/check_mk_agent/local/checkbot-local-check ``` Für ein Intervall von 2 Minuten statt jeder Agent-Abfrage in `/usr/lib/check_mk_agent/local/120/` ablegen. Der Check braucht nur das System-`python3` und ruft `http://127.0.0.1:8080/health` direkt ab (nicht über Caddy). Andere URL: `CHECKBOT_HEALTH_URL`. Timeout 15 s, weil der Bot seine Backends selbst mit bis zu 10 s prüft. Services: `Checkbot_api`, `Checkbot_db`, `Checkbot_checkmk`, `Checkbot_checkmk_api`, `Checkbot_ollama`, `Checkbot_poller`, `Checkbot_telegram`, `Checkbot_matrix`. Bewertung (Entscheidung): | Lage im `/health` | Status | | --- | --- | | Teilcheck ok | OK | | Telegram/Matrix fehlen im JSON (in der UI deaktiviert) | OK, "deaktiviert" | | `nicht konfiguriert` (Checkmk, Ollama, Poller, aktivierter Chat-Adapter, `checkmk_api` ohne Checkmk-Konfiguration oder "noch nicht gelaufen") | WARN: der Bot ist ohne Konfiguration nicht voll funktionsfähig, aber nichts ist kaputt. Vor der Einrichtung ist WARN erwartbar | | Fehler, Timeout, Poller-Zyklus überfällig, Selbsttest `abweichend` oder `fehler` (`checkmk_api`) | CRIT | | Bot nicht erreichbar oder ungültige Antwort | CRIT für alle Services | `Checkbot_checkmk_api` liest nur den zuletzt gespeicherten Selbsttest-Lauf (siehe UI `/selftest`, Phase 6d), macht selbst keinen eigenen API-Aufruf. "noch nicht gelaufen" (kurz nach dem Start) zählt wie "nicht konfiguriert" als WARN. **Variante B: Active Check "HTTP"** auf `https:///health`, erwarteter Status 200. Der Server braucht Zugriff (Monitoring-IP in `CHECKBOT_MONITOR_IP`) und muss der Caddy-CA vertrauen, sonst Zertifikatsprüfung ausschalten. Achtung: `/health` liefert 503, solange irgendein Teilcheck nicht ok ist, auch "nicht konfiguriert". Ein WARN/CRIT ist vor der vollständigen Einrichtung also normal, und die Detailtexte bekommt man nur im Body. ## 7. Firewall Die Regeln in `nftables.conf` (Variablen oben anpassen, mit `nft -c -f` prüfen). In unprivilegierten LXCs lässt sich nftables oft nicht laden (fehlende Rechte für Netfilter im Container). Dann dieselben Regeln in der Proxmox-Firewall abbilden: Firewall am Datacenter, am Host und am Container (Reiter Firewall des CT) aktivieren, Eingangs-Policy DROP, Ausgangs-Policy DROP, dazu die Regeln: | Richtung | Aktion | Protokoll | Quelle / Ziel | Port | Zweck | | --- | --- | --- | --- | --- | --- | | IN | ACCEPT | tcp | Quelle Admin-Netz | 22 | SSH | | IN | ACCEPT | tcp | Quelle internes Netz | 443 | UI (HTTPS) | | IN | ACCEPT | tcp | Quelle internes Netz | 80 | nur HTTP-zu-HTTPS-Redirect (optional) | | IN | ACCEPT | tcp | Quelle Monitoring-Server | 443 | `/health` (Active Check) | | IN | ACCEPT | tcp | Quelle Monitoring-Server | 6556 | Checkmk-Agent (entfällt bei SSH-Agent) | | IN | ACCEPT | icmp | beliebig | - | Ping | | OUT | ACCEPT | udp/tcp | DNS-Server | 53 | DNS | | OUT | ACCEPT | udp | NTP-Server | 123 | Zeit | | OUT | ACCEPT | tcp | beliebig (oder Checkmk, Ollama-Proxy, api.telegram.org, Homeserver) | 443 | HTTPS-Ziele, apt | | OUT | ACCEPT | tcp | Ollama-Host | 11434 | Ollama direkt | | OUT | ACCEPT | icmp | beliebig | - | Ping | Weitere ausgehende Ziele (Checkmk per HTTP, Matrix auf 8448) bei Bedarf ergänzen. Telegram nutzt `api.telegram.org` auf 443, die IPs wechseln, deshalb dort nicht auf IPs einschränken. ## 8. Fehlersuche ```bash systemctl status checkbot journalctl -u checkbot -n 100 --no-pager # App journalctl -u caddy -n 100 --no-pager # Proxy und Zugriffslog curl -s http://127.0.0.1:8080/health # direkt, ohne Caddy ``` | Symptom | Ursache und Abhilfe | | --- | --- | | Dienst startet nicht, "assertion failed ... master.key" | `/etc/checkbot/master.key` fehlt. Aus der separaten Sicherung zurückspielen (0600, Besitzer checkbot). Nur bei einer Neuinstallation `setup-lxc.sh` erneut ausführen, das fehlende Schlüssel neu erzeugt (neue Schlüssel machen bestehende DB-Secrets unbrauchbar) | | Exit-Code 217/USER | Benutzer `checkbot` fehlt, `setup-lxc.sh` erneut ausführen | | Exit-Code 226/NAMESPACE, 218/CAPABILITIES, 228/SECCOMP | Sandbox-Direktiven im unprivilegierten LXC nicht erlaubt, siehe unten | | Exit-Code 200/CHDIR oder 203/EXEC | `/opt/checkbot` oder `.venv` fehlt, `setup-lxc.sh` bzw. `update.sh` ausführen | | `/health` über Caddy: 403 | Absicht. Nur 127.0.0.1 und `CHECKBOT_MONITOR_IP`; Setup mit der richtigen IP erneut ausführen | | Login klappt nicht, kein Cookie | App ist über HTTP statt HTTPS aufgerufen (Secure-Cookie), immer `https://` verwenden | | Browser warnt vor dem Zertifikat | Caddy-interne CA, siehe unten | | Checkmk-Test: SSL-Fehler | Checkmk nutzt eine interne CA: Die CA-Datei auf den LXC legen und in der UI unter Checkmk im Feld "CA-Datei" eintragen (lesbar für den Benutzer `checkbot`). Für andere Ziele mit interner CA (z.B. Matrix-Homeserver) alternativ CA nach `/usr/local/share/ca-certificates/`, `update-ca-certificates`, `SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt` in `checkbot.env` aktivieren und `systemctl restart checkbot` (Annahme: httpx wertet `SSL_CERT_FILE` aus) | | Caddy lädt nicht | `journalctl -u caddy`; das Skript stellt die vorherige Datei `/etc/caddy/Caddyfile.bak` wieder her | ### Unprivilegierte LXCs: systemd-Direktiven Zuerst im Proxmox-Host `pct set --features nesting=1` und den Container neu starten. Hilft das nicht, verursachen meist diese Direktiven die Exit-Codes 218, 226 oder 228: | Direktive | typischer Fehler | | --- | --- | | `ProtectSystem`, `ProtectHome`, `PrivateTmp`, `ReadWritePaths`, `RestrictNamespaces` | 226/NAMESPACE | | `ProtectKernelTunables/Modules/Logs`, `ProtectControlGroups` | 226/NAMESPACE | | `CapabilityBoundingSet` | 218/CAPABILITIES | | `SystemCallFilter`, `RestrictSUIDSGID`, `LockPersonality` | 228/SECCOMP | `systemctl status checkbot` und `journalctl -u checkbot` nennen die Direktive meist im Klartext. Abhilfe: `setup-lxc.sh --lxc-relaxed` erneut ausführen oder das Drop-In `systemd/checkbot-lxc-relaxed.conf` manuell nach `/etc/systemd/system/checkbot.service.d/lxc-relaxed.conf` kopieren (das Skript legt es auch für den Backup-Dienst an). Anschließend nur die Zeilen im Drop-In stehen lassen, die nötig sind. Die Datei überschreibt die Direktiven der Unit, `systemctl daemon-reload && systemctl restart checkbot` nicht vergessen. ### Zertifikatsvertrauen für die Caddy-CA Das Root-Zertifikat liegt im Container unter `/var/lib/caddy/.local/share/caddy/pki/authorities/local/root.crt` (öffentlich, enthält keinen Schlüssel). Verteilen: - Debian/Ubuntu-Clients: `cp root.crt /usr/local/share/ca-certificates/checkbot-caddy.crt && update-ca-certificates` - Windows: als Administrator `certutil -addstore -f Root root.crt` oder per Gruppenrichtlinie in "Vertrauenswürdige Stammzertifizierungsstellen" - Firefox: eigener Speicher, Einstellungen, Zertifikate, Importieren (oder Richtlinie `ImportEnterpriseRoots`) - Checkmk-Server (für den Active Check): Zertifikat unter Setup, Allgemeine Einstellungen, "Site management", "Trusted certificate authorities for SSL" eintragen Besser für den Dauerbetrieb: Modus `files` mit einem Zertifikat der Unternehmens-CA, der Clients ohnehin vertrauen. ## 9. Sicherheitscheckliste - [ ] Nach außen offen sind nur 443 (und 80 für den Redirect) aus dem internen Netz und SSH aus dem Admin-Netz; uvicorn lauscht nur auf 127.0.0.1 (`ss -tlnp`) - [ ] `/etc/checkbot` 0750 root:checkbot, `master.key` und `session.secret` 0600 checkbot, `checkbot.env` 0640 - [ ] `/opt/checkbot` gehört root, `checkbot` kann dort nichts schreiben - [ ] `master.key` und `session.secret` sind getrennt von den DB-Backups gesichert - [ ] `/health` über Caddy nur von localhost und Monitoring-IP (von einem anderen Rechner testen: 403) - [ ] Automation-User in Checkmk hat nur Lese-Rolle; ein eventueller Downtime-User ist ein eigener User mit eigenem Secret, Downtime-Funktion nur bei Bedarf aktiv - [ ] Telegram-Allowlist und Matrix-Allowlist sind gefüllt, nur Admins haben Admin-Rolle, TOTP für Admins aktiv - [ ] Den Telegram-Token nie in Browserverlauf oder Chat stehen lassen; bei Verdacht Token in BotFather erneuern - [ ] Der Dienst läuft mit genau einem Worker (Rate-Limiter, TOTP-Einrichtung, Downtime-Bestätigungen liegen im Prozessspeicher) - [ ] Zugriffslog (`journalctl -u caddy`) enthält keine Query-Strings, Cookies, Authorization-Header (Stichprobe) - [ ] Updates des Containers: `unattended-upgrades` oder regelmäßig `apt-get upgrade`; danach prüfen, dass `checkbot` und `caddy` laufen