2026-07-08 · Team Fenrir
Hardening de SSH en Linux: lo que de verdad importa
Si tu servidor Linux está expuesto a internet, su SSH ya está siendo golpeado: la fuerza bruta sobre credenciales es una técnica tan extendida que MITRE la cataloga en cuatro variantes distintas (T1110), y SSH es uno de sus objetivos favoritos. La buena noticia: cuatro intervenciones — claves en lugar de contraseñas, sshd_config corregido, accesos restringidos, fail2ban — cierran la puerta a la casi totalidad de estos ataques. Aquí va la checklist, comando a comando.
¿Por qué precisamente SSH?
Porque es la puerta de administración: quien entra por ahí tiene (o puede obtener) el control completo de la máquina. MITRE ATT&CK cataloga la adivinación de credenciales como T1110 (Brute Force) — password guessing, password spraying, credential stuffing — y el uso de SSH para moverse entre máquinas comprometidas como T1021.004 (Remote Services: SSH). Traducido: a los atacantes SSH les sirve tanto para entrar como para extenderse una vez dentro.
El punto débil no es el protocolo — es sólido — sino la configuración: contraseñas débiles, root expuesto, claves olvidadas. Todo cosas que se arreglan en una tarde.
¿Cómo paso de contraseñas a claves?
Es la intervención individual más eficaz. Una contraseña se adivina a base de intentos; una clave ed25519 no. Tres comandos:
# 1. Genera el par de claves (en TU ordenador, no en el servidor)
ssh-keygen -t ed25519 -a 64
# 2. Instala la clave pública en el servidor
ssh-copy-id usuario@servidor
# 3. Verifica que entras SIN contraseña antes de continuar
ssh usuario@servidor
Solo cuando el paso 3 funciona, desactiva las contraseñas. Ojo con el valor por defecto: en el manual oficial de OpenSSH, PasswordAuthentication es yes por defecto — si no lo apagas tú, la fuerza bruta sigue siendo posible. En /etc/ssh/sshd_config:
PasswordAuthentication no
KbdInteractiveAuthentication no
Después systemctl reload sshd — manteniendo abierta la sesión actual: si te has equivocado en algo, todavía tienes una shell para arreglarlo.
¿Qué corrijo en sshd_config?
Las directivas que importan, con los valores por defecto reales del manual (muchas guías online los ponen mal):
PermitRootLogin no— el valor por defecto de OpenSSH esprohibit-password: root ya solo puede entrar con clave, no con contraseña. Ponerlo ennoes aun mejor: se entra con un usuario nominal y se eleva consudo, así cada acción en los logs tiene nombre y apellidos.MaxAuthTries 3— el valor por defecto es 6 intentos por conexión. Tres le bastan a cualquiera que tenga la clave correcta.LoginGraceTime 30— el valor por defecto es 120 segundos para completar el login. Treinta son suficientes, y reducen las conexiones aparcadas por los escáneres.AllowUsers mario deploy(oAllowGroups ssh-users) — por defecto cualquier usuario del sistema puede hacer login. Listar explícitamente quién puede entrar deja fuera cuentas de servicio y usuarios olvidados.ClientAliveInterval 300+ClientAliveCountMax 2— cierra las sesiones muertas en lugar de dejarlas colgadas.
¿Y el puerto? Moverlo del 22 reduce el ruido, no el riesgo: los escáneres masivos paran, un atacante dirigido lo encuentra con un escaneo de puertos. Está bien hacerlo por higiene de logs, nunca como medida de seguridad.
¿Cómo restrinjo quién puede conectarse?
Dos niveles, complementarios:
- A nivel de red — si la administración se hace desde IP conocidas (oficina, VPN), el firewall es la primera línea:
ufw allow from 203.0.113.10 to any port 22y nada más. Un SSH inalcanzable es un SSH inatacable. - A nivel de sshd —
AllowUsers/AllowGroupscomo arriba, y bloquesMatchpara reglas dirigidas (por ejemplo: el usuariodeploysolo puede entrar desde la IP del CI, solo con clave, sin shell interactiva).
¿Sigue mereciendo la pena fail2ban?
Sí, como capa adicional. fail2ban hace una sola cosa y la hace bien: banea las IP que acumulan errores de autenticación leyendo los logs en tiempo real. Con las contraseñas desactivadas la fuerza bruta clásica ya es estéril, pero fail2ban mantiene limpios los logs, frena el reconocimiento y protege también los demás servicios expuestos.
apt install fail2ban # Debian/Ubuntu
systemctl enable --now fail2ban
fail2ban-client status sshd # jail activa, IPs baneadas
Su límite estructural: es reactivo y por IP. Un ataque distribuido entre miles de IP — pocos intentos cada una — se queda bajo el umbral de baneo. Por eso es la capa extra, no el cimiento.
Y las claves, ¿quién las gestiona?
La otra cara de las claves: se acumulan. El NIST dedicó un informe entero al problema (IR 7966): en las infraestructuras reales las claves SSH proliferan sin inventario ni caducidad — empleados que se fueron hace años y siguen en algún authorized_keys, claves de automatización con más privilegios de los necesarios. El hardening no termina con la configuración: necesita higiene continua.
En la práctica, cada trimestre:
# ¿Quién puede entrar en esta máquina?
for u in $(cut -d: -f1 /etc/passwd); do
f="/home/$u/.ssh/authorized_keys"
[ -s "$f" ] && echo "== $u" && wc -l < "$f"
done
Toda clave que no sepas de quién es debe eliminarse. Toda clave de automatización debe restringirse (command=, from= en authorized_keys) al mínimo que necesita hacer.
¿Cómo verifico que la configuración aguanta?
No te fíes del archivo: pregúntale a sshd qué está aplicando de verdad (includes, overrides y bloques Match incluidos):
sshd -T | grep -Ei 'passwordauth|permitroot|maxauthtries|allowusers|kbdinteractive'
Si la salida dice passwordauthentication no y permitrootlogin no, la puerta está cerrada de verdad. Después mira los logs — ahí es donde se ve el asedio:
journalctl -u ssh --since today | grep -c 'Failed\|Invalid'
En un servidor expuesto, ese número no será cero. Está bien así: el objetivo del hardening no es parar los intentos, es volverlos todos inútiles.
¿Por qué la monitorización importa tanto como el hardening?
Porque el hardening es una fotografía, y el servidor es una película. La configuración perfecta de hoy se erosionará: un compañero reactiva las contraseñas “cinco minutos”, una herramienta de aprovisionamiento reescribe sshd_config, una clave de más acaba en authorized_keys. Y la fuerza bruta de las 2 de la madrugada no te manda un correo por sí sola.
Hace falta algo que observe en continuo: los logs de autenticación, los cambios en sshd_config y en las claves autorizadas, los patrones de acceso anómalos — y que actúe cuando toca, no el lunes por la mañana. Es exactamente el trabajo de Fenrir SOC: correlaciona los logs SSH con sus demás monitores, clasifica el ataque y, por encima del umbral de confianza, lo bloquea solo, en menos de un segundo. Tú firmas la checklist de esta página una vez; él la defiende cada noche.
Preguntas frecuentes
¿Son mejores las claves SSH que las contraseñas?▾
Sí. Una clave ed25519 no se adivina a base de intentos: la fuerza bruta funciona con contraseñas, no con claves. El cambio completo requiere dos pasos: instalar la clave con ssh-copy-id y después poner PasswordAuthentication no (el valor por defecto de OpenSSH es yes).
¿Debo poner PermitRootLogin no?▾
El valor por defecto de OpenSSH ya es prohibit-password (root solo entra con clave). Ponerlo en no es aun así más limpio: obliga a entrar con un usuario nominal y elevar con sudo, de modo que cada acción en los logs tiene nombre y apellidos.
¿Cambiar el puerto SSH mejora la seguridad?▾
Reduce el ruido de los escáneres automáticos en los logs, no la seguridad real: un atacante dirigido encuentra el puerto con un escaneo. Hazlo si quieres, pero después de las claves, PasswordAuthentication no y fail2ban — nunca en su lugar.
¿Basta fail2ban contra la fuerza bruta?▾
Ayuda: banea las IP que acumulan errores de autenticación y corta el ruido. Pero es reactivo y por IP: un ataque distribuido lo esquiva. La defensa real es eliminar las contraseñas; fail2ban es la capa extra, no el cimiento.