Un servidor recién creado con IP pública empieza a recibir intentos de login automatizados en cuestión de minutos. En esta guía aplicarás la configuración básica que todo servidor Ubuntu o Debian debería tener antes de alojar nada: un usuario administrador sin privilegios de root, acceso SSH solo con claves, un firewall que bloquea todo excepto lo necesario, Fail2Ban contra ataques de fuerza bruta y parches de seguridad automáticos. Los comandos son para Ubuntu 24.04 LTS; las diferencias con Debian 12 se indican donde importan.
Requisitos previos
- Un servidor recién instalado con Ubuntu 24.04 LTS o Debian 12, por ejemplo un VPS de CubePath.
- Acceso como
rootpor SSH, con contraseña o clave. - Una clave SSH en tu equipo local. Si todavía no tienes una, créala con
ssh-keygen -t ed25519como se explica en la guía para conectarse a un servidor por SSH. - Acceso a la consola del panel de CubePath por si te quedas sin SSH durante los cambios.
Importanteno cierres la sesión SSH con la que trabajas hasta haber comprobado desde una segunda terminal que puedes volver a entrar. Así, si algo falla, sigues teniendo una sesión abierta para deshacerlo.
Paso 1: Actualizar el sistema
Empieza con todos los paquetes al día para no desplegar software con vulnerabilidades ya corregidas. Conéctate como root:
ssh root@your_server_ip
Actualiza la lista de paquetes e instala las actualizaciones:
apt update && apt upgrade -y
Si se actualizó el kernel o alguna librería básica, el sistema crea el archivo /var/run/reboot-required. Compruébalo:
ls /var/run/reboot-required 2>/dev/null && echo "Reinicio necesario"
Si aparece el mensaje, reinicia con reboot y vuelve a conectarte antes de seguir.
Paso 2: Crear un usuario administrador
Trabajar siempre como root significa que cualquier error o comando mal copiado tiene efecto sobre todo el sistema. Crea un usuario normal; sustituye your_user por el nombre que quieras:
adduser your_user
adduser te pedirá una contraseña (la necesitarás para sudo) y unos datos opcionales que puedes dejar en blanco. Añade el usuario al grupo sudo para que pueda ejecutar comandos administrativos:
usermod -aG sudo your_user
Notaen Debian 12 la imagen mínima puede no incluir
sudo. Instálalo antes conapt install sudo.
Comprueba los grupos del usuario:
groups your_user
your_user : your_user sudo users
Paso 3: Dar acceso SSH con clave al nuevo usuario
Si ya entras como root con una clave, lo más sencillo es copiar el authorized_keys de root al nuevo usuario con los permisos correctos:
rsync --archive --chown=your_user:your_user ~/.ssh /home/your_user
Si entras como root con contraseña, ejecuta en su lugar este comando desde tu equipo local:
ssh-copy-id your_user@your_server_ip
Ahora, sin cerrar la sesión de root, abre una segunda terminal en tu equipo y conéctate con el nuevo usuario:
ssh your_user@your_server_ip
Debes entrar sin contraseña (o solo con la frase de paso de tu clave). Comprueba que sudo funciona:
sudo whoami
root
A partir de aquí, trabaja desde la sesión de your_user.
Paso 4: Endurecer la configuración de SSH
Con el acceso por clave funcionando, desactiva el login de root y la autenticación por contraseña. En lugar de editar /etc/ssh/sshd_config, crea un archivo propio en /etc/ssh/sshd_config.d/, que sobrevive a las actualizaciones del paquete. OpenSSH aplica el primer valor que encuentra para cada opción y lee los archivos de ese directorio por orden alfabético, así que el prefijo 00- garantiza que tus valores ganan a otros archivos como 50-cloud-init.conf, que en muchas imágenes activa PasswordAuthentication yes.
sudo nano /etc/ssh/sshd_config.d/00-hardening.conf
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
Comprueba que la sintaxis es correcta. Si no hay errores, el comando no muestra nada:
sudo sshd -t
Revisa la configuración efectiva que usará el servicio:
sudo sshd -T | grep -Ei '^(permitrootlogin|passwordauthentication|kbdinteractiveauthentication|pubkeyauthentication|maxauthtries)'
maxauthtries 3
permitrootlogin no
pubkeyauthentication yes
passwordauthentication no
kbdinteractiveauthentication no
Recarga el servicio para aplicar los cambios. Las sesiones abiertas no se cortan:
sudo systemctl reload ssh
Desde otra terminal local, comprueba que tu usuario sigue entrando y que root ya no puede:
ssh your_user@your_server_ip
ssh root@your_server_ip
root@your_server_ip: Permission denied (publickey).
Paso 5: Activar el firewall UFW
UFW (Uncomplicated Firewall) es la forma sencilla de gestionar el firewall del kernel en Ubuntu. La política por defecto recomendada es bloquear todo el tráfico entrante y permitir el saliente. Ubuntu 24.04 lo trae instalado; en Debian 12 instálalo con sudo apt install ufw.
sudo ufw default deny incoming
sudo ufw default allow outgoing
Permite SSH antes de activar el firewall o perderás la conexión:
sudo ufw allow OpenSSH
Si vas a servir webs, abre también HTTP y HTTPS (sudo ufw allow 80/tcp y sudo ufw allow 443/tcp). Activa el firewall y confirma con y:
sudo ufw enable
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y
Firewall is active and enabled on system startup
Comprueba las reglas:
sudo ufw status verbose
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), deny (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp (OpenSSH) ALLOW IN Anywhere
22/tcp (OpenSSH (v6)) ALLOW IN Anywhere (v6)
Paso 6: Instalar Fail2Ban
Aunque SSH ya no acepte contraseñas, los bots seguirán intentándolo y llenando los logs. Fail2Ban lee los intentos fallidos y bloquea temporalmente las IPs que insisten. Instálalo junto con el módulo que le permite leer el journal de systemd:
sudo apt install fail2ban python3-systemd
Nunca edites jail.conf, que se sobrescribe al actualizar. Crea jail.local con tu configuración:
sudo nano /etc/fail2ban/jail.local
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
ignoreip = 127.0.0.1/8 ::1
[sshd]
enabled = true
backend = systemd
Con esto, una IP que falle 5 veces en 10 minutos queda bloqueada una hora. backend = systemd hace que funcione igual en Debian 12, que no instala rsyslog ni crea /var/log/auth.log. Si te conectas siempre desde una IP fija, añádela a ignoreip para no bloquearte a ti mismo.
Activa el servicio y comprueba la jail:
sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd
Status for the jail: sshd
|- Filter
| |- Currently failed: 0
| |- Total failed: 0
| `- Journal matches: _SYSTEMD_UNIT=sshd.service + _COMM=sshd
`- Actions
|- Currently banned: 0
|- Total banned: 0
`- Banned IP list:
Tras unas horas verás crecer Total banned. Para desbloquear una IP concreta usa sudo fail2ban-client set sshd unbanip 203.0.113.50.
Paso 7: Activar las actualizaciones de seguridad automáticas
El paquete unattended-upgrades instala cada día las actualizaciones de seguridad sin intervención. Viene instalado en Ubuntu; asegúrate de que está y actívalo:
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Responde Yes en la pantalla que aparece. Esto crea /etc/apt/apt.conf.d/20auto-upgrades; comprueba su contenido:
cat /etc/apt/apt.conf.d/20auto-upgrades
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
Por defecto solo se instalan actualizaciones del origen de seguridad y el servidor no se reinicia solo. Si quieres reinicios automáticos cuando un parche del kernel lo requiera, edita /etc/apt/apt.conf.d/50unattended-upgrades y descomenta estas líneas ajustando la hora:
Unattended-Upgrade::Automatic-Reboot "true";
Unattended-Upgrade::Automatic-Reboot-Time "04:00";
Haz una prueba en seco para verificar que la configuración es válida:
sudo unattended-upgrade --dry-run --debug 2>&1 | tail -n 5
El registro de cada ejecución real queda en /var/log/unattended-upgrades/.
Paso 8: Ajustar zona horaria y sincronización de hora
Unos logs con la hora correcta son imprescindibles para investigar cualquier incidente, y Fail2Ban depende de ellos. Ubuntu 24.04 y Debian 12 sincronizan la hora con systemd-timesyncd. Ajusta la zona horaria (en servidores, UTC también es una buena elección):
sudo timedatectl set-timezone Europe/Madrid
timedatectl
Local time: jue 2026-09-24 10:15:32 CEST
Universal time: jue 2026-09-24 08:15:32 UTC
Time zone: Europe/Madrid (CEST, +0200)
System clock synchronized: yes
NTP service: active
Si System clock synchronized indica no, activa la sincronización con sudo timedatectl set-ntp true.
Paso 9: Revisar los servicios expuestos
Todo servicio que escucha en una interfaz pública es superficie de ataque. Lista los puertos abiertos:
sudo ss -tulpn
En un servidor recién configurado solo deberías ver SSH en el puerto 22 y servicios locales (en 127.0.0.1 o 127.0.0.53, como el resolvedor DNS de systemd). Si aparece algo que no necesitas, desactívalo, por ejemplo:
sudo systemctl disable --now nombre_del_servicio
Solución de problemas
Te has quedado sin acceso SSH. Entra por la consola del panel de CubePath con tu usuario, revierte el cambio (por ejemplo, borra /etc/ssh/sshd_config.d/00-hardening.conf o ejecuta sudo ufw allow OpenSSH) y recarga SSH con sudo systemctl reload ssh.
Permission denied (publickey) con el usuario nuevo. Casi siempre son permisos o propietario. Desde root:
chown -R your_user:your_user /home/your_user/.ssh
chmod 700 /home/your_user/.ssh
chmod 600 /home/your_user/.ssh/authorized_keys
Fail2Ban ha bloqueado tu propia IP. Desde la consola o desde otra IP, ejecuta sudo fail2ban-client set sshd unbanip tu_ip y añade tu IP a ignoreip.
fail2ban no arranca. Revisa el error con sudo journalctl -u fail2ban -n 30. Suele ser un error de sintaxis en jail.local; sudo fail2ban-client -t valida la configuración.
Conclusión
Tu servidor ya tiene un usuario administrador con sudo, SSH solo por clave y sin root, un firewall que únicamente deja pasar SSH, Fail2Ban bloqueando a quien insiste y parches de seguridad instalados a diario. Es una base sólida para instalar cualquier aplicación. A partir de aquí puedes cambiar el puerto SSH por defecto, repasar la gestión de usuarios y permisos en Linux o configurar copias de seguridad antes de poner el servidor en producción.
