Verificar un estado, no reconstruirlo
El endurecimiento inicial de un VPS se hace una vez, en la entrega: claves SSH, cortafuegos, fail2ban, actualizaciones automáticas. Nuestra checklist de endurecimiento ya lo detalla. Aquí damos por hecho que todo eso existe y nos preguntamos si sigue en pie. Un paquete que quedó pendiente, una cuenta creada para un proveedor y nunca eliminada, un puerto abierto para una prueba, un certificado cuya renovación falla en silencio: nada de eso se ve mientras no se mira. La auditoría mensual es por tanto una rutina de control, no de configuración. Cada control produce una salida que se archiva y un estado verde, naranja o rojo en el informe del cliente. Una desviación se anota, nunca se corrige sin acuerdo.
Fijar el perímetro antes de la primera auditoría
Antes del primer comando, deje por escrito quién es responsable de qué. ¿El VPS pertenece al cliente o a la agencia? ¿Quién guarda la cuenta root, quién recibe las alertas, quién decide un reinicio? Sin respuestas, la primera desviación se convierte en una disputa: ¿podía la agencia corregirla, estaba el cliente avisado? Incluya cinco puntos en su contrato o pedido: los VPS cubiertos, la frecuencia de la auditoría, los accesos concedidos de solo lectura, el plazo de respuesta ante una desviación roja y la lista de acciones que la agencia puede hacer sola, como aplicar una actualización de seguridad, frente a las que exigen validación del cliente, como un reinicio o la eliminación de una cuenta.
Para preparar una sola vez, antes de auditar
- Una cuenta de auditoría dedicada — un usuario nominal con
sudolimitado a leer registros e inspeccionar la red, en lugar de un root compartido. - Una lista esperada por VPS — puertos que deben escuchar, cuentas autorizadas, dominios servidos, herramienta de copia y repositorio. Sin referencia, una desviación no se distingue del funcionamiento normal.
- Un script de recogida de solo lectura — encadena los comandos de la checklist y escribe todo en un archivo fechado, para teclear cada comando una sola vez.
- Una carpeta de archivo por cliente — una subcarpeta por mes, conservada fuera del VPS auditado, para poder comparar los meses.
- Una plantilla de informe — el mismo formato para todos los clientes, rellenado a partir de las salidas recogidas.
- Un calendario — un día fijo del mes por cliente, anotado en la agenda del equipo; si no, la auditoría se salta en el primer mes cargado.
Los siete controles, con su presupuesto de tiempo
Actualizaciones pendientes (6 min)
sudo apt updateapt list --upgradable 2>/dev/nullapt list --upgradable 2>/dev/null | grep -i security
Aísle los paquetes cuyo origen termina en-security: salen primero. Los demás pasan por validación humana, porque un salto de versión mayor puede romper una aplicación. En AlmaLinux o RHEL,sudo dnf check-update --securitycumple el mismo papel. Aun con las actualizaciones automáticas activas, este control muestra lo que sigue bloqueado.Kernel y reinicio pendiente (4 min)
uname -rls /boot/vmlinuz-*ls /var/run/reboot-requiredsudo needrestart -b -r l
Si el kernel instalado más reciente difiere deuname -r, o si existe/var/run/reboot-required, hay un reinicio pendiente. En la salida de needrestart, la líneaNEEDRESTART-KSTAindica si el kernel cargado está al día, y la lista muestra los servicios que aún usan bibliotecas antiguas. El reinicio nunca se hace en solitario: se planifica con el cliente.Cuentas y claves SSH (8 min)
awk -F: '$3>=1000' /etc/passwdgetent group sudosudo ssh-keygen -lf /home/<cuenta>/.ssh/authorized_keyslastlog | grep -v 'Never logged in'last -n 20
Cada cuenta humana debe corresponder a una persona conocida del cliente o de la agencia. Cada huella de clave debe pertenecer a alguien que sigue trabajando en el proyecto. Una cuenta sin conexión desde hace meses, o una clave desconocida, pasa a naranja y va al cliente para su validación.Puertos abiertos (5 min)
sudo ss -tlnpsudo ss -ulnpsudo ufw status verbose
Compare el resultado con la lista esperada para este VPS. Una base de datos que escucha en todas las interfaces en lugar del bucle local, un puerto de prueba olvidado, un servicio desconocido: cada desviación se anota con el proceso que la abre, sin cerrarla de inmediato, porque un servicio puede depender de ese puerto.Certificados (4 min)
openssl s_client -connect su-dominio.com:443 -servername su-dominio.com </dev/null 2>/dev/null | openssl x509 -noout -enddate
Lea la fecha de caducidad en el servicio realmente expuesto, no solo la presencia de un temporizador de renovación: un temporizador activo puede fallar cada noche. Si el dominio pasa por una CDN, este comando lee el certificado de la CDN. Para el origen, sustituya el host de-connectpor la dirección IP del VPS y conserve-servername.Copias restauradas (10 min)
restic snapshotsrestic restore latest --target /tmp/prueba-restauracion --include /etc/nginx
Anote la fecha del último punto de restauración, luego restaure de verdad un archivo o una base de datos en un directorio temporal y ábralo. Una copia nunca restaurada no es una prueba, es una hipótesis. Elimine después el directorio temporal. Si el cliente usa otra herramienta, la lógica es la misma: lista de puntos, restauración parcial, comprobación del contenido.Registros de autenticación (8 min)
sudo journalctl -u ssh --since '30 days ago' --no-pager | grep -c 'Failed password'sudo journalctl -u ssh --since '30 days ago' --no-pager | grep 'Accepted'sudo journalctl _COMM=sudo --since '30 days ago' --no-pager
Cuente los fallos, liste las conexiones correctas y busque las que vienen de una dirección desconocida. Revise los usos desudo. En RHEL y derivadas, la unidad se llamasshd, nossh.
El presupuesto de 45 minutos por VPS
Desplace la tabla
| Control | Comando clave | Tiempo |
|---|---|---|
| Actualizaciones pendientes | `apt list --upgradable` | 6 min |
| Kernel y reinicio | `needrestart -b -r l` | 4 min |
| Cuentas y claves SSH | `ssh-keygen -lf authorized_keys` | 8 min |
| Puertos abiertos | `ss -tlnp` | 5 min |
| Certificados | `openssl s_client` | 4 min |
| Copias restauradas | `restic restore` | 10 min |
| Registros de autenticación | `journalctl -u ssh` | 8 min |
Un script de recogida en lugar de siete sesiones a mano
La mayor parte de los 45 minutos es lectura, no tecleo, siempre que no se vuelvan a escribir los comandos. Escriba un script audit-vps que ejecute los comandos de los controles uno a siete y redirija cada salida a un archivo con el nombre del cliente y la fecha, por ejemplo ~/audits/client-a/AAAA-MM/salida-bruta.txt. Solo contiene comandos de lectura: ningún apt upgrade, ningún systemctl restart, ningún rm. Láncelo por SSH desde su equipo, recupere el archivo y léalo con calma. La restauración de la copia sigue siendo el único paso manual, porque exige juzgar si el contenido restaurado es coherente.
Archivar y comparar: ahí se ven las derivas
Una auditoría aislada da una foto; dos auditorías consecutivas dan una tendencia. Conserve la salida bruta de cada mes y compárela con la anterior mediante diff -u auditoria-anterior.txt auditoria-actual.txt. Un puerto que aparece, una cuenta de más, un número de fallos de conexión multiplicado por diez, un punto de restauración que ya no avanza: todas estas señales destacan en unas pocas líneas de diferencia, mientras que son invisibles en una salida leída sola. Archive también el informe entregado al cliente. El día en que este pregunte desde cuándo existía una cuenta o cuándo se aplicó una corrección, la respuesta es un archivo fechado, no un recuerdo.
El informe de una página entregado al cliente
La cabecera
Nombre del cliente, identificador del VPS, dirección IP, fecha de la auditoría, nombre de la persona que la realizó.
La tabla de los siete controles
Una línea por control con un estado: verde si no hay nada que señalar, naranja si una desviación requiere una decisión del cliente, rojo si se necesita una acción urgente.
Las desviaciones constatadas
Cada desviación en una frase factual, con la prueba: la línea de salida, el puerto, la cuenta afectada.
Las acciones realizadas
Lo que la agencia aplicó sola, dentro del perímetro acordado, por ejemplo una actualización de seguridad.
Las acciones que el cliente debe validar
Reinicio, eliminación de una cuenta, cierre de un puerto, con el riesgo de no hacer nada.
La próxima fecha
La fecha de la próxima auditoría y, para cada desviación naranja o roja, un plazo límite de tratamiento.
Anote la desviación, no la corrija sobre la marcha
El reflejo de cerrar el puerto o eliminar la cuenta sospechosa durante la auditoría es el más caro: cae un servicio del cliente y la agencia lo decidió sola. El papel de la auditoría es hacer visible y fechada la desviación. La corrección sigue el circuito de validación acordado al inicio, incluso para lo que parece evidente.
Cuando una salida no dice lo que parece decir
needrestartno encontrado — el paquete no está instalado por defecto en todas partes. Instálelo una vez con el acuerdo del cliente, o compare a manouname -ry los kernels presentes en/boot.- Ningún fallo SSH en los registros — compruebe el nombre de la unidad antes de concluir. Según la distribución, la autenticación se registra bajo
ssh,sshdo, en las versiones recientes de OpenSSH,sshd-session. Pruebesudo journalctl _COMM=sshd-session --since '30 days ago'. ss -tlnpno muestra los procesos — sinsudo, la columna de procesos queda vacía para los servicios de otros usuarios.- Un certificado válido mientras el sitio muestra un error — ha leído el de una CDN o de otro vhost. Apunte a la dirección del VPS y pase el
-servernamecorrecto. resticpide una contraseña — el repositorio está cifrado. Obtenga el secreto del cliente antes de la auditoría, no durante ella; de lo contrario el control se salta.
La objeción del tiempo: 45 minutos por cliente, cada mes
Veinte clientes suman quince horas al mes, y la objeción es legítima. Tres palancas la reducen. Primero, el tiempo se mide por VPS, no por cliente: un cliente con un solo servidor cuesta 45 minutos, y menos desde el segundo mes, porque las referencias esperadas ya están fijadas. Segundo, el script lo recoge todo, usted solo lee, y el informe se rellena desde una plantilla. Por último, compare con el coste de un incidente no detectado: un acceso olvidado o una copia inutilizable se descubren el día de la caída, con un cliente molesto y una factura de recuperación. La rutina cuesta menos que un solo incidente evitable.
Cuando la cartera crece
Con diez VPS, la checklist cabe en una jornada. Con cincuenta, la dificultad pasa a ser de organización: saber qué cliente tiene qué, qué vencimientos caen este mes, quién ha sido auditado. El espacio de agencia de ServOrbit.com reúne los servicios y vencimientos de cada cliente en una sola interfaz, lo que evita mantener una hoja de cálculo paralela. Si la agencia prefiere no asumir ella misma la base del sistema, existe la opción de administración de VPS, que se estudia aparte. Esta guía se facilita tal cual, sin soporte: la ejecución de la auditoría y la responsabilidad frente al cliente siguen siendo suyas.
Para ir más lejos
- Montar la base — /blog/linux-hardening-vps-checklist describe el endurecimiento inicial que esta auditoría verifica.
- Automatizar las correcciones — /blog/securite-vps-mises-a-jour-automatiques-debian-ubuntu explica unattended-upgrades, cuyos restos mide el primer control.
- Respaldar bien — /blog/backup-vps-restic-s3-3-2-1 cubre la puesta en marcha de Restic, cuya restauración verifica el sexto control.
- Vigilar de forma continua — /blog/alertes-disque-ram-vps-monitoring-proactif completa la auditoría mensual con alertas entre dos pasadas.
- Inventariar las versiones de PHP — /blog/inventaire-versions-php-parc-sites-clients-agence aplica la misma disciplina al parque de sitios.
- Reaccionar ante una vulnerabilidad — las guías de corrección de la categoría Seguridad y monitorización del blog muestran lo que permite un inventario al día el primer día.
La documentación oficial
Opciones de apt: https://manpages.debian.org/stable/apt/apt.8.en.html
Proyecto needrestart: https://github.com/liske/needrestart
Actualizaciones automáticas en Debian: https://wiki.debian.org/UnattendedUpgrades
Comando ss: https://man7.org/linux/man-pages/man8/ss.8.html
Comando openssl s_client: https://docs.openssl.org/master/man1/openssl-s_client/
Comando journalctl: https://www.freedesktop.org/software/systemd/man/latest/journalctl.html
Demonio sshd: https://man.openbsd.org/sshd.8
Comando last: https://man7.org/linux/man-pages/man1/last.1.html