Implementar 2FA SSH en Linux requiere instalar el módulo PAM google-authenticator, generar el secret TOTP para el usuario y modificar la configuración de PAM y sshd para exigir el código OTP tras la contraseña o la clave pública. En 10 minutos bloqueas cualquier acceso con credenciales robadas. Las credenciales SSH de un servidor de staging se vendieron en Telegram. El servidor era accesible desde el exterior y usaba autenticación solo con contraseña. El 2FA habría bloqueado el ataque por completo. La intrusión duró 6 horas antes de que alguien notara la carga anómala en la CPU. El 73% de las brechas de seguridad parte de credenciales robadas, según el Verizon DBIR 2025. Cuando implementé la autenticación de dos factores en 50 servidores para una organización sanitaria pública, la criticidad principal era evitar bloquear a los operadores durante el turno de noche. La solución es probar manteniendo una sesión abierta. Aquí explico cómo hacerlo.
Requisitos Previos para 2FA SSH Linux / Entorno de Prueba
Necesitas un servidor Ubuntu 20.04 o 22.04 LTS, acceso SSH con privilegios sudo y una app TOTP en el teléfono (Google Authenticator, Authy, Microsoft Authenticator). El 51% de los ataques de fuerza bruta SSH tiene éxito en 12 horas si la contraseña es débil (Rapid7 2025). No pruebes este procedimiento directamente en un servidor en producción sin una sesión de fallback abierta.
Instalar google-authenticator-libpam
El paquete conecta el sistema de autenticación Linux (PAM) con el generador de códigos temporales TOTP.
sudo apt update
sudo apt install libpam-google-authenticator
En RHEL/CentOS el paquete está en EPEL: sudo yum install google-authenticator. La instalación no modifica el acceso SSH todavía. Solo habilita el módulo.
Configurar el 2FA para el usuario
Cada usuario que deba usar 2FA genera su propio secret. No ejecutes este comando con sudo para otro usuario, porque el secret terminaría en la home de root.
google-authenticator
El comando hace cinco preguntas. Responde Y a todas:
- Do you want authentication tokens to be time-based? Y
- Do you want to inhibit multiple uses? Y (bloquea el reuse del código)
- Do you want to enforce rate-limiting? Y (máximo 3 intentos cada 30 segundos)
- Do you want to limit the number of failures before banning? Y (máximo 3 fallos)
- Do you want to enable rate-limiting in the log file? Y
El terminal muestra el QR code, el secret key manual y los scratch codes para el recovery.
Escanear el código QR con la app
Abre Google Authenticator en tu teléfono. Selecciona Añadir cuenta, escanea el QR code mostrado en el terminal. La app empieza a generar códigos de 6 dígitos que cambian cada 30 segundos. Si no puedes escanear el QR desde un terminal remoto, introduce el secret key manual que aparece debajo del QR.
Guarda el secret key en un lugar seguro. Lo necesitas para regenerar la cuenta si pierdes el teléfono.
Modificar PAM para habilitar 2FA
PAM (Pluggable Authentication Modules) decide cómo Linux verifica las credenciales. Modifica el archivo que gestiona SSH.
sudo nano /etc/pam.d/sshd
Añade esta línea al inicio del archivo, antes de las otras líneas auth:
# /etc/pam.d/sshd: auth required pam_google_authenticator.so
auth required pam_google_authenticator.so nullok
El parámetro nullok es crítico. Permite el acceso sin 2FA si el usuario aún no ha generado el archivo .google_authenticator en su home. Sin nullok, todos los usuarios sin secret quedan bloqueados. Elimina nullok solo después de que cada usuario haya configurado su secret.
Modificar sshd_config
El demonio SSH debe saber que requiere el challenge-response para el código OTP.
sudo nano /etc/ssh/sshd_config
Busca y modifica estas líneas:
# sshd_config: ChallengeResponseAuthentication yes
ChallengeResponseAuthentication yes
Si la línea está comentada o configurada en no, SSH ignora la solicitud OTP de PAM. Verifica también que PasswordAuthentication sea yes si quieres la combinación contraseña + OTP. Si usas solo clave pública + OTP, PasswordAuthentication permanece en no, pero necesitas la configuración Keyboard-Interactive descrita en la documentación oficial de OpenSSH.
Aplica los cambios:
sudo systemctl restart sshd
Probar sin cerrar la sesión actual
Este es el paso donde muchos se bloquean fuera. NO cierres la sesión SSH activa. Abre un nuevo terminal e intenta el login.
ssh usuario@ip-servidor
El sistema pide primero el Verification code (el OTP del teléfono), luego la contraseña. Si el login falla, vuelve a la sesión original, elimina la línea de /etc/pam.d/sshd, reinicia sshd y verifica qué falló.
Si el login funciona, el acceso ahora requiere contraseña y OTP. Cierra la sesión de prueba.
Gestionar los códigos de respaldo y excluir usuarios
El comando google-authenticator genera 5 scratch codes (emergency scratch codes). Son códigos de un solo uso que funcionan una vez, sin el teléfono.
Guarda estos códigos offline, en un lugar accesible sin el servidor. Si pierdes el teléfono y no tienes los scratch codes, quedas bloqueado. Para regenerar los códigos, ejecuta google-authenticator de nuevo, pero el secret cambia y debes actualizar la app.
Las cuentas de servicio o los usuarios administrativos de backup no tienen un teléfono para el OTP. El parámetro nullok gestiona este caso. Si el archivo .google_authenticator no existe en la home del usuario, PAM salta la verificación OTP y pide solo la contraseña.
Para excluir un usuario específico incluso después de activar 2FA para todos, crea un archivo de skip en PAM.
sudo nano /etc/pam.d/sshd
Modifica la línea auth required:
auth [success=done default=ignore authinfo_missing=ignore] pam_google_authenticator.so nullok_skippable
Alternativamente, usa la directiva PAM user sense=ignore para especificar los usuarios excluidos. La documentación de Arch Linux explica las opciones avanzadas de PAM para estos escenarios.
Errores Comunes y Resolución de Problemas
Acceso denegado después de reiniciar sshd: ChallengeResponseAuthentication sigue en no en sshd_config, o la línea PAM está en posición incorrecta (después de las otras auth). Debe ser la primera línea auth.
SSH pide solo contraseña, sin OTP: nullok está activo y el usuario no generó el secret, o sshd no se reinició tras el cambio.
Código OTP rechazado: El tiempo del servidor está desfasado. TOTP tolera una ventana de 30 segundos. Sincroniza el servidor con NTP (sudo timedatectl set-ntp true).
Bloqueado fuera: Si no mantuviste la sesión abierta y el login falla, necesitas acceso por consola física o vía proveedor cloud (VNC) para restaurar los archivos.
Preguntas Frecuentes sobre 2FA en SSH
¿Cómo funciona 2FA SSH con clave pública en lugar de contraseña?
Si usas clave pública, SSH ya autentica la identidad. Para añadir 2FA, configura Keyboard-Interactive en sshd_config y PAM pedirá el OTP tras la verificación de la clave. El procedimiento difiere de la configuración contraseña+OTP.
¿Cuál es la diferencia entre nullok y nullok_skippable?
nullok permite el login sin OTP si el archivo secret no existe. nullok_skippable hace lo mismo pero no registra el evento como error PAM. Para la transición gradual usa nullok, para las cuentas de servicio permanentes usa nullok_skippable.
¿Puedo usar Authy o Microsoft Authenticator en lugar de Google Authenticator?
Sí. El módulo PAM usa el estándar TOTP (RFC 6238). Cualquier app compatible con TOTP genera códigos válidos. El QR code es universal.
¿Qué hacer si pierdo el teléfono y los scratch codes?
Necesitas acceso por consola física o web console del proveedor. Accede como root, elimina la línea pam_google_authenticator.so de /etc/pam.d/sshd, reinicia sshd, luego regenera el secret para el usuario.
¿El 2FA SSH es requerido por la compliance NIS2?
El artículo 21 de NIS2 requiere MFA para los accesos a los activos críticos. 2FA SSH en servidores de producción es un requisito directo para organizaciones sanitarias y PA.
Conclusiones con Puntos Clave Operativos
Añadir Google Authenticator a SSH Linux requiere 10 minutos y bloquea el 100% de los accesos con credenciales robadas. Los tres pasos críticos: instala el módulo PAM, genera el secret para cada usuario, modifica sshd_config y PAM. El riesgo mayor es bloquearte fuera durante la prueba. Mantén siempre una sesión abierta. Elimina nullok solo cuando todos los usuarios tengan el secret activo. Las organizaciones sujetas a NIS2 deben implementar MFA en todos los accesos críticos. 2FA SSH es el primer paso.