Hardening SSH paso a paso: asegura tu servidor

Hardening SSH paso a paso: asegura tu servidor

Hardening SSH paso a paso: asegura tu servidor

Exponer SSH a internet sin configurarlo bien es invitar al ruido. Aquí están los pasos reales para que tu servidor aguante sin sorpresas desagradables.

Por Javier · Actualizado: 2025-08-15

Asegurar SSH significa reducir la superficie de ataque de tu servidor antes de que los bots lo encuentren — y lo harán, porque el puerto 22 recibe intentos de fuerza bruta continuos desde internet. Los pasos esenciales son: deshabilitar login por contraseña (PasswordAuthentication no), usar claves públicas, restringir usuarios con AllowUsers y activar fail2ban para banear IPs reincidentes.

Abriste el puerto 22 y no estás solo

Si acabas de abrir el puerto 22 en tu router y has echado un vistazo a /var/log/auth.log, es probable que ya hayas visto líneas como Failed password for root from 185.x.x.x. Llevan ahí desde los primeros minutos. No es que alguien te tenga manía: son bots automatizados que escanean internet de forma continua, probando combinaciones de usuario y contraseña en cualquier servidor expuesto que encuentran.

Es normal que con eso te entren las dudas. ¿He hecho algo mal al exponerlo? ¿Debería cerrarlo todo de nuevo y olvidarme? No necesariamente. Exponer un servidor a internet tiene solución, pero requiere configurarlo bien desde el principio en lugar de dejarlo con los ajustes por defecto que trae OpenSSH.

En este post voy paso a paso por las medidas que aplico en mis propios servidores: ajustar parámetros clave en sshd_config, configurar fail2ban y desactivar el acceso por contraseña. Sin promesas de seguridad absoluta —eso no existe—, pero sí las suficientes para que la mayoría de los bots se aburran y sigan de largo.

Por qué importa

Claves en lugar de contraseñas

Con autenticación por clave pública/privada eliminas el vector de fuerza bruta. Sin contraseña que robar, no hay ataque posible.

fail2ban banea atacantes

Tras 5 intentos fallidos (maxretry por defecto), fail2ban bloquea la IP automáticamente. No detiene botnets distribuidas, pero elimina el 95% del ruido.

Limita quién entra

AllowUsers en sshd_config restringe el acceso a cuentas específicas. Root no debería poder conectar directamente: PermitRootLogin no.

Puerto no estándar reduce ruido

Mover SSH del 22 a cualquier puerto alto elimina bots oportunistas. No es seguridad real, pero el log de auth.log se vuelve legible.

Lo que pasa en el puerto 22 desde el primer minuto

Acabas de abrir el puerto 22 al mundo. Puede que sea para gestionar un VPS, un servidor casero o un Raspberry Pi con IP pública. Lo que no se ve —pero ocurre— es que en cuestión de minutos los bots de fuerza bruta ya están llamando a la puerta.

No es paranoia. Puedes comprobarlo tú mismo con journalctl -u ssh --since "10 minutes ago" después de exponer el puerto. Lo normal es ver decenas de intentos de login fallidos desde IPs de todo el mundo en muy poco tiempo.

Esto no significa que tu servidor esté en peligro inmediato. Significa que necesitas tenerlo bien configurado antes de que algo falle.

Autenticación por clave pública: el cambio más importante que puedes hacer

Si solo haces una cosa, que sea esta. La autenticación por clave pública elimina el vector de ataque de fuerza bruta sobre contraseñas: aunque un bot pruebe millones de combinaciones, sin la clave privada no entra.

Funciona así: generas un par de claves (pública y privada) en tu máquina local. La clave pública va al servidor. La privada nunca sale de tu equipo.

Generar el par de claves en tu máquina local

En Linux o macOS, desde la terminal:

ssh-keygen -t ed25519 -C "mi-servidor-vps"

ed25519 es el algoritmo recomendado hoy. Si necesitas compatibilidad con sistemas más viejos, rsa -b 4096 también es válido. El flag -C es solo un comentario para identificar la clave después.

Cuando te pida passphrase, ponla. Es una capa más: si alguien roba tu archivo de clave privada, todavía necesita esa passphrase para usarla.

Copiar la clave pública al servidor

La forma más limpia:

ssh-copy-id -i ~/.ssh/id_ed25519.pub usuario@ip-del-servidor

Si no tienes ssh-copy-id disponible (Windows sin WSL, por ejemplo), el proceso manual es:

  1. Muestra el contenido de ~/.ssh/id_ed25519.pub en tu máquina local.
  2. Conéctate al servidor con contraseña.
  3. Añade esa línea al archivo ~/.ssh/authorized_keys del usuario en el servidor.
  4. Ajusta los permisos: chmod 700 ~/.ssh && chmod 600 ~/.ssh/authorized_keys.

Antes de deshabilitar el login por contraseña, verifica que puedes conectarte con la clave desde una terminal nueva. Si funciona, sigues adelante. Si no, investigas primero.

Los parámetros de sshd_config que vale la pena revisar

El archivo /etc/ssh/sshd_config controla el comportamiento del servidor SSH. La mayoría de distribuciones modernas tienen valores razonables por defecto, pero hay unos cuantos que merece la pena revisar explícitamente.

Después de cada cambio, recarga el servicio con systemctl reload sshd (en Debian/Ubuntu puede ser systemctl reload ssh). Y antes de cerrar la sesión activa, abre una segunda conexión para verificar que todo sigue funcionando.

Deshabilitar el login por contraseña

Una vez que tienes la clave pública instalada y comprobada:

PasswordAuthentication no

Con esto los bots de fuerza bruta se vuelven irrelevantes para este vector: no hay contraseña que probar.

No permitir login directo como root

PermitRootLogin no

Si necesitas hacer tareas de root, entra con tu usuario y usa sudo. El login directo de root es innecesario en casi cualquier escenario y amplifica el daño potencial si algo falla.

Restringir qué usuarios pueden conectarse por SSH

AllowUsers tu_usuario otro_usuario

O si prefieres gestionar por grupos:

AllowGroups sshusers

Esto limita el radio de acción: aunque existiera una cuenta comprometida en el sistema, si no está en la lista, no puede acceder por SSH.

Timeouts de sesión inactiva

ClientAliveInterval 300
ClientAliveCountMax 2

El servidor envía un keepalive cada 300 segundos. Si el cliente no responde dos veces seguidas, cierra la sesión. Evita sesiones zombi abiertas indefinidamente, que pueden ser un problema si dejas una terminal abierta en un equipo ajeno.

fail2ban: un filtro para las IPs que insisten demasiado

fail2ban monitoriza los logs del sistema y banea temporalmente las IPs que acumulan demasiados intentos fallidos. No es una solución mágica —no detiene ataques distribuidos donde cada IP de una botnet intenta solo una vez— pero reduce enormemente el ruido de bots simples y mantiene los logs limpios.

En Debian/Ubuntu:

apt install fail2ban

Configuración básica para SSH

No edites /etc/fail2ban/jail.conf directamente; ese archivo se sobreescribe con las actualizaciones del paquete. Crea un override en /etc/fail2ban/jail.local:

[sshd]
enabled = true
port    = ssh
maxretry = 5
bantime  = 1h
findtime = 10m

Con esto, una IP que falle 5 veces en 10 minutos queda baneada durante una hora. Puedes ajustar bantime a valores más agresivos (24h, 7d) si ves ruido persistente de las mismas subredes.

Para ver el estado de los baneos activos en cualquier momento:

fail2ban-client status sshd

Cambiar el puerto: reduce el ruido, no es seguridad real

Mover SSH del puerto 22 a algo como el 2222 o el 49200 elimina prácticamente todo el ruido de los bots más simples, que solo sondean el puerto estándar. Los logs de autenticación quedan mucho más limpios, lo que hace más fácil detectar actividad sospechosa real entre el ruido.

El cambio va en sshd_config:

Port 2222

Y si usas un firewall (UFW es el más habitual en Ubuntu), tienes que abrir el nuevo puerto antes de cerrar el 22:

ufw allow 2222/tcp
ufw delete allow 22/tcp

Lo importante es entender qué no hace esto: no cifra mejor las conexiones, no elimina vulnerabilidades de OpenSSH, y un escaneo de puertos básico lo descubre en segundos. Si lo combinas con clave pública y fail2ban, suma algo de comodidad operacional. Solo, no protege nada con entidad.

Un detalle práctico que se olvida: si cambias el puerto, o lo configuras en ~/.ssh/config de tu máquina local para no tener que acordarte, o vas a estar escribiendo -p 2222 para siempre.

Verifica la configuración antes de cerrar la sesión

Este paso se salta más de lo que debería, y es el que evita el escenario clásico de quedarte fuera de tu propio servidor.

  • Abre una segunda terminal y conéctate desde ahí con la nueva configuración antes de cerrar la sesión activa.
  • Valida la sintaxis del archivo con sshd -t: no reinicia el servicio, solo comprueba si hay errores.
  • Si cambiaste el puerto, conecta con ssh -p nuevo_puerto usuario@servidor desde esa segunda terminal.
  • Si deshabilitaste contraseñas, confirma que la autenticación por clave funciona antes de cerrar la sesión anterior.

Si algo sale mal y te quedas sin acceso, dependes de la consola de rescate del proveedor (en un VPS) o de acceso físico (en hardware propio). Vale la pena el minuto extra de verificación.

Preguntas frecuentes

Q: ¿Cambiar el puerto SSH ya me protege suficiente?

A: Cambiar el puerto reduce el ruido de bots automatizados que atacan el 22 por defecto, pero no es seguridad real. Un escaneo de puertos básico lo descubre en segundos. Combínalo siempre con autenticación por clave pública y deshabilitar PasswordAuthentication para tener protección efectiva.

Q: ¿Qué pasa si deshabilito PasswordAuthentication antes de subir mi clave?

A: Te quedas fuera del servidor sin posibilidad de entrar por SSH. Antes de poner 'PasswordAuthentication no' en sshd_config, verifica en una sesión aparte que tu clave pública funciona y puedes autenticarte con ella sin contraseña.

Q: ¿Por qué fail2ban no me protege de todas las IPs atacantes?

A: fail2ban banea IPs individuales tras N intentos fallidos (por defecto 5 intentos, 10 minutos de ban), pero no detiene ataques distribuidos donde una botnet usa miles de IPs distintas, cada una haciendo pocos intentos. Es una capa útil, no una solución completa.

Q: ¿Cuándo debo usar AllowUsers en sshd_config?

A: Siempre que el servidor tenga más de una cuenta de sistema y no todas necesiten acceso SSH. AllowUsers limita explícitamente qué usuarios pueden autenticarse, reduciendo la superficie de ataque si alguna cuenta auxiliar queda con contraseña débil o sin clave configurada.

Q: ¿Qué pasa si dejo PermitRootLogin en 'yes'?

A: Cualquier atacante que consiga credenciales válidas tendría acceso root directo, sin pasar por sudo ni dejar trazas en logs de escalada. En servidores expuestos a internet, PermitRootLogin debe estar en 'no' o como mínimo en 'prohibit-password' si necesitas acceso root remoto puntual.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *