Files

65 lines
4.1 KiB
Bash

#!/bin/bash
# vps_check.sh ÔÇö Revision desatendida de salud del VPS (cron).
# Detecta carga alta, procesos tipo minero (exe desde /tmp borrado / memfd,
# o binarios sospechosos con CPU alta) y servicios criticos caidos.
# Registra en /root/vps_health.log. Si el proceso es claramente minero
# (CPU>150 y exe en /tmp o memfd/(deleted)) y AUTO_KILL=1, lo mata.
LOG=/root/vps_health.log
AUTO_KILL=1
MAX_LOAD=8.0
MAX_CPU_MINERO=150.0
NOW=$(date '+%Y-%m-%d %H:%M:%S')
{
echo "=== $NOW ==="
echo "-- carga --"
uptime
echo "-- memoria --"
free -h | head -2
echo "-- disco / --"
df -h / | tail -1
echo "-- top procesos por CPU --"
ps -eo pid,user,pcpu,pmem,etime,args --sort=-pcpu | head -8
echo "-- deteccion de mineros --"
ALGO=0
while read -r pid pcpu args; do
exe=$(readlink "/proc/$pid/exe" 2>/dev/null)
case "$exe" in
'') continue ;;
/usr/*|/bin/*|/sbin/*|/lib*|/opt/*|/etc/*) continue ;;
esac
caso=0
case "$exe" in
*memfd*|*deleted*|/tmp/*|/var/tmp/*) caso=1 ;;
esac
[ "$caso" = 1 ] || continue
ok=$(awk -v p="$pcpu" -v m="$MAX_CPU_MINERO" 'BEGIN{print (p+0>m+0)?1:0}')
if [ "$ok" = "1" ]; then
ALGO=1
echo "ALERTA_MINERO pid=$pid cpu=${pcpu}% exe=$exe cmd=${args:0:120}"
if [ "$AUTO_KILL" = "1" ]; then
kill -9 "$pid" 2>/dev/null && echo " -> matado pid $pid"
fi
fi
done < <(ps -eo pid=,pcpu=,args= | sort -k2 -nr | head -15)
[ "$ALGO" = "0" ] && echo "sin procesos mineros detectados"
echo "-- servicios --"
for s in opencode-serve opencode-tg; do
echo "$s: $(systemctl is-active "$s" 2>/dev/null)"
done
for c in gitea engram-cloud engram-cloud-postgres; do
echo "docker $c: $(docker inspect -f '{{.State.Status}}' "$c" 2>/dev/null || echo no-existe)"
done
LOAD=$(awk '{print $1}' /proc/loadavg)
if awk -v l="$LOAD" -v m="$MAX_LOAD" 'BEGIN{exit !(l+0>m+0)}'; then
echo "AVISO_LOAD load1=$LOAD > $MAX_LOAD"
fi
} >> "$LOG" 2>&1
tail -n 2000 "$LOG" > "$LOG.tmp" && mv "$LOG.tmp" "$LOG"
exit 0