ops-jrz1/scripts/cpu-watchdog

44 lines
1.2 KiB
Bash
Executable file

#!/run/current-system/sw/bin/bash
# cpu-watchdog - Detect sustained CPU abuse, kill after 5 consecutive violations
# Runs every minute via systemd timer
set -euo pipefail
# NixOS paths
PATH="/run/current-system/sw/bin:$PATH"
THRESHOLD=180 # 180% CPU (almost 2 cores)
MAX_STRIKES=5
COUNTDIR="/var/lib/cpu-watchdog"
mkdir -p "$COUNTDIR"
for homedir in /home/*; do
user=$(basename "$homedir")
# Skip if not a real user
id "$user" &>/dev/null || continue
# Get total CPU usage for user
pct=$(ps -u "$user" -o %cpu= 2>/dev/null | awk '{s+=$1}END{print int(s)}' | tr -d '[:space:]' || echo 0)
pct=${pct:-0}
[[ "$pct" =~ ^[0-9]+$ ]] || pct=0
if [ "$pct" -gt "$THRESHOLD" ]; then
# Increment strike counter
count=$(cat "$COUNTDIR/$user" 2>/dev/null || echo 0)
count=$((count + 1))
echo "$count" > "$COUNTDIR/$user"
logger -t cpu-watchdog "User $user at ${pct}% CPU (strike $count/$MAX_STRIKES)"
if [ "$count" -ge "$MAX_STRIKES" ]; then
killswitch "$user" "sustained CPU abuse (${pct}%)"
rm -f "$COUNTDIR/$user"
fi
else
# Reset counter if below threshold
rm -f "$COUNTDIR/$user"
fi
done