Cumplimiento

SSH seguro en servidores Linux: los nueve consejos de siempre, revisados en 2026, y los cuatro que casi nadie aplica

Por Equipo Cloud Privado · · 15 min de lectura
Lista de comprobación con tres marcas grises y una roja junto a una llave y un candado dibujados con trazo blanco

Las claves en 30 segundos

  • Root con contraseña ya está cerrado de serie. PermitRootLogin vale prohibit-password por defecto desde OpenSSH 7.0 (2015). Lo que sigue abierto en las cuatro distribuciones probadas es la contraseña para el resto de usuarios, y eso sí hay que cerrarlo.
  • OpenSSH ya trae su propio freno contra fuerza bruta. Desde la 9.8, PerSourcePenalties corta las conexiones de una IP que acumula fallos. Lo hemos visto en Debian 13: tras seis contraseñas erróneas, el servidor rechazó también la buena. Debian 12 y Ubuntu 24.04 no lo tienen; ahí fail2ban sigue teniendo sentido.
  • /var/log/auth.log ya no existe en Debian. Desde Debian 12, rsyslog no se instala por defecto y los registros de SSH van solo al journal. La orden que dan muchas guías no devuelve nada.
  • Debian y Ubuntu dejan X11Forwarding yes y los reenvíos abiertos. El valor por defecto de OpenSSH es no; el de las distribuciones, no.
  • Lo que más cambia la seguridad casi nunca sale en las listas: certificados firmados por una autoridad propia en lugar de copiar claves a mano, claves restringidas para automatismos y llaves FIDO2 como segundo factor.

Hay un artículo sobre seguridad de SSH que se reescribe cada pocos meses en Medium, en blogs personales y en documentación interna de empresas. El último que nos ha llegado es de Harristar Tech, de julio de 2026, con nueve «errores» que su autor cometió administrando servidores en producción: dejar root abierto, depender de contraseñas, no cambiar el puerto, olvidar el cortafuegos, no frenar la fuerza bruta, no mirar los registros, no actualizar, dar SSH a todo el mundo y no usar doble factor.

Los nueve son razonables, y ninguno es falso. El problema es que esas listas se escriben pensando en el servidor de hace diez años, y las distribuciones han cambiado mucho desde entonces. Así que hemos hecho lo que solemos hacer con estos borradores: comprobar cada consejo en Debian 12, Debian 13, Ubuntu 24.04 y Ubuntu 26.04, instalando openssh-server en contenedores limpios y leyendo la configuración efectiva con sshd -T. Algunos consejos ya vienen hechos. Otros funcionan de forma distinta a como se cuentan. Y hay cuatro medidas que no salen en la lista y que pesan más que la mitad de las que sí salen.

Este artículo se centra solo en SSH. Para la línea base completa del servidor (cortafuegos, parches automáticos, registros, Lynis) está la guía de hardening para Debian y Ubuntu, y para entender por qué OpenSSH es como es, la historia de quién lo creó.

Lo que trae cada distribución de serie

Esto es lo que devuelve sshd -T nada más instalar el servidor, sin tocar nada, el 9 de octubre de 2026:

Ajuste efectivoDebian 12Debian 13Ubuntu 24.04Ubuntu 26.04
Versión de OpenSSH9.210.0p29.6p110.2p1
Root con contraseñacerradocerradocerradocerrado
Contraseña para otros usuariosabiertaabiertaabiertaabierta
X11Forwardingyesyesyesyes
Reenvío de agente y de puertosabiertoabiertoabiertoabierto
Freno de fuerza bruta (PerSourcePenalties)no existeactivono existeactivo
Intercambio de claves poscuántico primeronosí (mlkem768x25519)nosí (mlkem768x25519)
MaxAuthTries6666

Valores leídos con sshd -T en contenedores con las imágenes oficiales. Root aparece como without-password en Debian y Ubuntu 24.04 y como prohibit-password en Ubuntu 26.04: son el mismo valor con dos nombres.

Tres cosas destacan. La contraseña sigue abierta en todas. Debian y Ubuntu activan X11Forwarding en su sshd_config, cuando el valor por defecto de OpenSSH, según su propio manual, es no. Y el salto entre las versiones de 2023-2024 y las de 2025-2026 es grande: con OpenSSH 10 llegan el freno de fuerza bruta y el cifrado poscuántico.

Antes de tocar nada: no quedarte fuera

Todas las guías dicen «edita sshd_config y reinicia». Antes de eso hay tres costumbres que evitan el peor resultado posible, que es dejarte fuera de tu propio servidor:

  1. Deja una sesión abierta mientras cambias la configuración, y prueba el acceso desde una segunda terminal antes de cerrarla. Las sesiones ya establecidas sobreviven a un reinicio de sshd.
  2. Comprueba la sintaxis con sudo sshd -t antes de reiniciar. Si no devuelve nada, el fichero es válido.
  3. Mira el valor efectivo con sudo sshd -T, no el fichero que acabas de editar. Es la única forma de saber lo que el servidor va a aplicar de verdad.

Lo tercero importa por una razón concreta. Las cuatro distribuciones incluyen Include /etc/ssh/sshd_config.d/*.conf al principio de sshd_config, y en SSH gana el primer valor que se lee, no el último. Las imágenes que se despliegan con cloud-init dejan un 50-cloud-init.conf con PasswordAuthentication yes. Si tu ajuste va en 60-seguridad.conf, pierde. Si va en 00-acceso.conf o directamente editado en sshd_config después del Include, también depende del orden. Ponlo en un fichero con número bajo y verifica con sshd -T | grep passwordauthentication.

Y si el servidor es remoto y no tienes consola fuera de banda (IPMI, iDRAC, la consola web del proveedor o la de Proxmox), piénsalo dos veces antes de tocar el puerto o el cortafuegos.

Los nueve consejos, uno a uno

1. Desactivar el acceso de root: ya viene medio hecho

El consejo dice que cambies PermitRootLogin yes por no. Pero en ninguna distribución actual vas a encontrar yes: desde OpenSSH 7.0, publicada en agosto de 2015, el valor por defecto es prohibit-password. Root puede entrar con clave, pero no con contraseña, así que los bots que prueban contraseñas contra root ya fallan siempre.

Poner PermitRootLogin no sigue siendo buena idea en un servidor de aplicaciones: obliga a entrar con un usuario personal, deja rastro de quién fue y pasa por sudo. Con una excepción importante: en un nodo de Proxmox VE no lo hagas. Los nodos del clúster se conectan entre sí como root por SSH, y cerrarlo rompe migraciones y tareas del clúster. Ahí la protección va por otro lado: red de gestión aislada y acceso al panel con 2FA, roles y tokens.

2. Claves en lugar de contraseñas: sí, y cerrando las dos puertas

Este es el consejo que más importa de la lista. El procedimiento es el que cuenta la guía:

ssh-keygen -t ed25519 -C "nombre@equipo"
ssh-copy-id usuario@servidor

Ed25519 es la elección correcta hoy: claves cortas, rápidas y sin los problemas de parámetros de las curvas NIST. Lo que suele faltar es el segundo ajuste. Para que no quede ningún camino con contraseña hay que cerrar dos opciones, no una:

PasswordAuthentication no
KbdInteractiveAuthentication no

KbdInteractiveAuthentication es el método por el que PAM puede seguir pidiendo una contraseña aunque PasswordAuthentication esté a no. Debian y Ubuntu ya lo dejan desactivado, pero conviene fijarlo por si alguien lo cambió. Después, sshd -T y una prueba real: ssh -o PreferredAuthentications=password usuario@servidor debe responder Permission denied (publickey).

Y protege la clave privada con una frase de paso. Una clave sin cifrar en el portátil es una contraseña escrita en un fichero.

3. Cambiar el puerto: menos ruido, misma seguridad

La guía lo dice bien: mover SSH al 2222 no frena a nadie que te busque, pero reduce mucho el ruido de bots en los registros. Es una decisión de comodidad, no de seguridad, y tiene costes: hay que recordarlo en cada cliente, en cada herramienta de automatización y en cada regla de cortafuegos.

Si lo haces, ojo con Ubuntu. Desde Ubuntu 22.10, SSH arranca por activación de socket: quien escucha en el puerto es ssh.socket, no sshd. Desde Ubuntu 24.04, un generador de systemd lee el Port de sshd_config y reescribe el socket, pero solo al recargar systemd. El systemctl restart ssh de la guía no basta:

sudo systemctl daemon-reload
sudo systemctl restart ssh.socket

En Red Hat, Rocky o AlmaLinux hay otro paso más: SELinux solo permite a sshd escuchar en los puertos etiquetados como ssh_port_t, así que hace falta semanage port -a -t ssh_port_t -p tcp 2222.

4. El cortafuegos: mejor por origen que por puerto

El ejemplo de la guía abre el puerto de SSH a todo Internet con ufw allow 2222/tcp. Funciona, pero desaprovecha lo mejor que puede hacer un cortafuegos con SSH, que es limitar desde dónde se puede entrar:

sudo ufw allow from 203.0.113.10 to any port 22 proto tcp

Si tu equipo trabaja desde IP fijas, una regla así elimina casi todo el riesgo de un plumazo. Si no las tiene, la alternativa es no exponer SSH a Internet: entrar por una VPN como WireGuard o por un bastión. Y antes de activar ufw enable en remoto, añade la regla de SSH. Parece obvio hasta que te pasa.

5. Fail2ban: depende de tu versión de OpenSSH

Aquí es donde más ha cambiado el panorama. Desde OpenSSH 9.8 (julio de 2024), sshd trae PerSourcePenalties: lleva la cuenta de lo que hace cada IP y, si acumula fallos de autenticación, conexiones que no llegan a autenticarse o caídas del proceso, deja de aceptarle conexiones durante un tiempo que crece con cada infracción. Está activo por defecto.

Lo hemos probado en Debian 13. Tras seis intentos de contraseña erróneos desde la misma IP, el servidor empezó a cortar la conexión antes de autenticar, con esta línea en el registro:

drop connection #0 from [127.0.0.1]:48886 on [127.0.0.1]:22 penalty: failed authentication

Y en ese momento, la contraseña correcta tampoco entraba. Es lo que se espera de un freno así, y conviene saberlo: si un compañero se equivoca varias veces desde la misma oficina, toda la oficina se queda fuera unos segundos o minutos. La lista de exenciones es PerSourcePenaltyExemptList.

¿Sigue haciendo falta fail2ban? En Debian 12 y Ubuntu 24.04, que llevan versiones anteriores a la 9.8, sí. En Debian 13 y Ubuntu 26.04 es opcional para SSH, aunque sigue aportando dos cosas que sshd no hace: bloquear en el cortafuegos (la IP no llega ni a abrir conexión) y vigilar otros servicios, como el servidor web o el correo. Si lo instalas en Debian, fíjate en que el paquete ya trae la configuración correcta para un sistema sin rsyslog: en Debian 13 su jail.d usa backend = systemd y bloquea con nftables.

6. Revisar los registros: auth.log ya no está

La guía propone tail -f /var/log/auth.log en Debian y Ubuntu. En Debian, desde la versión 12, ese fichero no existe en una instalación nueva: rsyslog dejó de instalarse por defecto y los mensajes de SSH van solo al journal de systemd. Lo dicen las notas de publicación de Debian 12. Ubuntu Server sí mantiene rsyslog y auth.log.

La forma que funciona en todas es preguntar al journal por la unidad:

journalctl -u ssh --since today        # Debian y Ubuntu
journalctl -u sshd --since today       # Red Hat, Rocky, AlmaLinux

Un detalle para quien filtra por nombre de proceso: desde OpenSSH 9.8, el servidor se divide en un proceso que escucha (sshd) y otro por sesión (sshd-session), así que las reglas que buscaban solo sshd pueden perder mensajes. Filtra por unidad.

Más útil que contar intentos fallidos es mirar los accesos que sí entraron. Cada Accepted publickey lleva la huella de la clave usada, y con certificados también su identificador. Si aparece una huella que no reconoces, eso sí es un incidente.

7. Actualizar OpenSSH: sí, y no te fíes del número

Totalmente de acuerdo con el consejo, con un matiz: ssh -V muestra la versión del cliente, no la del servidor. Y el número de versión engaña. Debian 12 sigue diciendo «OpenSSH 9.2», pero lleva parcheados los fallos de seguridad posteriores, como regreSSHion, porque Debian corrige sin cambiar de versión. Lo que hay que comparar es la versión del paquete con los avisos de seguridad de la distribución:

dpkg -l openssh-server        # Debian y Ubuntu
rpm -q openssh-server         # Red Hat y derivadas

Y no lo dejes para el trimestre que viene. En las notas de OpenSSH 10.6, publicada el 6 de octubre de 2026, el equipo avisa de que está recibiendo muchos informes de seguridad hechos con herramientas de IA y que va a publicar versiones con más frecuencia. Las actualizaciones automáticas de seguridad (unattended-upgrades en Debian y Ubuntu) son la forma razonable de seguir ese ritmo.

8. Limitar quién puede entrar: sí, mejor por grupo

AllowUsers y AllowGroups funcionan como dice la guía. Nuestra recomendación es usar el grupo, porque la lista de usuarios acaba desactualizada en cuanto alguien entra o sale del equipo:

sudo groupadd sshusers
sudo usermod -aG sshusers ana
AllowGroups sshusers

En la prueba, un usuario con clave válida pero fuera del grupo recibió Permission denied, y el registro lo explica sin ambigüedad: User bot from 127.0.0.1 not allowed because none of user's groups are listed in AllowGroups.

Para cuentas que solo deben subir ficheros, un bloque Match las encierra en SFTP sin consola:

Match Group soloftp
    ForceCommand internal-sftp
    ChrootDirectory /srv/sftp/%u
    AllowTcpForwarding no
    X11Forwarding no

9. Doble factor: mejor con una llave física que con un código

La guía propone clave SSH más un código de un solo uso. Se puede hacer con PAM y libpam-google-authenticator, combinando métodos con AuthenticationMethods publickey,keyboard-interactive. Funciona, pero añade una pieza de PAM que hay que mantener, y obliga a reactivar KbdInteractiveAuthentication, que acabamos de cerrar. Además, ese módulo en Debian y Ubuntu sigue siendo una instantánea de diciembre de 2019.

Desde OpenSSH 8.2 (febrero de 2020) hay una opción mejor: claves respaldadas por una llave FIDO2 (YubiKey, Nitrokey, SoloKey o similares).

ssh-keygen -t ed25519-sk -O verify-required

La parte privada vive en la llave y no se puede copiar. Cada conexión exige tocar la llave, y con verify-required (OpenSSH 8.4) también el PIN. Es un segundo factor real que no depende de PAM, y en el servidor basta con añadir PubkeyAuthOptions verify-required para exigirlo a todas las claves de este tipo.

Lo que casi nadie aplica y más cambia

La lista de nueve se queda en la superficie del acceso. Estas cuatro medidas no salen en casi ninguna guía de iniciación y, en un equipo de más de dos personas, cambian más que cualquiera de las anteriores.

Certificados SSH en lugar de copiar claves

Con claves sueltas, cada servidor tiene un authorized_keys que alguien mantiene a mano. Cuando una persona deja la empresa, hay que ir servidor por servidor quitando su clave, y siempre se escapa alguno. Los certificados SSH resuelven eso: creas una autoridad propia, firmas la clave de cada persona con una caducidad, y los servidores confían en la autoridad, no en cada clave.

# Una vez: la autoridad de usuarios
ssh-keygen -t ed25519 -f user_ca

# Por persona: firmar su clave pública, válida 8 horas, para el usuario «ana»
ssh-keygen -s user_ca -I ana@portatil -n ana -V +8h id_ed25519.pub

En cada servidor, una línea:

TrustedUserCAKeys /etc/ssh/user_ca.pub

Lo hemos probado en Debian 13: el usuario entra sin que su clave esté en ningún authorized_keys, y el registro deja constancia del certificado: Accepted publickey for ana ... ED25519-CERT ... ID ana@laptop (serial 0) CA ED25519 .... Cuando el certificado caduca, el acceso se acaba solo. No hace falta ningún producto comercial; está en OpenSSH desde 2010. La parte delicada es custodiar la clave de la autoridad, que es la llave maestra de todo.

Claves restringidas para automatismos

Las copias de seguridad, los despliegues y los scripts de monitorización suelen entrar con una clave sin frase de paso. Si esa clave se filtra, da una consola completa. En authorized_keys se puede limitar qué hace cada clave:

restrict,command="/usr/local/bin/backup-dump",from="10.0.0.5" ssh-ed25519 AAAA... backup

restrict desactiva de golpe la terminal, todos los reenvíos y el agente; command fuerza un único comando, pida el cliente lo que pida; from limita la IP de origen. En la prueba, al pedir bash -c id con esa clave, el servidor ejecutó solo el comando forzado.

Cerrar los reenvíos que no usas

Debian y Ubuntu dejan activados el reenvío de X11, el del agente y el de puertos. Si en tus servidores nadie abre aplicaciones gráficas ni hace túneles, ciérralos:

X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no

El reenvío de agente merece una nota aparte. ssh -A es cómodo para saltar de un servidor a otro, pero mientras dura la sesión, cualquiera con root en el servidor intermedio puede usar tu agente para autenticarse como tú en otras máquinas. La alternativa segura es ProxyJump (ssh -J bastion servidor): la conexión al destino sale cifrada de tu equipo y el bastión solo reenvía bytes.

Comprobar la identidad del servidor

La primera vez que te conectas, SSH muestra la huella del servidor y pregunta si confías. Casi todo el mundo responde yes sin mirar. Esa huella es lo que te protege de un servidor suplantado, así que en servidores nuevos conviene comprobarla contra la que muestra la consola del proveedor (ssh-keygen -lf /etc/ssh/ssh_host_ed25519_key.pub). En flotas grandes, los mismos certificados resuelven también esto: una autoridad que firma las claves de los servidores y una línea @cert-authority en el known_hosts de los clientes.

Un fichero de partida

Con todo lo anterior, esta es una configuración razonable para un servidor de aplicaciones con OpenSSH 9.8 o posterior. Va en /etc/ssh/sshd_config.d/00-acceso.conf, con el número bajo para que gane a 50-cloud-init.conf:

PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
AllowGroups sshusers
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
# Solo si usas certificados:
# TrustedUserCAKeys /etc/ssh/user_ca.pub

Después: sudo sshd -t, sudo sshd -T | grep -E "passwordauth|permitroot|allowgroups|forwarding", recarga del servicio y prueba desde otra terminal sin cerrar la que tienes abierta. No es una configuración para un nodo de Proxmox VE, por lo de root, ni para un bastión, que necesita los reenvíos.

Y no añadas líneas de Ciphers, MACs ni KexAlgorithms copiadas de otra guía. Congelan el servidor y le impiden recibir mejoras como el intercambio de claves poscuántico, que es el predeterminado desde OpenSSH 10.0.

La lista, revisada

ConsejoQué viene de serieQué hacer
Quitar rootRoot sin contraseña desde 2015PermitRootLogin no, salvo en nodos de Proxmox
Claves, no contraseñasContraseña abierta en las cuatroCerrar PasswordAuthentication y KbdInteractiveAuthentication, y verificar con sshd -T
Cambiar el puerto22Opcional; en Ubuntu, daemon-reload y reiniciar ssh.socket
CortafuegosSin reglasLimitar por IP de origen, o VPN o bastión
Fail2banPerSourcePenalties desde OpenSSH 9.8Necesario en Debian 12 y Ubuntu 24.04; opcional después
RegistrosSin auth.log en Debian 12 y 13journalctl -u ssh y vigilar los accesos aceptados
ActualizarParches sin cambiar de versiónComparar el paquete con los avisos y automatizar
Limitar usuariosTodos pueden entrarAllowGroups y Match para SFTP
Doble factorNadaLlaves FIDO2 con verify-required
No estaba en la listaX11 y reenvíos abiertosCerrarlos y usar ProxyJump
No estaba en la listaClaves sueltas en cada servidorCertificados con caducidad y claves restringidas

Si heredas un servidor que no configuraste tú, el punto de partida es otro: saber quién puede entrar hoy. Lo explicamos en cómo auditar un servidor Linux heredado.

En Cloud Privado entregamos los servidores con el acceso SSH cerrado a claves, detrás de red privada y con las actualizaciones de seguridad gestionadas. Si gestionas una flota y el authorized_keys de cada máquina es un misterio, podemos ayudarte a ordenarlo.

Preguntas frecuentes

¿Sigue siendo necesario desactivar el acceso de root por SSH?

El acceso de root con contraseña ya está cerrado por defecto desde OpenSSH 7.0. Poner PermitRootLogin no añade trazabilidad, porque obliga a entrar con un usuario personal, y es recomendable en servidores de aplicaciones. En los nodos de Proxmox VE no debe hacerse, porque el clúster usa SSH como root entre nodos.

¿Hace falta fail2ban si tengo OpenSSH 9.8 o posterior?

Para SSH, no es imprescindible: PerSourcePenalties corta las conexiones de las IP que acumulan fallos y viene activo por defecto. Fail2ban sigue siendo útil para bloquear en el cortafuegos y para proteger otros servicios. En Debian 12 y Ubuntu 24.04, que llevan versiones anteriores, sigue siendo recomendable.

¿Por qué no encuentro /var/log/auth.log en Debian?

Porque desde Debian 12 rsyslog no se instala por defecto y los registros van al journal de systemd. Se consultan con journalctl -u ssh. Ubuntu Server sí mantiene auth.log.

He cambiado el puerto de SSH en Ubuntu y sigue escuchando en el 22. ¿Por qué?

Porque desde Ubuntu 22.10 SSH arranca por activación de socket. Tras cambiar el Port en sshd_config hay que ejecutar systemctl daemon-reload y reiniciar ssh.socket, no solo el servicio ssh.

¿Qué ventaja tienen los certificados SSH frente a las claves normales?

Que los servidores confían en una autoridad, no en cada clave. Dar acceso es firmar un certificado; quitarlo es dejar que caduque. No hay que mantener un authorized_keys por servidor y por persona.

¿Qué doble factor recomendáis para SSH?

Una llave FIDO2 con claves ed25519-sk y la opción verify-required, que exige tocar la llave e introducir el PIN. No depende de PAM y la clave privada no se puede copiar fuera de la llave.

Fuentes

  • Harristar Tech, SSH Security Best Practices for Linux Servers: 10 Lessons I Learned Securing Production Servers (Medium, 20 de julio de 2026): la lista de partida.
  • OpenSSH, Release Notes: PermitRootLogin prohibit-password por defecto (7.0), claves FIDO (8.2), verify-required (8.4), PerSourcePenalties y la división en sshd-session (9.8), intercambio poscuántico por defecto (10.0) y el aviso sobre informes de seguridad con IA (10.6).
  • OpenBSD, sshd_config(5): valores por defecto de OpenSSH, incluido X11Forwarding no, y las opciones AllowGroups, Match, PerSourcePenalties y TrustedUserCAKeys.
  • OpenBSD, sshd(8): formato de authorized_keys y las opciones restrict, command y from.
  • OpenBSD, ssh-keygen(1): certificados y claves FIDO.
  • OpenSSH, Post-Quantum Cryptography: por qué el intercambio de claves poscuántico es el predeterminado.
  • Debian, Notas de publicación de Debian 12, capítulo 5: rsyslog deja de instalarse por defecto.
  • Ubuntu Discourse, sshd now uses socket-based activation: la activación por socket desde Ubuntu 22.10 y cómo cambiar el puerto.
  • Debian, libpam-google-authenticator: versión del módulo de PAM para códigos de un solo uso.
  • fail2ban: repositorio del proyecto.

Los valores de la tabla y las líneas de registro salen de pruebas propias con las imágenes oficiales de Debian y Ubuntu en contenedores, hechas el 9 de octubre de 2026.