#!/bin/bash # Network Watchdog – generiert von Ansible # Scannt {{ watchdog_subnet }} auf {{ watchdog_iface }} alle {{ watchdog_cron_interval }} set -euo pipefail IFACE="{{ watchdog_iface }}" SUBNET="{{ watchdog_subnet }}" LOGFILE="/var/log/net-watchdog.log" WEBHOOK_URL="{{ watchdog_webhook_url }}" # Whitelist (generiert aus Ansible defaults/main.yml) declare -A KNOWN {% for host in watchdog_known_hosts %} KNOWN["{{ host.mac }}|{{ host.ip }}"]="{{ host.name }}" {% endfor %} QUIET="${1:-}" log() { local msg="$(date '+%Y-%m-%d %H:%M:%S') $1" echo "$msg" >> "$LOGFILE" [ "$QUIET" != "--quiet" ] && echo "$msg" } SCAN=$(/usr/sbin/arp-scan --interface="$IFACE" "$SUBNET" 2>/dev/null \ | grep -E '^[0-9]+\.' | awk '{print $2"|"$1}') UNKNOWN="" ALERT_COUNT=0 while IFS= read -r line; do [ -z "$line" ] && continue mac=$(echo "$line" | cut -d'|' -f1) ip=$(echo "$line" | cut -d'|' -f2) if [ -z "${KNOWN["${mac}|${ip}"]:-}" ]; then UNKNOWN+="⚠️ ${ip} (MAC: ${mac})\n" log "ALERT: Unbekannter Host ${ip} MAC=${mac}" ((ALERT_COUNT++)) fi done <<< "$SCAN" if [ "$ALERT_COUNT" -gt 0 ]; then log "SCAN: ${ALERT_COUNT} unbekannte Hosts!" if [ -n "$WEBHOOK_URL" ]; then curl -s -X POST "$WEBHOOK_URL" \ -H "Content-Type: application/json" \ -d "{\"event\":\"unknown_host\",\"subnet\":\"${SUBNET}\",\"count\":${ALERT_COUNT},\"details\":\"$(echo -e "$UNKNOWN" | tr '\n' ' ')\",\"timestamp\":\"$(date -Iseconds)\"}" \ >/dev/null 2>&1 || log "WARN: Webhook fehlgeschlagen" fi [ "$QUIET" != "--quiet" ] && echo -e "\n${UNKNOWN}" exit 1 else log "SCAN: OK – alle $(echo "$SCAN" | wc -l) Hosts bekannt" exit 0 fi