feat(benachrichtigung): E-Mail und Webhook bei Drift und Ablauf (#028)

Drift, ablaufende und abgelaufene Schluessel, unerreichbare Hosts und
geaenderte Host-Keys sollen auffallen, ohne dass jemand taeglich in die
Oberflaeche schaut. Versand per SMTP (Microsoft 365, STARTTLS) und per
Webhook mit HMAC-Signatur, eingestellt unter /einstellungen.

Die Anlaesse liest der Worker aus der Datenbank, statt sie im Abgleich
auszuloesen: der Abgleich-Ablauf bleibt unberuehrt, und ein verpasster
Lauf holt sich der naechste. Ein Versandprotokoll (Zustellung) mit
Anlass-Fingerabdruck verhindert Doppelmeldungen und haelt Fehlschlaege
fuer begrenzte Wiederholungen fest. Taeglich eine Zusammenfassung,
geaenderte Host-Keys im Fuenf-Minuten-Takt sofort.

Versand und Testnachricht laufen im Worker, damit der Webprozess keinen
Weg zu Mailserver oder Webhook-Ziel braucht. Passwort und Geheimnis
liegen nur verschluesselt in der Datenbank; die Seite zeigt "gesetzt".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-12 16:54:43 +02:00
co-authored by Claude Opus 5.5
parent 83bd9e0922
commit 8f5b31c0cb
26 changed files with 3243 additions and 12 deletions
+8 -1
View File
@@ -64,6 +64,9 @@ services:
SSHKV_OIDC_GROUP_ADMIN: ${SSHKV_OIDC_GROUP_ADMIN:-sshkv-admins}
SSHKV_OIDC_GROUP_OPERATOR: ${SSHKV_OIDC_GROUP_OPERATOR:-sshkv-operators}
SSHKV_OIDC_GROUP_READER: ${SSHKV_OIDC_GROUP_READER:-sshkv-readers}
# Nur zur Anzeige unter /einstellungen; ausgefuehrt werden die Zeitplaene im Worker.
SSHKV_SYNC_CRON: ${SSHKV_SYNC_CRON:-30 2 * * *}
SSHKV_MELDUNG_CRON: ${SSHKV_MELDUNG_CRON:-0 7 * * *}
# Absichtlich KEIN Master-Key: eine Luecke im Webprozess allein entschluesselt keine
# Private Keys. Nach aussen braucht er nur den OIDC-Anbieter.
ports:
@@ -94,9 +97,13 @@ services:
SSHKV_APP_SECRET: ${SSHKV_APP_SECRET}
SSHKV_MASTER_KEY_FILE: /run/secrets/master_key
SSHKV_SYNC_CRON: ${SSHKV_SYNC_CRON:-30 2 * * *}
# Benachrichtigungen (#028): taegliche Zusammenfassung; Links in den Nachrichten zeigen
# auf SSHKV_APP_URL. Den Weg zu Mailserver und Webhook-Ziel hat der Worker ueber "aussen".
SSHKV_MELDUNG_CRON: ${SSHKV_MELDUNG_CRON:-0 7 * * *}
SSHKV_APP_URL: ${SSHKV_APP_URL}
secrets:
- master_key
# Der Worker braucht die Datenbank und den Weg zu den Hosts.
# Der Worker braucht die Datenbank und den Weg zu den Hosts (und zu Mailserver/Webhook).
networks: [datenbank, aussen]
healthcheck:
test: ["CMD-SHELL", "pgrep -f dist/worker.mjs > /dev/null"]