#!/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