Cuando un servidor deja de responder, lo más difícil es saber por dónde empezar: puede ser la red, un proceso que se ha comido la memoria, un disco lleno o un servicio caído. En esta guía seguirás un orden de diagnóstico que va de fuera hacia dentro: primero compruebas desde tu equipo qué es lo que falla, luego entras en el servidor y revisas CPU, memoria, disco, servicios y logs. Los comandos están pensados para Ubuntu 24.04 y funcionan igual en Debian 12; las diferencias con Rocky Linux 9 se indican donde importan.

Requisitos previos

Para seguir esta guía necesitas:

  • Un servidor Linux con Ubuntu 24.04 LTS (o Debian 12 / Rocky Linux 9), por ejemplo un VPS de CubePath.
  • Un usuario con privilegios sudo en el servidor.
  • Un equipo local con ping, mtr, nc y curl. En Ubuntu se instalan con sudo apt install mtr-tiny netcat-openbsd curl.
  • Acceso a la consola del servidor desde el panel de CubePath, para cuando SSH no funciona.

A lo largo de la guía, sustituye your_server_ip por la IP pública del servidor y your_domain por su dominio.

Paso 1: Acotar el problema desde fuera

Antes de entrar en el servidor, averigua qué capa falla. Estas tres pruebas separan un problema de red de uno del propio sistema o de un servicio concreto.

Comprueba si el servidor responde a nivel de red:

ping -c 4 your_server_ip
4 packets transmitted, 4 received, 0% packet loss, time 3004ms
rtt min/avg/max/mdev = 18.211/18.498/18.902/0.254 ms

Comprueba los puertos de los servicios que deberían responder. nc -vz intenta abrir la conexión TCP y dice si lo consigue:

nc -vz -w 5 your_server_ip 22
nc -vz -w 5 your_server_ip 443
Connection to your_server_ip 22 port [tcp/ssh] succeeded!
nc: connect to your_server_ip port 443 (tcp) failed: Connection refused

Si hay un servicio web, pide solo las cabeceras y mide cuánto tarda:

curl -sS -o /dev/null -w "%{http_code} %{time_total}s\n" https://your_domain/
502 0.184s

Cómo interpretar los resultados:

PingPuerto 22ServicioLo más probable
FallaFallaFallaServidor apagado, colgado o problema de red. Ve a la consola (paso 2).
OKOKFalla o lentoEl sistema vive, falla un servicio o faltan recursos. Entra por SSH (pasos 3 a 6).
OKTimeoutTimeoutSistema sin recursos (memoria o CPU) o firewall bloqueando.
FallaOKOKICMP filtrado por el firewall. No es un problema.

Connection refused significa que el servidor responde pero nada escucha en ese puerto (servicio caído). Un timeout suele indicar un firewall que descarta paquetes o un sistema tan saturado que no llega a contestar.

Si el ping pierde paquetes o la latencia es anormal, mtr muestra en qué salto de la ruta empieza el problema:

mtr -rwc 50 your_server_ip

Si la pérdida empieza en un salto intermedio y continúa hasta el destino, el problema está en la ruta, no en tu servidor. Si solo aparece en saltos intermedios pero no en el último, es simplemente un router que limita las respuestas ICMP.

Paso 2: Entrar en el servidor

Intenta SSH en modo detallado, que muestra en qué fase se queda la conexión:

ssh -v your_user@your_server_ip

Si se detiene después de Connecting to your_server_ip port 22 sin avanzar, el sistema no está aceptando conexiones. Si llega a Authenticated pero la shell tarda minutos en aparecer, el servidor está saturado: sigue esperando, porque una vez dentro podrás diagnosticar.

Si SSH no funciona, abre la consola del servidor desde el panel de CubePath. La consola equivale a tener un monitor y teclado conectados: no depende de la red ni de SSH. Si en la pantalla ves mensajes del kernel como Out of memory: Killed process o blocked for more than 120 seconds, anótalos, porque indican la causa. Si el servidor no responde ni por consola, reinícialo desde el panel y continúa el diagnóstico con los logs del arranque anterior (paso 6).

Paso 3: Revisar la carga y la CPU

Empieza por una visión general con uptime:

uptime
 10:41:07 up 12 days,  3:18,  1 user,  load average: 14.52, 11.08, 6.33

Los tres números son la carga media del último minuto, 5 minutos y 15 minutos. Compáralos con el número de núcleos:

nproc
4

Una carga de 14 con 4 núcleos significa que hay muchos más procesos esperando de los que el sistema puede atender. Que el primer número sea mayor que el tercero indica que el problema está empeorando.

La carga alta no siempre es CPU: también cuenta procesos bloqueados esperando al disco. vmstat lo distingue:

vmstat 1 5
procs -----------memory---------- ---swap-- -----io---- -system-- -------cpu-------
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st gu
 9  0      0 182340  40212 912340    0    0     2    15  812 1403 94  5  1  0  0  0
11  0      0 181920  40212 912356    0    0     0     8  790 1350 96  4  0  0  0  0

Fíjate en estas columnas:

  • r alto y us + sy cerca de 100: la CPU está saturada.
  • b alto y wa alto: los procesos esperan al disco (ve al paso 5).
  • si y so distintos de cero de forma continua: el sistema está usando swap intensivamente (ve al paso 4).
  • st alto: la máquina virtual espera CPU del hipervisor.

Para ver qué procesos consumen la CPU, ordénalos:

ps -eo pid,user,%cpu,%mem,etime,cmd --sort=-%cpu | head -n 10
    PID USER     %CPU %MEM     ELAPSED CMD
  18234 www-data 98.7  2.1       41:12 php-fpm: pool www
  18240 www-data 97.9  2.0       40:58 php-fpm: pool www
    912 mysql    45.3 18.4 12-03:17:02 /usr/sbin/mysqld

Para seguirlo en tiempo real, usa top (pulsa P para ordenar por CPU, M por memoria y q para salir).

Paso 4: Revisar la memoria y el OOM killer

Consulta el uso de memoria:

free -h
               total        used        free      shared  buff/cache   available
Mem:           3.8Gi       3.6Gi       102Mi        12Mi       214Mi       98Mi
Swap:             0B          0B          0B

La columna importante es available, no free: Linux usa la memoria libre como caché de disco y la libera cuando hace falta. Si available está cerca de cero y no hay swap, el sistema está a punto de quedarse sin memoria.

Cuando la memoria se agota, el kernel mata procesos con el OOM killer. Busca si ha ocurrido en este arranque:

sudo journalctl -k -b | grep -iE "out of memory|oom-kill"
Sep 25 10:32:18 web01 kernel: Out of memory: Killed process 912 (mysqld) total-vm:2841236kB, anon-rss:1402340kB, file-rss:0kB, shmem-rss:0kB, UID:112 pgtables:3104kB oom_score_adj:0

La línea indica qué proceso murió y cuánta memoria usaba. Que muera la base de datos no significa que sea la culpable: el OOM killer elige al proceso que más memoria ocupa, no al que la está haciendo crecer. Ordena los procesos por memoria para ver quién consume:

ps -eo pid,user,rss,%mem,cmd --sort=-rss | head -n 10

La columna RSS está en KB. Muchos procesos iguales (por ejemplo, decenas de php-fpm o apache2) suelen indicar que el número máximo de workers está configurado por encima de lo que cabe en la RAM.

Paso 5: Revisar el disco

Un disco lleno impide escribir logs, sesiones o datos de la base de datos, y muchos servicios fallan de formas poco obvias. Comprueba el espacio:

df -h -x tmpfs -x devtmpfs
Filesystem      Size  Used Avail Use% Mounted on
/dev/vda1        38G   38G     0 100% /
/dev/vda15      105M  6.1M   99M   6% /boot/efi

Comprueba también los inodos. Un disco puede tener espacio libre y aun así no admitir archivos nuevos si se han agotado los inodos (típico con millones de archivos de sesión o caché):

df -i -x tmpfs -x devtmpfs

Si el disco está lleno, localiza qué directorio ocupa más espacio. La opción -x evita salir del sistema de archivos raíz:

sudo du -xh --max-depth=1 / 2>/dev/null | sort -h | tail -n 8
1.2G    /usr
2.1G    /home
31G     /var
38G     /

Repite el comando sobre el directorio más grande (/var, luego /var/log, etc.) hasta encontrar el culpable. Los sospechosos habituales son /var/log, el journal de systemd, /var/lib/docker y copias de seguridad olvidadas.

Si el problema no es espacio sino lentitud, mide la actividad del disco. Instala sysstat, que incluye iostat:

sudo apt install sysstat
iostat -xz 1 3

En la salida, un %util cercano a 100 y valores altos de r_await o w_await (milisegundos por operación) indican que el disco está saturado. Para ver qué proceso escribe o lee, sudo apt install iotop y ejecuta sudo iotop -o.

Paso 6: Revisar servicios y logs

Lista los servicios que systemd ha marcado como fallidos:

systemctl --failed
  UNIT          LOAD   ACTIVE SUB    DESCRIPTION
● nginx.service loaded failed failed A high performance web server and a reverse proxy server

Consulta el estado y las últimas líneas del log del servicio afectado:

sudo systemctl status nginx
sudo journalctl -u nginx -n 50 --no-pager

Revisa también los errores de todo el sistema en este arranque, que suelen apuntar directamente a la causa:

sudo journalctl -p err -b --no-pager | tail -n 40

Si reiniciaste el servidor desde el panel porque no respondía, la información útil está en el arranque anterior. Ubuntu guarda el journal en disco de forma persistente, así que puedes consultarlo:

sudo journalctl --list-boots | tail -n 3
sudo journalctl -b -1 -p warning -n 60 --no-pager

Las últimas líneas del arranque anterior muestran lo que ocurría justo antes del bloqueo: mensajes del OOM killer, errores de disco (I/O error, EXT4-fs error) o tareas bloqueadas (task ... blocked for more than 120 seconds).

Para comprobar qué servicios escuchan en qué puertos, y confirmar que el servicio caído del paso 1 realmente no está escuchando:

sudo ss -tlnp

Si el servidor responde pero está lento en red, cuenta las conexiones por estado. Miles de conexiones en SYN-RECV o desde una misma IP apuntan a un ataque o a un cliente descontrolado:

ss -s
ss -Htn state established '( sport = :443 )' | awk '{print $4}' | cut -d: -f1 | sort | uniq -c | sort -rn | head

Paso 7: Aplicar la solución

La solución depende de la causa que hayas encontrado. Estas son las acciones más comunes.

Un proceso consume toda la CPU o la memoria. Si pertenece a un servicio, reinícialo en lugar de matar el proceso a mano, para que systemd mantenga el estado coherente:

sudo systemctl restart php8.3-fpm

Si es un proceso suelto, termínalo con SIGTERM y, solo si no responde en unos segundos, con SIGKILL:

sudo kill 18234
sudo kill -9 18234

Después ajusta la causa: el número de workers de PHP-FPM o Apache, la memoria de la base de datos o el límite de memoria de la aplicación.

El disco está lleno. Reduce el journal de systemd a un tamaño fijo y limpia la caché de paquetes:

sudo journalctl --vacuum-size=200M
sudo apt clean

Si el espacio lo ocupa un log que sigue abierto por un proceso, vacíalo en lugar de borrarlo (un archivo borrado pero abierto sigue ocupando espacio hasta que el proceso lo cierra):

sudo truncate -s 0 /var/log/app/huge.log

Comprueba con df -h que el espacio se ha liberado.

El servidor no tiene swap y se queda sin memoria. Un archivo de swap de 2 GB evita que un pico puntual active el OOM killer mientras corriges el consumo real:

sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Verifica que está activo con swapon --show.

Un servicio se cae y no vuelve. Haz que systemd lo reinicie automáticamente con un override, que sobrevive a las actualizaciones del paquete:

sudo systemctl edit nginx

En el editor, añade estas líneas en la zona indicada:

[Service]
Restart=on-failure
RestartSec=5s

Guarda y comprueba que el cambio se ha aplicado:

systemctl show nginx -p Restart
Restart=on-failure

Solución de problemas

journalctl -b -1 dice Specified boot ID not found o no hay arranques anteriores: el journal no es persistente en ese sistema. En Rocky Linux 9 y algunas imágenes mínimas, créalo con sudo mkdir -p /var/log/journal y sudo systemctl restart systemd-journald; a partir de ese momento se conservarán los logs entre reinicios.

df muestra el disco lleno pero du no encuentra los archivos: hay archivos borrados que un proceso mantiene abiertos. Localízalos con sudo lsof +L1 y reinicia el servicio que los tiene abiertos.

La consola muestra el prompt de login pero no acepta tu contraseña: si tu usuario solo tiene clave SSH y no contraseña, no podrás entrar por consola. Configura una contraseña con sudo passwd your_user mientras tengas acceso, para disponer de una vía de emergencia.

Conclusión

Has seguido un orden de diagnóstico que va de fuera hacia dentro: red y puertos desde tu equipo, acceso por SSH o consola, y después CPU, memoria, disco, servicios y logs, incluido el arranque anterior a un reinicio. Con esa información puedes aplicar la solución adecuada en lugar de reiniciar a ciegas.

Como siguientes pasos, puedes:

  • Instalar una monitorización con alertas de CPU, memoria y disco para enterarte antes de que el servidor deje de responder.
  • Revisar la configuración de workers de tus servicios web y bases de datos para que quepan en la RAM disponible.
  • Documentar cada incidente con la causa y la solución, para resolver el siguiente más rápido.