Checklist de endurecimiento SSH para servidores Linux expuestos

Una checklist ordenada para un servidor Linux que debe aceptar SSH desde internet: por dónde empezar, qué se equivocan la mayoría de las listas, y qué puede esperar.

9 min de lectura

Cómo usar esta lista

Las checklists de endurecimiento suelen fallar por un motivo: están ordenadas por tema y no por riesgo, la gente baja por ellas y se queda sin tiempo hacia la configuración del banner, sin haber llegado nunca a la autenticación.

Esta está ordenada. La sección 1 elimina la vía por la que los servidores Linux se comprometen de verdad. Si solo tienes una hora, haz la sección 1 y para — vale más que todo lo demás junto.

Da por supuesto un servidor que debe aceptar SSH desde direcciones arbitrarias. Si el tuyo no, la sección 3 se reduce a una regla de firewall, y eso es una buena noticia.

1. Autenticación

Los compromisos empiezan con credenciales válidas mucho más a menudo que con un demonio sin parchear. Esta sección es todo el asunto.

  • Desactiva por completo la autenticación por contraseña: PasswordAuthentication no. Es la línea de mayor valor de este documento — sin contraseña que adivinar, los ataques de adivinación no pueden tener éxito en absoluto.
  • Pon también KbdInteractiveAuthentication no. Si lo olvidas, PAM sigue ofreciendo una petición de contraseña, así que las contraseñas siguen funcionando y no has cambiado nada. Verifica con sshd -T, no leyendo el archivo.
  • Pon PermitRootLogin en prohibit-password, o en no si root nunca entra directamente. Root es el primer nombre de toda lista de ataque.
  • Protege las claves privadas con frase de paso y mantenlas fuera de máquinas compartidas. Una clave filtrada es exactamente igual de mala que una contraseña filtrada, y se filtra por las mismas vías: portátil robado, commit accidental, entorno de un runner de CI.
  • Rota las claves cuando alguien se vaya, y audita ~/.ssh/authorized_keys en cada cuenta. Las claves viejas se acumulan en silencio y nadie las quita nunca.
  • Define AllowUsers o AllowGroups como lista explícita. Incluso en solo-claves, esto evita que una cuenta de servicio recién creada quede accesible remotamente por accidente.

2. Reducir lo que es accesible

La segunda pregunta después de «quién puede entrar» es «qué más está escuchando». Cada puerto abierto es un servicio que alguien está probando ahora mismo.

  • Inventaria qué escucha realmente: ss -tlnp en el host, y luego verifica desde otra red cuáles responden. Las dos listas rara vez coinciden.
  • Enlaza a localhost los servicios que no necesiten ser remotos — las bases de datos especialmente. Un PostgreSQL o un Redis en 0.0.0.0 es un problema mucho mayor de lo que SSH ha sido nunca.
  • Ten un firewall de denegación por defecto: nftables o el front-end de la distribución, permitiendo solo lo que hayas nombrado.
  • Restringe las direcciones de origen de SSH si puedes. Si el conjunto legítimo es pequeño y estable, es el control real más barato — y deja de funcionar en cuanto alguien viaja.
  • Considera salir del puerto 22 para reducir ruido, entendiendo que es reducción de ruido y no protección.

3. Bloqueo automático de inicios de sesión fallidos

Solo-claves elimina el riesgo de una adivinación exitosa. No elimina el tráfico, y esta sección va del tráfico.

Los bots no conocen tu configuración. Siguen conectándose, ofreciendo contraseñas y siendo rechazados — cada intento cuesta una conexión TCP, un fork de sshd, una línea de registro y una porción de CPU. A su aire, un servidor expuesto absorbe miles al día, y el registro rota lo bastante rápido como para perder los eventos que necesitabas.

fail2ban es la respuesta estándar y un punto de partida razonable. Configúralo bien — bantime -1, ignoreip con tus propias direcciones, y monitorización del número de baneos en vez del estado del servicio, porque su modo de fallo es el silencio. Sus límites estructurales: baneos de direcciones sueltas frente a botnets que rotan rangos, estado que no sobrevive a una reconstrucción, y ningún conocimiento compartido entre tus servidores.

SSH Protector hace el mismo trabajo como agente gestionado: baneos de subred, permanentes y restaurados al arrancar, el puerto SSH real desde la configuración de sshd, tu dirección en lista blanca desde la instalación, reputación compartida entre todos los servidores protegidos, y una consola que responde si sigue funcionando.

4. Detalles de configuración de sshd

Merecen ajustarse: individualmente menores, en conjunto una superficie de ataque menor. Ejecuta sshd -t tras cada cambio y recarga en vez de reiniciar.

  • MaxAuthTries 3 — menos intentos de credenciales por conexión, así que un bot necesita más conexiones para el mismo número de pruebas.
  • MaxSessions y MaxStartups reducidos — limita cuántas conexiones sin autenticar pueden estar en vuelo a la vez, que es justo lo que consume una avalancha.
  • LoginGraceTime 30 — una conexión sin autenticar no debería quedarse abierta dos minutos.
  • X11Forwarding no y AllowAgentForwarding no salvo que algo los necesite de verdad. El reenvío de agente en particular permite a un destino comprometido usar tu clave.
  • Solo algoritmos modernos: quita cifrados, MAC e intercambios de claves heredados. Las distribuciones actuales traen valores por defecto sensatos, así que comprueba antes de copiar un fragmento de endurecimiento de hace una década — varios populares rompen ya más de lo que arreglan.

5. Registro y detección

No puedes investigar lo que no registraste, y la configuración por defecto conserva menos de lo que esperas.

  • Confirma que el LogLevel de sshd sea al menos INFO. Puesto en QUIET no registra ningún fallo de autenticación.
  • Sube la retención de journald, o envía los registros fuera del host. El journal local de una máquina comprometida es evidencia que un atacante puede editar; una copia en otro sitio no lo es.
  • Alerta sobre lo que importa en vez de sobre el volumen: un inicio de sesión correcto desde una dirección desconocida, una línea Accepted password en un servidor que debería ser solo-claves, una nueva entrada en sudoers, una nueva entrada en authorized_keys.
  • Revisa los inicios de sesión correctos de vez en cuando y a propósito. Los fallos son ruido; un éxito que no puedes explicar es todo el asunto.

6. Parches y recuperación

Los dos últimos, y el orden entre ellos importa menos que el hecho de que existan ambos.

Mantén sshd y el kernel al día — activa las actualizaciones de seguridad desatendidas si tu proceso de cambios lo permite. OpenSSH ha tenido vulnerabilidades previas a la autenticación y tendrá más, y la ventana entre divulgación y explotación masiva se mide ya en días.

Después las copias de seguridad, con una propiedad que importa más que todas las demás: al menos una copia que el propio servidor no pueda alcanzar ni borrar. Los operadores de ransomware buscan el destino de las copias antes de cifrar nada, y un montaje en el que el host comprometido pueda escribir no es una copia de seguridad, es una segunda copia esperando a ser destruida. Y restaura una — una copia que nunca se ha restaurado es una hipótesis, no un plan.

FAQ

¿Cuál es el paso de endurecimiento SSH más importante?
Desactivar la autenticación por contraseña. Con PasswordAuthentication no y KbdInteractiveAuthentication no no hay contraseña que adivinar, así que toda la categoría de ataques de adivinación de credenciales pasa a ser imposible en vez de simplemente más difícil. Nada más en una lista de endurecimiento se le acerca por el esfuerzo que exige.
¿Debo cambiar el puerto SSH como parte del endurecimiento?
Merece la pena para reducir ruido, no para proteger. Salir del 22 suele recortar el volumen de inicios de sesión fallidos más de un 90% y vuelve legible tu registro, pero SSH se anuncia en su banner de versión, así que cualquier escáner de rango completo lo encuentra de inmediato. Trátalo como higiene de registros, nunca como un control.
¿Forma parte fail2ban de un endurecimiento SSH correcto?
Es una base razonable y mucho mejor que nada. Pon bantime en -1, mete tus propias direcciones en ignoreip, y monitoriza el número de baneos en vez del estado del servicio — una jail cuyo filtro dejó de coincidir tras una actualización de distribución parece idéntica a una semana tranquila.
¿Protege MaxAuthTries contra la fuerza bruta?
Solo marginalmente. Limita los intentos de credenciales dentro de una conexión, así que un atacante simplemente abre más conexiones; eleva ligeramente su coste sin cambiar el resultado. Ponerlo en 3 merece la pena, pero no es una defensa — lo que reduce de verdad el tráfico es bloquear el origen en el firewall.

Cubrir la sección 3 en un minuto

Baneos de subred, permanentes y restaurados al arrancar, el puerto SSH real detectado, reputación compartida entre todos los servidores protegidos. Un servidor gratis para siempre, sin tarjeta.