#!/bin/bash
# Wächter 1 – Software-Wächter auf dem Server selbst (läuft alle 2 Minuten per systemd-Timer)
# Prüft: Webseite/Dienst antwortet, Zertifikat noch > 14 Tage gültig, Platte < 90 % voll, Temperatur, Container laufen.
# Bei Fehler: einmal selbst heilen (Dienst/Container neu starten), dann melden – an deinen eigenen ntfy-Server oder per Mail.
# Einstellungen in /etc/default/waechter (siehe unten), nichts davon steht im Skript.
set -uo pipefail
[ -r /etc/default/waechter ] && . /etc/default/waechter
URLS=${URLS-"https://example.org/"}            # Leerzeichen-getrennt
DIENSTE=${DIENSTE-"nginx"}                      # systemd-Dienste, die laufen müssen
CONTAINER=${CONTAINER-""}                       # Docker-Container, die laufen müssen
MELDEN=${MELDEN-""}                             # z. B. https://ntfy.example.org/mein-server  (eigener ntfy) – leer: nur Journal
MAIL=${MAIL-""}                                 # z. B. admin@example.org (braucht ein funktionierendes 'mail')
STAND=${STAND-/var/lib/waechter}; mkdir -p "$STAND"

melden() {
    local text="$1" schluessel; schluessel=$(echo "$text" | md5sum | cut -c1-12)
    # dieselbe Meldung höchstens einmal pro Stunde
    if [ -e "$STAND/$schluessel" ] && [ $(( $(date +%s) - $(stat -c %Y "$STAND/$schluessel") )) -lt 3600 ]; then return; fi
    touch "$STAND/$schluessel"
    logger -t waechter "$text"
    [ -n "$MELDEN" ] && curl -fsS -m 10 -H "Title: Wächter $(hostname)" -d "$text" "$MELDEN" >/dev/null 2>&1
    [ -n "$MAIL" ] && echo "$text" | mail -s "Wächter $(hostname)" "$MAIL" 2>/dev/null
}

for dienst in $DIENSTE; do
    systemctl is-active -q "$dienst" || { systemctl restart "$dienst"; sleep 3
        systemctl is-active -q "$dienst" && melden "$dienst war aus – neu gestartet" || melden "$dienst startet nicht!"; }
done
for c in $CONTAINER; do
    [ "$(docker inspect -f '{{.State.Running}}' "$c" 2>/dev/null)" = true ] || { docker start "$c" >/dev/null 2>&1
        melden "Container $c lief nicht – Start versucht"; }
done
for url in $URLS; do
    code=$(curl -s -o /dev/null -m 15 -w '%{http_code}' "$url")
    [[ "$code" =~ ^(2|3) ]] || melden "$url antwortet nicht richtig (HTTP $code)"
    host=$(echo "$url" | sed -E 's#https?://([^/:]+).*#\1#')
    ende=$(echo | openssl s_client -servername "$host" -connect "$host:443" 2>/dev/null | openssl x509 -noout -enddate 2>/dev/null | cut -d= -f2)
    if [ -n "$ende" ]; then
        tage=$(( ( $(date -d "$ende" +%s) - $(date +%s) ) / 86400 ))
        [ "$tage" -lt 14 ] && melden "Zertifikat von $host läuft in $tage Tagen ab"
    fi
done
voll=$(df --output=pcent / | tail -1 | tr -dc 0-9); [ "$voll" -ge 90 ] && melden "Systemplatte zu $voll % voll"
if [ -r /sys/class/thermal/thermal_zone0/temp ]; then
    t=$(( $(cat /sys/class/thermal/thermal_zone0/temp) / 1000 )); [ "$t" -ge 80 ] && melden "Temperatur $t °C"
fi
exit 0
