--- title: "Hardening de un servidor Ubuntu 24.04 paso a paso" description: "Asegura un servidor Ubuntu 24.04: usuario sudo, SSH solo con claves, firewall UFW, parches automáticos, ajustes del kernel, auditd y una auditoría con Lynis." category: "Seguridad del Servidor" language: es source: https://cubepath.com/es/docs/seguridad-del-servidor/hardening-de-servidor-linux-guia-completa updated: 2026-09-25 --- # Hardening de un servidor Ubuntu 24.04 paso a paso Un servidor recién creado y expuesto a Internet empieza a recibir intentos de acceso por SSH en cuestión de minutos. El hardening consiste en reducir la superficie de ataque y dejar rastro de lo que ocurre: menos servicios expuestos, accesos solo con clave, parches al día y registro de los cambios sensibles. En este tutorial aplicarás esas medidas a un servidor Ubuntu 24.04 en un orden seguro, comprobando cada una antes de pasar a la siguiente, y terminarás con una auditoría de Lynis para ver qué queda por mejorar. ## Requisitos previos Para seguir esta guía necesitas: - Un servidor con Ubuntu 24.04 LTS recién instalado, por ejemplo un VPS de CubePath, y su dirección IP (`your_server_ip`). - Acceso como `root` o con un usuario con `sudo`. - Un equipo local con cliente SSH (Linux, macOS o Windows 10/11 con OpenSSH). - Acceso a la consola del servidor desde el panel de tu proveedor, por si te quedas fuera por SSH mientras cambias su configuración. > Importante: mientras modificas SSH o el firewall, mantén siempre abierta una sesión SSH ya iniciada y prueba los cambios desde una segunda terminal. Si algo falla, la sesión abierta te permite deshacerlo. ## Paso 1: Actualizar el sistema Muchas intrusiones aprovechan vulnerabilidades ya corregidas. Antes de nada, instala todas las actualizaciones pendientes: ```bash sudo apt update sudo apt full-upgrade -y ``` Si se ha actualizado el kernel, el sistema lo indica con el archivo `/var/run/reboot-required`. Comprueba si existe y reinicia en ese caso: ```bash [ -f /var/run/reboot-required ] && echo "Reinicio necesario" || echo "No hace falta reiniciar" ``` ```bash sudo reboot ``` ## Paso 2: Crear un usuario administrador Trabajar directamente como `root` hace que cualquier error o credencial robada tenga el máximo impacto. Crea un usuario propio (sustituye `your_user` por el nombre que quieras) y añádelo al grupo `sudo`: ```bash sudo adduser your_user sudo usermod -aG sudo your_user ``` `adduser` te pedirá una contraseña. Úsala solo para `sudo`; el acceso por SSH será con clave. Comprueba que el usuario tiene permisos de administración: ```bash sudo -l -U your_user ``` ```output User your_user may run the following commands on server: (ALL : ALL) ALL ``` ## Paso 3: Configurar el acceso SSH con clave Las claves SSH no se pueden adivinar por fuerza bruta como una contraseña. Desde **tu equipo local**, genera una clave Ed25519 si todavía no tienes una: ```bash ssh-keygen -t ed25519 -C "your_user@portatil" ``` Copia la clave pública al servidor. `ssh-copy-id` la añade a `~/.ssh/authorized_keys` del usuario con los permisos correctos: ```bash ssh-copy-id your_user@your_server_ip ``` Abre una nueva terminal y comprueba que entras con la clave, sin que te pida la contraseña del usuario: ```bash ssh your_user@your_server_ip ``` No sigas al paso siguiente hasta que este acceso funcione. ## Paso 4: Endurecer la configuración de SSH En Ubuntu 24.04, `/etc/ssh/sshd_config` incluye al principio todos los archivos `/etc/ssh/sshd_config.d/*.conf`, en orden alfabético, y para cada opción sshd se queda con **el primer valor** que encuentra. Algunas imágenes cloud crean `50-cloud-init.conf` con `PasswordAuthentication yes`, así que tu archivo debe tener un nombre que se ordene antes, como `00-hardening.conf`: ```bash sudo nano /etc/ssh/sshd_config.d/00-hardening.conf ``` ```text PermitRootLogin no PasswordAuthentication no KbdInteractiveAuthentication no PubkeyAuthentication yes MaxAuthTries 3 LoginGraceTime 30 X11Forwarding no AllowUsers your_user ``` Qué hace cada opción: - `PermitRootLogin no`: nadie puede entrar directamente como `root`. - `PasswordAuthentication no` y `KbdInteractiveAuthentication no`: desactivan el acceso con contraseña, solo se aceptan claves. - `MaxAuthTries 3` y `LoginGraceTime 30`: menos intentos por conexión y menos tiempo para autenticarse. - `X11Forwarding no`: un servidor no necesita reenviar aplicaciones gráficas. - `AllowUsers your_user`: solo los usuarios de la lista pueden iniciar sesión por SSH. Añade más nombres separados por espacios si hace falta. Valida la sintaxis antes de aplicar nada. Si no hay errores, el comando no muestra nada: ```bash sudo sshd -t ``` Comprueba los valores efectivos, que confirman que ningún otro archivo los está pisando: ```bash sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|maxauthtries|allowusers)' ``` ```output permitrootlogin no maxauthtries 3 kbdinteractiveauthentication no passwordauthentication no allowusers your_user ``` Aplica los cambios reiniciando el servicio, que en Ubuntu se llama `ssh`: ```bash sudo systemctl restart ssh ``` Desde una segunda terminal, verifica que sigues entrando con tu usuario y que `root` ya no puede: ```bash ssh your_user@your_server_ip ssh root@your_server_ip ``` ```output root@your_server_ip: Permission denied (publickey). ``` ## Paso 5: Activar el firewall con UFW UFW viene instalado en Ubuntu, pero desactivado. La política recomendada es denegar todo el tráfico entrante y permitir solo lo que usas. Permite SSH primero, para no cortar tu propia conexión. La regla `limit` permite SSH pero bloquea temporalmente una IP que abra 6 o más conexiones en 30 segundos: ```bash sudo ufw default deny incoming sudo ufw default allow outgoing sudo ufw limit OpenSSH ``` Si el servidor va a servir web, abre también HTTP y HTTPS: ```bash sudo ufw allow 80/tcp sudo ufw allow 443/tcp ``` Activa el firewall (responde `y` al aviso de que puede cortar conexiones SSH; la regla anterior mantiene la tuya) y revisa las reglas: ```bash sudo ufw enable sudo ufw status verbose ``` ```output Status: active Logging: on (low) Default: deny (incoming), allow (outgoing), deny (routed) New profiles: skip To Action From -- ------ ---- 22/tcp (OpenSSH) LIMIT IN Anywhere 80/tcp ALLOW IN Anywhere 443/tcp ALLOW IN Anywhere 22/tcp (OpenSSH (v6)) LIMIT IN Anywhere (v6) 80/tcp (v6) ALLOW IN Anywhere (v6) 443/tcp (v6) ALLOW IN Anywhere (v6) ``` > Nota: si usas Docker, los puertos que publica un contenedor con `-p` no pasan por las reglas de UFW. Publica solo lo necesario o enlázalo a `127.0.0.1`. ## Paso 6: Instalar parches de seguridad automáticamente `unattended-upgrades` instala cada día las actualizaciones del repositorio de seguridad de Ubuntu. Viene preinstalado en Ubuntu Server; instálalo por si acaso y actívalo: ```bash sudo apt install unattended-upgrades sudo dpkg-reconfigure -plow unattended-upgrades ``` Responde `Yes` en la pantalla que aparece. Comprueba que ha quedado activado: ```bash cat /etc/apt/apt.conf.d/20auto-upgrades ``` ```output APT::Periodic::Update-Package-Lists "1"; APT::Periodic::Unattended-Upgrade "1"; ``` Las actualizaciones del kernel solo se aplican al reiniciar. Si aceptas reinicios automáticos en una ventana de poco tráfico, añádelo en un archivo propio para no modificar el del paquete: ```bash sudo nano /etc/apt/apt.conf.d/52unattended-upgrades-local ``` ```text Unattended-Upgrade::Automatic-Reboot "true"; Unattended-Upgrade::Automatic-Reboot-Time "04:00"; ``` Haz una simulación para confirmar que la configuración es válida: ```bash sudo unattended-upgrade --dry-run --debug 2>&1 | tail -5 ``` Los resultados de cada ejecución quedan en `/var/log/unattended-upgrades/unattended-upgrades.log`. ## Paso 7: Revisar los servicios expuestos Cada puerto abierto es una posible entrada. Lista los procesos que escuchan en la red: ```bash sudo ss -tulpn ``` ```output Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port Process udp UNCONN 0 0 127.0.0.54:53 0.0.0.0:* users:(("systemd-resolve",pid=512,fd=16)) udp UNCONN 0 0 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=512,fd=14)) tcp LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=512,fd=15)) tcp LISTEN 0 4096 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=801,fd=3),("systemd",pid=1,fd=100)) ``` Lo que escucha en `127.0.0.x` solo es accesible desde el propio servidor. Revisa cualquier servicio en `0.0.0.0` o `[::]` que no reconozcas. Para ver qué servicios arrancan con el sistema: ```bash systemctl list-unit-files --type=service --state=enabled ``` Si encuentras uno que no usas, detenlo y desactívalo (sustituye `nombre_del_servicio`), o desinstala directamente el paquete: ```bash sudo systemctl disable --now nombre_del_servicio ``` ## Paso 8: Ajustar parámetros de red y del kernel Algunos parámetros del kernel reducen la información expuesta y la exposición a ataques de red sencillos. Ubuntu ya trae valores seguros para varios de ellos (como `tcp_syncookies` o `dmesg_restrict`); este archivo los fija explícitamente y añade los que faltan: ```bash sudo nano /etc/sysctl.d/99-hardening.conf ``` ```ini # No aceptar ni enviar redirecciones ICMP net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv6.conf.all.accept_redirects = 0 net.ipv6.conf.default.accept_redirects = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # Rechazar paquetes con enrutamiento de origen net.ipv4.conf.all.accept_source_route = 0 net.ipv6.conf.all.accept_source_route = 0 # Registrar paquetes con direcciones imposibles net.ipv4.conf.all.log_martians = 1 # Protección frente a SYN flood net.ipv4.tcp_syncookies = 1 # Ocultar direcciones del kernel y el buffer de dmesg a usuarios sin privilegios kernel.kptr_restrict = 2 kernel.dmesg_restrict = 1 ``` > Advertencia: si el servidor actúa como router, VPN o nodo de Kubernetes, revisa estos valores antes de aplicarlos. Este archivo no toca `ip_forward`, que Docker y otras herramientas activan cuando lo necesitan. Carga todos los archivos de `/etc/sysctl.d/` y comprueba un par de valores: ```bash sudo sysctl --system > /dev/null sysctl net.ipv4.conf.all.accept_redirects kernel.kptr_restrict ``` ```output net.ipv4.conf.all.accept_redirects = 0 kernel.kptr_restrict = 2 ``` ## Paso 9: Registrar cambios sensibles con auditd `auditd` registra a nivel de kernel quién modifica archivos críticos, incluso si luego se borran los logs de la aplicación. Instálalo: ```bash sudo apt install auditd ``` Crea un archivo de reglas que vigile usuarios, grupos, `sudo` y la configuración de SSH. La opción `-p wa` registra escrituras y cambios de atributos, y `-k` asigna una etiqueta para buscar después: ```bash sudo nano /etc/audit/rules.d/50-hardening.rules ``` ```text -w /etc/passwd -p wa -k identidad -w /etc/shadow -p wa -k identidad -w /etc/group -p wa -k identidad -w /etc/sudoers -p wa -k sudoers -w /etc/sudoers.d/ -p wa -k sudoers -w /etc/ssh/sshd_config -p wa -k sshd -w /etc/ssh/sshd_config.d/ -p wa -k sshd ``` Carga las reglas y compruébalas: ```bash sudo augenrules --load sudo auditctl -l ``` ```output -w /etc/passwd -p wa -k identidad -w /etc/shadow -p wa -k identidad -w /etc/group -p wa -k identidad -w /etc/sudoers -p wa -k sudoers -w /etc/sudoers.d -p wa -k sudoers -w /etc/ssh/sshd_config -p wa -k sshd -w /etc/ssh/sshd_config.d -p wa -k sshd ``` Pruébalo creando y borrando un usuario de prueba, y busca los eventos con la etiqueta `identidad`: ```bash sudo useradd prueba-audit && sudo userdel prueba-audit sudo ausearch -k identidad -i --start today | tail -5 ``` Verás entradas con el comando ejecutado (`comm=useradd`) y el usuario que lo lanzó (`auid=your_user`). ## Paso 10: Comprobar AppArmor y bloquear ataques de fuerza bruta Ubuntu activa AppArmor por defecto, que limita qué puede hacer cada programa con perfil aunque sea comprometido. Confirma que está cargado: ```bash sudo aa-status | head -3 ``` ```output apparmor module is loaded. 120 profiles are loaded. 48 profiles are in enforce mode. ``` Con SSH limitado a claves, los intentos de fuerza bruta ya no pueden tener éxito, pero siguen llenando los logs y consumiendo recursos. Fail2Ban bloquea en el firewall las IP que acumulan fallos. Instálalo; en Ubuntu la jaula de SSH viene activada: ```bash sudo apt install fail2ban sudo fail2ban-client status sshd ``` La guía de Fail2Ban de esta misma sección explica cómo ajustar tiempos de bloqueo, listas blancas y jaulas para otros servicios. ## Paso 11: Auditar el resultado con Lynis Lynis revisa cientos de puntos de configuración y te da una lista priorizada de sugerencias. Instálalo desde los repositorios de Ubuntu y lanza una auditoría: ```bash sudo apt install lynis sudo lynis audit system ``` Al final del informe verás el índice de hardening y las rutas de los resultados: ```output Hardening index : 72 [############## ] Tests performed : 262 ... - Test and debug information : /var/log/lynis.log - Report data : /var/log/lynis-report.dat ``` Revisa la sección `Suggestions` del informe. No todas aplican a cada servidor (por ejemplo, las que piden particiones separadas); prioriza las que afectan a servicios expuestos y a cuentas de usuario. Vuelve a ejecutar Lynis tras cada cambio importante para comparar el índice. ## Solución de problemas - **Te has quedado fuera por SSH**: entra por la consola web del panel, revisa `/etc/ssh/sshd_config.d/00-hardening.conf` (normalmente un `AllowUsers` con un nombre mal escrito) y ejecuta `sudo sshd -t && sudo systemctl restart ssh`. - **SSH sigue aceptando contraseñas**: algún archivo de `/etc/ssh/sshd_config.d/` con un nombre anterior al tuyo en orden alfabético define `PasswordAuthentication yes`. Localízalo con `grep -ri passwordauthentication /etc/ssh/sshd_config /etc/ssh/sshd_config.d/`. - **Un servicio deja de responder tras activar UFW**: falta la regla de su puerto. Añádela con `sudo ufw allow puerto/tcp` y compruébalo con `sudo ufw status numbered`. ## Conclusión Tu servidor Ubuntu 24.04 ya solo acepta acceso SSH con clave y sin `root`, filtra el tráfico entrante con UFW, instala parches de seguridad por sí mismo, expone únicamente los servicios necesarios y registra los cambios en usuarios, `sudo` y SSH. El hardening no es una tarea única: repítelo con cada servicio nuevo que instales. Como siguientes pasos puedes: - Ajustar Fail2Ban con tiempos de bloqueo progresivos y jaulas para tus aplicaciones web. - Configurar copias de seguridad automáticas y comprobar que sabes restaurarlas. - Centralizar los logs y los eventos de auditd en otro servidor para que un atacante no pueda borrarlos.