ES | EN

De un VPS Vulnerable a una Fortaleza Automatizada - Parte II

SYSADMIN / HARDENING / CLOUD_SECURITY Lectura Técnica: 18 min
De un VPS Vulnerable a una Fortaleza Automatizada - Parte II

En la Parte I vimos el diagnóstico: qué tiene un VPS típico, por qué es un problema, y cuáles son los principios que guían el hardening. Ahora viene lo concreto. Esta parte es el plan de ejecución real: los comandos en orden, con contexto, explicados para que entiendas qué hace cada uno y por qué va en ese lugar. No es una receta de copiar y pegar. Es un plan maestro que puedes adaptar a cualquier servidor desde el día cero.

ESTADO DEL SISTEMA: EN EJECUCIÓN / CLASIFICADO

Arquitecto: 0n3Z3r0 | Roles: SysAdmin Senior & Ethical Hacker.
Objetivo: Implementación completa del hardening en 5 fases secuenciales.
Serie: Parte II de III — El Script Maestro y Glosario Técnico.

El Script Maestro: De Cero a Fortaleza en 5 Fases

El orden importa. No puedes configurar el firewall antes de crear los usuarios. No puedes automatizar reportes antes de tener la estructura de carpetas. Cada fase prepara el terreno para la siguiente. Sigue el orden y el resultado es predecible. Sáltate pasos y tendrás un servidor a medias protegido, que es casi peor que uno sin proteger, porque te da falsa confianza.

Fase 1: Preparación y Limpieza — Adiós al Bloatware

Antes de construir cualquier cosa, hay que limpiar. Un servidor recién aprovisionado trae consigo servicios que no pediste y que no necesitas. Servicios de impresión, descubrimiento de red local, gestión de módems. En un entorno cloud no sirven para nada, pero sí añaden superficie de ataque. Lo primero es actualizar el sistema a su estado más reciente y luego quitarle todo lo que sobra.

# 1. Actualizar el sistema al máximo
sudo apt update && sudo apt upgrade -y

# 2. Eliminar servicios innecesarios detectados en el diagnóstico
sudo apt purge cups avahi-daemon modemmanager -y
sudo apt autoremove -y

# 3. Cambiar el target por defecto: sin GUI, solo terminal
sudo systemctl set-default multi-user.target

Ese tercer comando es más importante de lo que parece. Si el servidor tenía una interfaz gráfica instalada (cosa común en VPS que empezaron como laboratorio), este comando le dice a systemd que no la levante en el próximo arranque. El servidor sigue funcionando exactamente igual para todo lo demás, pero sin cargar X11, el display manager ni ninguna de sus dependencias. Menos RAM consumida, menos superficie de ataque, más foco.

Comando Qué hace exactamente
apt update && apt upgrade -y Sincroniza los repositorios y aplica todos los parches disponibles. Cierra vulnerabilidades conocidas antes de configurar nada más.
apt purge cups avahi-daemon modemmanager Elimina completamente (configuración incluida) tres servicios sin función en un servidor cloud: gestión de impresoras, descubrimiento mDNS y gestión de módems.
apt autoremove -y Borra las dependencias huérfanas que quedaron instaladas por los paquetes que acabas de eliminar. Limpieza completa.
systemctl set-default multi-user.target Establece el modo de arranque en consola pura. Elimina la carga del entorno gráfico en cada reinicio del servidor.

Explicación no técnica

Imagina que te mudas a una oficina nueva y el anterior inquilino dejó cosas: una impresora que no usas, un router viejo enchufado, papeles por todos lados. Antes de poner tu equipo, limpias. Eso es esta fase: dejar el servidor en blanco limpio, sin cachivaches del inquilino anterior, antes de construir tu propia infraestructura encima.

Fase 2: Creación de la Jerarquía de Usuarios

Aquí empieza la arquitectura de seguridad real. La premisa es simple: ninguna tarea debe tener más permisos de los estrictamente necesarios para realizarla. Creamos tres usuarios con funciones muy concretas, y solo uno de ellos tendrá acceso a sudo.

# Crear usuarios específicos para cada función
sudo adduser labadmin # Administración diaria del servidor
sudo adduser services # Ejecución de procesos y contenedores
sudo adduser pentest # Herramientas de auditoría y hacking ético

# Solo labadmin recibe privilegios de administración
sudo usermod -aG sudo labadmin

El usuario services y el usuario pentest no tienen acceso a sudo. Eso es deliberado. Si un contenedor Docker es comprometido y el atacante consigue acceso al usuario services, está en un callejón sin salida: no puede instalar software, no puede modificar configuraciones del sistema, no puede escalar privilegios. La jaula funciona.

Usuario Función ¿Tiene sudo?
root Mantenimiento de kernel y emergencias críticas. SSH deshabilitado. Es root — acceso total por diseño, pero bloqueado en SSH
labadmin Administración diaria, despliegues, gestión general del servidor. Sí — único usuario con privilegios de administración
services Corre procesos y contenedores Docker. Sin shell interactiva. No — jaula de procesos sin privilegios
pentest Herramientas ofensivas y de auditoría. Entorno aislado. No — aislado del resto del sistema por diseño

Explicación no técnica

En una empresa, el becario puede usar el ordenador de la oficina pero no puede entrar al servidor de contabilidad. El técnico de IT puede acceder a los servidores pero no puede mover dinero. El director financiero puede mover dinero pero no toca los servidores. Nadie tiene acceso a todo. Si alguien comete un error o es engañado, el daño está contenido en su área. Eso es exactamente lo que hacemos aquí con los usuarios del sistema.

Fase 3: Arquitectura de Carpetas en /opt

Un servidor sin estructura es un servidor que no puedes defender ni auditar. Si mañana necesitas saber qué hay en producción, qué está en pruebas y dónde están los logs, la respuesta tiene que ser inmediata. La estructura de /opt es esa respuesta.

# Crear la estructura de directorios completa
sudo mkdir -p /opt/{services,lab,tools,data}
sudo mkdir -p /opt/lab/{redteam,blueteam,malware,poc}
sudo mkdir -p /opt/services/{web,api,proxy}
sudo mkdir -p /opt/data/{logs,captures,dumps}

# labadmin gestiona todo en /opt
sudo chown -R labadmin:labadmin /opt/

El flag -p en mkdir crea toda la jerarquía de una vez, incluidos los directorios intermedios que no existan todavía. El chown -R aplica el cambio de propietario de forma recursiva a todo el árbol de /opt. A partir de ahora, labadmin puede trabajar libremente en esa estructura sin necesitar sudo para cada operación.

/opt/
 ├── services/          # Aplicaciones en producción
 │   ├── web/           # Servicios web y frontends
 │   ├── api/           # Backends y APIs
 │   └── proxy/         # Configuraciones de Nginx
 ├── lab/               # Entornos de laboratorio
 │   ├── redteam/       # Herramientas ofensivas
 │   ├── blueteam/      # Herramientas defensivas
 │   ├── malware/       # Muestras para análisis (aisladas)
 │   └── poc/           # Pruebas de concepto
 ├── tools/             # Scripts y binarios de mantenimiento
 └── data/              # Datos persistentes
     ├── logs/          # Logs centralizados
     ├── captures/      # Capturas de tráfico
     └── dumps/         # Volcados de memoria o DB
Directorio Para qué sirve
/opt/services/ Todo lo que está en producción: Docker Compose files, configuraciones de servicios activos. Lo que no debe romperse.
/opt/lab/ Entornos de prueba y herramientas de hacking ético. Separado de producción para que un experimento no tumbe un servicio.
/opt/tools/ Scripts de mantenimiento, binarios personalizados, utilidades del sysadmin. Todo fuera del PATH estándar del sistema.
/opt/data/ Datos que deben sobrevivir aunque reinstales el servidor: logs históricos, capturas de tráfico, backups de bases de datos.

Explicación no técnica

Piensa en un taller mecánico bien organizado. Las herramientas de precisión están en un cajón. Los repuestos en otro. Los aceites en la estantería de la derecha. Si algo falla a las 2am, sabes exactamente dónde buscar sin encender la luz. Eso es /opt: no es perfeccionismo, es que cuando las cosas van mal necesitas encontrar lo que buscas en segundos, no en minutos.

Fase 4: Blindaje de Red — Firewall y VPN

Esta es la fase que más impacto visible tiene. Antes de ejecutar estos comandos, el servidor es accesible desde cualquier punto de internet en múltiples puertos. Después, solo existen tres puertas públicas. Todo lo demás desaparece del mapa.

# 1. Política base: denegar todo el tráfico entrante por defecto
sudo ufw default deny incoming
sudo ufw default allow outgoing

# 2. Abrir solo lo que se puede justificar
sudo ufw allow 22/tcp # SSH — acceso remoto al servidor
sudo ufw allow 80/tcp # HTTP — solo para redirigir a HTTPS
sudo ufw allow 443/tcp # HTTPS — tráfico web cifrado

# 3. Instalar Tailscale (la capa de invisibilidad para servicios internos)
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up

# 4. Activar el firewall — a partir de aquí, el kill switch está ON
sudo ufw enable

El orden aquí es crítico: primero defines las reglas, después activas el firewall. Si lo haces al revés y olvidas abrir el puerto 22 antes de hacer ufw enable, te quedas sin acceso SSH a tu propio servidor. Tailscale se instala antes de activar UFW porque su script de instalación necesita acceso a internet para descargar los binarios.

Una vez activo, Portainer, las bases de datos y cualquier panel de administración dejan de necesitar un puerto público. Solo son accesibles por la IP de la red Tailscale. Para Shodan, para Nmap, para cualquier escáner externo, esos servicios no existen.

Comando Qué hace y por qué va en este orden
ufw default deny incoming Establece la política base. Todo lo que llegue desde internet y no tenga una regla explícita de permiso: bloqueado.
ufw allow 22/tcp Debe ir antes de ufw enable. Si no, pierdes el acceso SSH al activar el firewall.
tailscale up Conecta el servidor a tu red mesh privada. A partir de aquí, los servicios internos tienen una IP privada exclusiva para tus dispositivos.
ufw enable Activa el firewall con todas las reglas ya definidas. Este es el momento en que el kill switch se pone en ON.

Explicación no técnica

Es como construir la valla de seguridad de una finca. Primero decides cuántas puertas quieres (tres: SSH, HTTP, HTTPS). Después instalas la valla. Si instalas la valla antes de dejar abierta la puerta principal, quedas encerrado fuera. El orden de los comandos existe por eso: primero las reglas, luego el candado. Y Tailscale es el pasadizo privado que conecta tu casa con la finca sin que nadie del exterior sepa que existe.

Fase 5: Automatización de Informes con Cron

El último pilar es la observabilidad. Un servidor que no te informa de lo que pasa es un servidor que administras a ciegas. El script ssh-summary.sh es la solución mínima viable: un resumen diario automático que llega a tu log sin que tengas que hacer nada.

# 1. Crear el script de auditoría SSH
sudo nano /usr/local/bin/ssh-summary.sh
# [Aquí va la lógica de análisis de logs — ver Parte III]

# 2. Darle permisos de ejecución
sudo chmod +x /usr/local/bin/ssh-summary.sh

# 3. Programarlo en crontab para que corra cada noche a las 23:00
(crontab -l 2>/dev/null; echo "0 23 * * * /usr/local/bin/ssh-summary.sh >> /var/log/ssh-summary.log 2>&1") | crontab -

Ese último comando merece atención. El crontab -l 2>/dev/null lista las tareas existentes, redirigiendo los errores a la nada por si el crontab está vacío. El resultado se combina con la nueva línea usando un pipe, y todo se pasa a crontab - que reescribe el crontab completo. Es la forma segura de añadir una tarea sin borrar las que ya tienes.

Elemento Qué hace
chmod +x Da permiso de ejecución al script. Sin esto, cron intentará correrlo y fallará en silencio.
0 23 * * * Sintaxis cron: minuto 0, hora 23, todos los días del mes, todos los meses, todos los días de la semana. Cada noche a las 23:00.
>> ssh-summary.log Añade la salida al final del log existente. El doble >> es importante: con uno solo sobreescribirías el historial cada noche.
2>&1 Redirige los errores al mismo sitio que la salida estándar. Si el script falla, el error queda registrado en el log.

Explicación no técnica

Imagina que contratas a un vigilante nocturno para tu empresa. Le dices exactamente qué revisar cada noche (los intentos de acceso, las alarmas activadas, quién entró y cuándo) y le pides que deje un informe escrito en tu mesa antes de que llegues por la mañana. Eso es cron con el script. El chmod +x es darle las llaves al vigilante. La línea de crontab es el horario que firma. Y el >> es que el informe se acumula en el mismo cuaderno, no que tire el del día anterior.

Glosario Técnico: El Vocabulario del Hardening

Si llegaste hasta aquí y hay términos que se repiten en los posts pero no quedaron del todo claros, este glosario es para ti. No es un diccionario de Wikipedia: cada definición está contextualizada para lo que hemos estado haciendo.

Término Qué significa en este contexto
Hardening El proceso de reducir la superficie de ataque de un sistema: eliminar lo innecesario, restringir permisos y cerrar vectores de entrada. No es instalar un antivirus; es diseñar el sistema para que sea difícil de comprometer.
Privilegio Mínimo Principio que dice: cada usuario, proceso o servicio solo debe tener acceso a lo estrictamente necesario para su función. Nada más. Si algo sale mal, el daño queda contenido en ese ámbito.
Superficie de Ataque La suma de todos los puntos donde un atacante puede intentar entrar: puertos abiertos, servicios corriendo, usuarios con acceso, software instalado. Cuanto menor sea, mejor.
Bloatware Software instalado por defecto que no cumple ninguna función útil en el entorno actual. En un servidor cloud, cups (impresoras) o avahi-daemon (descubrimiento de red local) son bloatware puro.
Movimiento Lateral Técnica de ataque donde, después de comprometer una cuenta o servicio, el atacante se mueve por el sistema buscando cuentas con más privilegios. La separación de usuarios lo dificulta enormemente.
Blast Radius El radio de daño si algo es comprometido. Si el usuario services es vulnerado, el blast radius está limitado a lo que ese usuario puede hacer. El objetivo del diseño es que ese radio sea lo más pequeño posible.
VPN Mesh (Tailscale) Una red privada donde todos los dispositivos autorizados están directamente conectados entre sí, sin un servidor central que enrute el tráfico. Tailscale implementa esto sobre WireGuard: rendimiento alto, configuración simple, sin puertos públicos expuestos.
Proxy Inverso Un servidor (Nginx, Caddy) que recibe todas las peticiones web en los puertos 80 y 443 y las distribuye internamente a los contenedores correctos. El mundo exterior solo ve una puerta; lo que hay detrás es invisible.
Shadow IT Servicios o procesos corriendo en el sistema que el administrador olvidó que instaló o desplegó. Contenedores parados desde hace meses, scripts heredados, paquetes sin usar. Superficie de ataque invisible porque nadie la vigila.
CVE Common Vulnerabilities and Exposures. El sistema de identificación global de vulnerabilidades de seguridad. Cuando unattended-upgrades parchea tu sistema, está cerrando CVEs conocidos antes de que alguien los explote.
Rootkit Software malicioso diseñado para ocultarse en el sistema con privilegios de root. Modifica binarios del sistema para pasar desapercibido. rkhunter lo busca comparando los hashes de los binarios contra una base de datos conocida.
headless Un servidor que opera sin interfaz gráfica. Solo terminal. Es el estándar en producción: consume menos recursos, tiene menos dependencias y elimina una categoría entera de vulnerabilidades relacionadas con entornos de escritorio.

Explicación no técnica

Si llegaste a este glosario directamente, bienvenido. La seguridad tiene mucho vocabulario propio que al principio parece diseñado para excluir gente. No lo es: son términos precisos para describir situaciones concretas. Lo importante no es memorizar las definiciones, sino entender la lógica que hay detrás. Y esa lógica, en el fondo, es siempre la misma: limitar el acceso, vigilar lo que pasa y reducir el daño cuando algo falla. Todo lo demás es implementación.

> SYSTEM_READY > NODE_ONLINE

< session_end // node: exit >
> INFOGRATECH_CORE_SHELL X
$