El NIST Cybersecurity Framework (CSF) es un marco voluntario para gestionar el riesgo de ciberseguridad. Su versión 2.0, publicada en 2024, organiza los resultados que debe lograr una organización en seis funciones: Gobernar, Identificar, Proteger, Detectar, Responder y Recuperar. El CSF no dice qué comandos ejecutar; dice qué resultados conseguir. En este tutorial traducirás cada función a controles concretos y verificables en servidores Ubuntu 24.04, de forma que puedas documentar tu perfil actual y avanzar hacia el perfil objetivo.
Requisitos previos
- Uno o varios servidores con Ubuntu 24.04 LTS, por ejemplo VPS de CubePath.
- Un usuario no root con privilegios
sudoy acceso SSH por clave pública. - Acceso a la consola del servidor por si un cambio de firewall o SSH te deja fuera.
- Un lugar fuera del servidor para copias de seguridad y evidencias (otro servidor accesible por SFTP, por ejemplo).
Paso 1: Entender las funciones y definir el alcance (Gobernar)
Esta tabla resume las seis funciones y el tipo de control técnico que les corresponde en un servidor Linux:
| Función | Categorías principales | Controles en esta guía |
|---|---|---|
| Gobernar (GV) | Contexto, estrategia de riesgo, roles, políticas, supervisión, cadena de suministro | Alcance y perfil objetivo (este paso) |
| Identificar (ID) | Gestión de activos (ID.AM), evaluación de riesgos (ID.RA), mejora (ID.IM) | Inventario y parches pendientes (paso 2) |
| Proteger (PR) | Identidad y acceso (PR.AA), datos (PR.DS), plataforma (PR.PS), resiliencia (PR.IR) | Firewall, SSH, fail2ban, parches automáticos (paso 3) |
| Detectar (DE) | Monitorización continua (DE.CM), análisis de eventos (DE.AE) | auditd y AIDE (paso 4) |
| Responder (RS) | Gestión (RS.MA), análisis (RS.AN), comunicación (RS.CO), mitigación (RS.MI) | Captura de evidencias y contención (paso 5) |
| Recuperar (RC) | Ejecución del plan de recuperación (RC.RP), comunicación (RC.CO) | Copias y prueba de restauración (paso 6) |
Gobernar es nueva en la versión 2.0 y es organizativa: define quién es responsable de la seguridad, qué riesgo es aceptable y qué políticas aplican. Antes de tocar un servidor, escribe al menos:
- Alcance: qué servidores y servicios entran (por ejemplo, "los 6 servidores de producción de la aplicación de facturación").
- Responsables: quién aprueba cambios, quién responde a incidentes y a quién se escala.
- Perfil actual y perfil objetivo: para cada categoría que aplique, en qué estado estás hoy y dónde quieres estar. Una tabla sencilla basta:
| Categoría | Estado actual | Objetivo | Prioridad |
|---|---|---|---|
| ID.AM | Sin inventario | Inventario mensual automático | Alta |
| PR.AA | SSH con contraseña | Solo clave, sin root | Alta |
| DE.CM | Sin auditoría | auditd y AIDE en todos los servidores | Media |
| RC.RP | Copias sin probar | Prueba de restauración trimestral | Alta |
Los pasos siguientes cubren esas filas.
Paso 2: Inventariar activos y riesgos (Identificar)
No puedes proteger lo que no sabes que existe. Crea un directorio para el inventario:
sudo install -d -m 700 /var/lib/csf/inventario
Guarda la información básica del sistema, los servicios que escuchan en red y los paquetes instalados:
inv=/var/lib/csf/inventario/$(date +%F)
sudo install -d -m 700 "$inv"
hostnamectl | sudo tee "$inv/sistema.txt" > /dev/null
sudo ss -tulpn | sudo tee "$inv/puertos.txt" > /dev/null
systemctl list-units --type=service --state=running --no-pager | sudo tee "$inv/servicios.txt" > /dev/null
dpkg-query -W -f='${Package}\t${Version}\n' | sudo tee "$inv/paquetes.txt" > /dev/null
Revisa los puertos: cada servicio que escuche en 0.0.0.0 o [::] debería estar justificado.
sudo ss -tulpn
Netid State Local Address:Port Peer Address:Port Process
tcp LISTEN 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=812,fd=3))
tcp LISTEN 127.0.0.1:5432 0.0.0.0:* users:(("postgres",pid=990,fd=6))
tcp LISTEN 0.0.0.0:443 0.0.0.0:* users:(("nginx",pid=1021,fd=7))
Para la evaluación de riesgos técnicos (ID.RA), el dato más objetivo es cuántas actualizaciones de seguridad faltan. Ubuntu lo muestra con:
pro security-status
apt list --upgradable 2>/dev/null | grep -- '-security'
Completa el análisis con un escaneo de configuración, por ejemplo con Lynis (sudo apt install lynis && sudo lynis audit system) u OpenSCAP contra el CIS Benchmark, y anota los hallazgos en tu registro de riesgos con su prioridad.
Paso 3: Aplicar salvaguardas (Proteger)
Firewall
Permite solo lo necesario. Añade SSH antes de activar UFW para no quedarte fuera:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose
Status: active
Default: deny (incoming), allow (outgoing), disabled (routed)
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
443/tcp ALLOW IN Anywhere
...
Acceso por SSH
En Ubuntu 24.04 los ficheros de /etc/ssh/sshd_config.d/ se leen primero y gana el primer valor encontrado, así que usa un número bajo para que tu configuración prevalezca sobre 50-cloud-init.conf:
sudo nano /etc/ssh/sshd_config.d/10-csf.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
MaxAuthTries 3
LoginGraceTime 60
X11Forwarding no
LogLevel VERBOSE
sudo sshd -t
sudo systemctl restart ssh
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication'
permitrootlogin no
passwordauthentication no
Confirma desde otra terminal que sigues pudiendo entrar antes de cerrar la sesión actual.
Bloqueo de fuerza bruta
fail2ban bloquea las IP que fallan repetidamente la autenticación. En Ubuntu la jaula de SSH viene activada por defecto:
sudo apt install fail2ban
sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 2
| |- Total failed: 37
...
`- Actions
|- Currently banned: 3
Parches automáticos
Ubuntu instala unattended-upgrades de serie. Verifica que aplica las actualizaciones de seguridad a diario:
cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Paso 4: Monitorizar y detectar anomalías (Detectar)
Auditoría de eventos con auditd
auditd registra en el kernel los cambios en ficheros críticos y los comandos privilegiados, con el usuario original aunque use sudo:
sudo apt install auditd audispd-plugins
sudo nano /etc/audit/rules.d/50-csf.rules
## Cuentas y privilegios
-w /etc/passwd -p wa -k identity
-w /etc/shadow -p wa -k identity
-w /etc/group -p wa -k identity
-w /etc/sudoers -p wa -k privileges
-w /etc/sudoers.d -p wa -k privileges
## Persistencia: tareas programadas y servicios
-w /etc/crontab -p wa -k persistence
-w /etc/cron.d -p wa -k persistence
-w /var/spool/cron -p wa -k persistence
-w /etc/systemd/system -p wa -k persistence
## Claves SSH y configuración del servidor SSH
-w /etc/ssh/sshd_config.d -p wa -k sshd
-w /root/.ssh -p wa -k ssh-keys
## Comandos ejecutados como root por usuarios humanos
-a always,exit -F arch=b64 -S execve -F euid=0 -F auid>=1000 -F auid!=unset -k root-commands
sudo augenrules --load
sudo auditctl -l | wc -l
Prueba la detección de persistencia creando y borrando una tarea:
echo '# prueba' | sudo tee /etc/cron.d/csf-test > /dev/null && sudo rm /etc/cron.d/csf-test
sudo ausearch -k persistence -ts recent -i | grep -m 2 csf-test
Integridad de ficheros con AIDE
AIDE detecta binarios o configuraciones modificados, un indicador típico de intrusión:
sudo apt install aide
sudo aideinit -y -f
sudo aide --config /etc/aide/aide.conf --check
AIDE found NO differences between database and filesystem. Looks okay!!
Tras cada cambio legítimo, revisa el informe y actualiza la base de datos con sudo aideinit -y -f. Envía los logs del sistema a un servidor central para que un atacante no pueda borrar su rastro borrando los ficheros locales.
Paso 5: Preparar la respuesta a incidentes (Responder)
Cuando sospechas de una intrusión, lo primero es capturar el estado volátil del sistema (conexiones, procesos, sesiones) antes de reiniciar o limpiar nada. Prepara el script ahora, no durante el incidente:
sudo nano /usr/local/sbin/ir-capture
#!/usr/bin/env bash
set -euo pipefail
dir="/root/incidentes/$(date +%Y%m%dT%H%M%S)-$(hostname)"
install -d -m 700 "$dir"
cd "$dir"
date -u > fecha-utc.txt
ss -tunap > conexiones.txt
ps auxwwf > procesos.txt
who -a > sesiones.txt
last -F -n 100 > ultimos-accesos.txt
ip addr > ip-addr.txt
ip route > ip-route.txt
systemctl list-units --type=service --state=running --no-pager > servicios.txt
journalctl --since "24 hours ago" --no-pager > journal-24h.txt
ausearch -ts today -i > auditd-hoy.txt 2>&1 || true
tar czf cron.tar.gz /etc/crontab /etc/cron.d /var/spool/cron 2>/dev/null || true
sha256sum -- * > SHA256SUMS
echo "Evidencias guardadas en $dir"
ausearch devuelve un error si no encuentra eventos, de ahí el || true. El fichero SHA256SUMS permite demostrar después que las evidencias no se han alterado.
sudo chmod 750 /usr/local/sbin/ir-capture
sudo /usr/local/sbin/ir-capture
Evidencias guardadas en /root/incidentes/20260925T101500-web01
Durante un incidente real, copia ese directorio fuera del servidor en cuanto termine. Para contener un servidor comprometido sin perder tu acceso, limita SSH a tu IP de administración y bloquea el resto del tráfico entrante:
sudo ufw insert 1 allow from your_admin_ip to any port 22 proto tcp
sudo ufw delete allow OpenSSH
sudo ufw delete allow 443/tcp
Documenta en tu plan de respuesta quién decide la contención, a quién se notifica (RS.CO) y en qué plazos, incluidas las obligaciones legales de notificación que te apliquen.
Paso 6: Recuperar y verificar (Recuperar)
La recuperación depende de tener copias fuera del servidor y de haberlas restaurado alguna vez. Si todavía no tienes copias, restic es una opción sencilla: cifra en origen y guarda los datos en otro servidor por SFTP.
sudo apt install restic
sudo sh -c 'openssl rand -base64 32 > /root/.restic-pass' && sudo chmod 600 /root/.restic-pass
sudo restic -r sftp:backup@your_backup_host:/srv/restic/web01 --password-file /root/.restic-pass init
sudo restic -r sftp:backup@your_backup_host:/srv/restic/web01 --password-file /root/.restic-pass backup /etc /var/www
Guarda una copia de la contraseña fuera del servidor y programa la copia con un temporizador de systemd. Después prueba la restauración, que es lo que de verdad cuenta:
sudo restic -r sftp:backup@your_backup_host:/srv/restic/web01 --password-file /root/.restic-pass \
restore latest --target /root/restore-test --include /etc/ssh
sudo ls /root/restore-test/etc/ssh
sudo rm -rf /root/restore-test
Tras una intrusión, la práctica recomendada es reconstruir el servidor desde una imagen limpia y restaurar solo los datos, en lugar de intentar limpiar el sistema comprometido. Registra las lecciones aprendidas y actualiza el perfil objetivo (ID.IM).
Paso 7: Medir el progreso
Vuelve a la tabla del paso 1 y actualiza el estado actual de cada categoría. Además del perfil, el CSF describe cuatro niveles (Tiers) que reflejan cómo de madura es la gestión del riesgo en la organización, no en un servidor concreto:
| Nivel | Nombre | Características |
|---|---|---|
| 1 | Parcial | Seguridad reactiva, sin procesos definidos |
| 2 | Informado por el riesgo | Prácticas aprobadas por la dirección, pero no aplicadas de forma uniforme |
| 3 | Repetible | Políticas formales, aplicadas y revisadas con regularidad |
| 4 | Adaptativo | Mejora continua basada en lecciones aprendidas e información de amenazas |
Los controles de esta guía, aplicados de forma uniforme con una herramienta de gestión de configuración como Ansible y revisados periódicamente, son la base técnica para alcanzar el nivel 3.
Solución de problemas
Te quedas sin acceso SSH tras activar UFW o cambiar sshd. Entra por la consola del servidor, revisa sudo ufw status numbered y sudo sshd -T, y corrige la regla o el fichero de /etc/ssh/sshd_config.d/ que cause el bloqueo.
fail2ban-client status sshd dice que la jaula no existe. Comprueba que el servicio está activo con systemctl status fail2ban y revisa sudo journalctl -u fail2ban -n 30.
augenrules --load da un error. Busca la línea problemática con sudo augenrules --check y revisa que todas las rutas vigiladas existan.
Conclusión
Has convertido las seis funciones del NIST CSF 2.0 en controles concretos sobre Ubuntu 24.04: alcance y perfil objetivo, inventario y parches pendientes, firewall, SSH y fail2ban, auditoría e integridad de ficheros, captura de evidencias y copias verificadas. Como siguientes pasos, automatiza estos controles con Ansible para aplicarlos igual en todos los servidores, centraliza los logs en un SIEM y revisa el perfil actual frente al objetivo al menos una vez por trimestre.
