SSH: solucionar Too many authentication failures
El error Too many authentication failures suele aparecer cuando SSH ofrece más de 6 claves al servidor. Diagnostícalo con ssh -v y limita la clave usada.
Qué significa "Too many authentication failures"
"Too many authentication failures" significa que el cliente SSH ofreció al servidor más claves de las que este estaba dispuesto a comprobar y que el servidor cerró la conexión antes de probar la clave correcta. Casi siempre es un problema del cliente. La clave está en el disco, el servidor la tiene en authorized_keys y ninguno de esos hechos ayuda, porque la conexión terminó demasiado pronto.
La secuencia es la siguiente. ssh-agent contiene todas las claves privadas que haya cargado. El cliente ofrece esas claves al servidor de una en una, porque no puede saber cuál acepta la cuenta. El servidor rechaza cada clave que no está en authorized_keys y cuenta cada rechazo como un intento de autenticación fallido. MaxAuthTries en sshd_config limita cuántos fallos permite una conexión. El valor predeterminado es 6. Si el agente contiene diez claves y la correcta ocupa el octavo lugar, el servidor cierra la conexión antes de llegar a ella.
Por tanto, la solución consiste en hacer que el cliente ofrezca una sola clave: la correcta.
Qué contabiliza el servidor y cómo interviene MaxAuthTries
La autenticación mediante clave pública comienza como un proceso de prueba. El cliente envía una clave pública y pregunta si el servidor aceptaría una firma creada con ella. El servidor responde sí o no. Un «no» cuenta como un intento fallido, igual que una contraseña incorrecta.
La página de manual de sshd_config(5) describe el límite: «Especifica el número máximo de intentos de autenticación permitidos por conexión. Cuando el número de fallos alcanza la mitad de este valor, se registran los fallos adicionales. El valor predeterminado es 6».
Seis intentos son suficientes para una persona que escribe una contraseña. No son muchos para un agente que usa diez claves. Cuando el contador de fallos alcanza el límite, sshd desconecta al cliente y escribe una línea como esta en el registro del sistema:
error: maximum authentication attempts exceeded for deploy from 203.0.113.10 port 51292 ssh2El cliente muestra la otra parte del mismo evento:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22Este fallo es distinto del error de SSH de permiso denegado (publickey). En ese caso, el servidor examinó todo lo que ofreció el cliente y no aceptó ninguna opción. Aquí el servidor dejó de examinar las opciones. Confundir ambos casos hace que se vuelva a copiar una clave que ya era correcta.
Por qué la misma clave funciona desde el portátil de su compañero
La clave y el servidor no tienen ninguna diferencia. El agente de su compañero contiene dos claves y el suyo contiene doce. La clave que llega primero al servidor para su compañero ocupa la novena posición para usted, y para entonces la conexión ya ha terminado.
El recuento aumenta de forma silenciosa. AddKeysToAgent yes en ~/.ssh/config añade al agente cada clave que usa y la deja allí. Los agentes del llavero del escritorio, como GNOME Keyring en Linux o el llavero de inicio de sesión de macOS, cargan las claves al iniciar sesión sin preguntar. Añada una clave de cliente, una clave de un servidor Git y una clave de un equipo de laboratorio a lo largo de un año, y un día un servidor que siempre funcionaba empezará a rechazarle. El servidor no ha cambiado. El agente contiene más claves.
Cómo ver las ofertas con ssh -v
Ejecute la conexión que falla con -v y lea el registro de trazas.
ssh -v deploy@203.0.113.10Hay dos tipos de línea relevantes. Will attempt key: muestra las identidades que el cliente ha reunido, en el orden en que las usará. Offering public key: aparece una vez por cada clave que se envía realmente al servidor.
debug1: Will attempt key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Will attempt key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agent
debug1: Offering public key: /home/you/.ssh/id_ed25519 ED25519 SHA256:AAAA... agent
debug1: Authentications that can continue: publickey,password
debug1: Offering public key: /home/you/.ssh/id_rsa RSA SHA256:BBBB... agentLas rutas, los tipos de clave y las huellas digitales serán diferentes. Debe contar el número de líneas Offering public key: antes de la desconexión. Si las ofertas continúan y la sesión termina sin que aparezca la clave prevista, el diagnóstico está confirmado. La palabra agent al final de una línea indica que esa identidad procede de ssh-agent. La palabra explicit indica que procede de una línea IdentityFile o de -i en la línea de comandos.
A continuación, pregunte al agente qué claves tiene cargadas:
ssh-add -lCada línea de la salida corresponde a una clave cargada. Si muestra The agent has no identities., el agente no es el problema y debe revisar las líneas IdentityFile de ~/.ssh/config. Si muestra Could not open a connection to your authentication agent., no se está ejecutando ningún agente y las ofertas proceden de los archivos de claves predeterminados.
Corrección 1: IdentitiesOnly con una clave por host
IdentitiesOnly yes indica a ssh que ofrezca sólo las identidades configuradas e ignore las adicionales que proporciona el agente. Combínalo con una línea IdentityFile para que el cliente envíe una única oferta.
Host vps
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519_vps
IdentitiesOnly yesGuarda esa configuración en ~/.ssh/config y ejecuta chmod 600 ~/.ssh/config. Si el archivo permite escritura al grupo o a cualquier usuario, ssh se niega a ejecutarlo y muestra Bad owner or permissions on /home/you/.ssh/config. Ahora ssh vps ofrece una sola clave y ssh -v vps debería mostrar exactamente una línea Offering public key:.
Hay dos detalles que suelen sorprender.
IdentitiesOnly yespor sí solo no significa «una clave». Si no hay una líneaIdentityFile, los archivos de identidad predeterminados cuentan como identidades configuradas. Por tanto, ssh sigue probando~/.ssh/id_ed25519,~/.ssh/id_rsay los demás valores predeterminados que encuentre. También necesitas la líneaIdentityFile: cuando se establece una, ssh deja de añadir los valores predeterminados.- El agente sigue realizando la firma.
IdentitiesOnlycontrola qué claves se ofrecen, no quién las firma. Si la clave privada indicada porIdentityFileestá cargada en el agente, el agente genera la firma y nunca se te solicita una frase de contraseña. Incluso puedes apuntarIdentityFileal archivo.pubcorrespondiente. Esto es útil cuando la clave privada sólo existe en el agente o en un token de hardware.
Un detalle de ~/.ssh/config puede deshacer esta corrección sin avisar. La mayoría de las palabras clave usan el primer valor encontrado. Por eso los bloques Host específicos deben aparecer antes de Host *. IdentityFile no sigue esa regla. El manual indica: «Es posible especificar varios archivos de identidad en los archivos de configuración; todas estas identidades se probarán en secuencia». Un IdentityFile dentro de Host * se añade al valor definido para cada host, en lugar de sustituirlo. Por tanto, una línea global olvidada vuelve a añadir una oferta a todas las conexiones.
Si quieres una protección global, establece sólo la opción al final del archivo:
Host *
IdentitiesOnly yesCada host necesitará entonces su propio IdentityFile. Este es el resultado que buscas. Asignar una clave a cada servidor también permite revocar más adelante el acceso de una sola máquina sin volver a emitir todas las claves. Conviene adoptar esta práctica desde el principio: consulta cómo administrar claves SSH por máquina.
Corrección 2: depure o reinicie el agente
Si todavía no puede editar la configuración, vacíe el agente y cargue sólo lo que necesite.
ssh-add -l # list what is loaded
ssh-add -d ~/.ssh/id_rsa # remove one key
ssh-add -D # remove every key
ssh-add ~/.ssh/id_ed25519_vps # load the one you needSi la conexión funciona justo después de ssh-add -D, el agente era la causa. Considérelo una prueba, no una reparación. Un agente de llavero del escritorio vuelve a cargar sus claves en el siguiente inicio de sesión, por lo que el problema reaparecerá mañana. Una línea IdentitiesOnly en ~/.ssh/config persiste después de reiniciar. Un agente vacío no.
También puede asignar una duración a una clave para que el agente la elimine automáticamente:
ssh-add -t 1800 ~/.ssh/id_ed25519_vpsLa clave se elimina 1800 segundos después de añadirla. Reiniciar el agente también funciona, pero el procedimiento depende de cómo se haya iniciado. Un ssh-agent que haya iniciado usted mismo se detiene con ssh-agent -k. Si lo ejecuta desde una unidad de usuario de systemd que haya creado, reinicie esa unidad con systemctl --user restart <unit>. Un agente de llavero se reinicia con la sesión del escritorio.
Corrección 3: el comando puntual para un servidor que sólo usa una vez
Para un host que no va a añadir a su configuración, indique los mismos ajustes en la línea de comandos:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10-i por sí solo es la corrección incorrecta más común. -i añade una clave a la lista de identidades. No elimina de esa lista las claves del agente, por lo que todas las demás ofertas siguen enviándose antes que la suya y la conexión vuelve a fallar al alcanzar el límite. Ejecute ssh -v -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10 sin IdentitiesOnly y verá que primero se ofrecen las claves del agente. -i necesita -o IdentitiesOnly=yes junto a él.
Para excluir por completo al agente en una conexión:
ssh -o IdentityAgent=none -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10ssh lee entonces la clave privada del disco y solicita su frase de contraseña si tiene una.
Las herramientas basadas en ssh aceptan la misma opción:
scp -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps report.tar.gz deploy@203.0.113.10:/tmp/
rsync -av -e "ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" ./site/ deploy@203.0.113.10:/srv/site/
GIT_SSH_COMMAND="ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps" git clone git@example.com:team/repo.gitPor qué el error aparece en el segundo salto
Con ForwardAgent yes, el socket del agente queda disponible en el servidor al que te conectas. Un comando ssh ejecutado en ese servidor usa tu agente local, con todas tus claves, a través del socket reenviado. Por eso el error puede aparecer en el salto desde un host intermedio hasta el servidor final, aunque el primer salto funcione correctamente. Ejecuta echo $SSH_AUTH_SOCK en la máquina intermedia: una salida vacía significa que no hay ningún agente accesible. Una ruta de socket indica que hay algún agente, pero no necesariamente el tuyo, porque un agente iniciado en esa máquina establece la misma variable. Ejecuta también ssh-add -l allí: si muestra las claves de tu propia máquina, el reenvío está activo.
El reenvío del agente tiene un segundo coste. Cualquier persona con acceso root a la máquina intermedia puede usar tu agente para autenticarse como tú mientras la sesión permanezca abierta. ProxyJump evita ambos problemas:
ssh -J deploy@jump.example.com deploy@10.0.0.5ProxyJump abre una conexión a través del host intermedio y se autentica en el servidor final desde tu propia máquina. Así, tu ~/.ssh/config local se aplica en cada salto, incluido IdentitiesOnly. Desactivar ForwardAgent es una medida habitual al reforzar la seguridad de SSH en un VPS.
¿Debería aumentar MaxAuthTries en el servidor?
Normalmente, no. Compruebe primero el valor actual:
sudo sshd -T | grep -i maxauthtriessshd -T muestra la configuración efectiva, incluidos los valores predeterminados, por lo que informa del valor real incluso cuando sshd_config no indica nada al respecto. Añada -C user=deploy,host=example.com,addr=203.0.113.10 si usa bloques Match, porque se evalúan por conexión y, de lo contrario, se omiten.
Aumentar el límite funciona, en el sentido estricto de que un número mayor da más margen a un cliente que se comporta mal:
MaxAuthTries 20Valide el archivo y vuelva a cargar el servicio. Mantenga abierta una segunda sesión mientras lo hace:
sudo sshd -t
sudo systemctl reload ssh # Debian and Ubuntu
sudo systemctl reload sshd # RHEL familySi systemctl is-enabled ssh.socket informa de enabled en Ubuntu 24.04, sshd se activa mediante un socket. ssh.socket de Ubuntu no inicia un daemon nuevo para cada conexión: inicia ssh.service cuando llega la primera conexión, y ese servicio sigue ejecutándose y gestiona las conexiones posteriores. La recarga anterior sigue siendo la forma de aplicar el cambio. Si ssh.service todavía no está activo, no hay nada que recargar y la siguiente conexión lo inicia con el archivo nuevo.
Ahora compruebe qué efecto tuvo el cambio. El cliente ofrece claves que este servidor nunca aceptará. Aumentar el límite indica al servidor que procese veinte ofertas rechazadas por conexión en lugar de seis, para cada cliente que se conecte y para cada atacante que intente adivinar contraseñas desde Internet. Cada oferta obliga al servidor a realizar una búsqueda en authorized_keys. Su propio inicio de sesión sigue siendo lento porque la clave correcta continúa al final de la lista. Si añade una decimotercera clave a su agente, volverá al punto de partida y tendrá que solicitar de nuevo un número mayor.
Auméntelo sólo cuando un cliente legítimo necesite presentar realmente varias identidades. En los demás casos, corrija el cliente. Reducirlo es una medida de refuerzo razonable cuando todos los usuarios inician sesión con una clave configurada, ya que un atacante tendrá menos intentos por conexión.
Por qué fail2ban puede bloquearte por esto
sshd no registra cada clave rechazada. Con el valor predeterminado de LogLevel INFO, una clave rechazada para una cuenta real sólo se escribe en el registro cuando el contador de fallos de la conexión alcanza la mitad de MaxAuthTries. Esto es lo que significa el manual cuando indica: «Una vez que el número de fallos alcanza la mitad de este valor, se registran los fallos adicionales». Con el valor predeterminado de 6, las tres primeras ofertas rechazadas no se escriben en el registro. Las tres últimas aparecen como líneas como esta, seguidas de la línea maximum authentication attempts exceeded:
Failed publickey for deploy from 203.0.113.10 port 51292 ssh2: ED25519 SHA256:AAAA...Esas líneas parecen una acumulación de fallos, pero el filtro sshd de fail2ban no las cuenta. El valor predeterminado incluido, publickey = nofail, lee una línea Failed publickey para un usuario válido sólo para obtener la dirección y el nombre de usuario. La línea que cuenta es maximum authentication attempts exceeded, por lo que una conexión que alcanza el límite añade un fallo, no varios. La jaula bloquea la dirección de origen cuando se registran maxretry fallos dentro de findtime. El archivo jail.conf propio de fail2ban establece esos valores en 5 y 10 minutos. Unas cinco conexiones fallidas en diez minutos bastan para bloquear tu propia dirección, y un script o una herramienta que reintenta en bucle alcanza ese límite rápidamente.
El síntoma cambia entonces, y esta es la parte que confunde a muchas personas. Dejas de ver «Too many authentication failures» y empiezas a no ver nada: la conexión queda bloqueada y termina agotando el tiempo de espera, porque el firewall ahora descarta tus paquetes en lugar de responder. Un tiempo de espera donde antes recibías un mensaje de error es la señal. Esta diferencia se explica en Diferencias entre conexión SSH rechazada y conexión SSH agotada por tiempo de espera.
Desde la consola de tu proveedor, o desde una dirección diferente, comprueba la jaula y elimina el bloqueo:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10Pon tu propia dirección en ignoreip dentro de jail.local mientras solucionas el problema del cliente. Después, elimínala cuando termines. La configuración de la jaula se explica en la guía de fail2ban para Ubuntu 24.04.
Qué hacer una sola vez para que esto no vuelva a ocurrir
Asigne a cada servidor su propio bloque Host en ~/.ssh/config, con HostName, User, IdentityFile y IdentitiesOnly yes. Después, ssh vps será corto de escribir, ofrecerá exactamente una clave y no podrá activar MaxAuthTries por mucho que crezca su agente. También mantendrá breve la salida de ssh -v, para que pueda leerla el día que falle otra cosa.
FAQ
¿Cómo corrijo ahora mismo el error "Too many authentication failures"?
Ofrezca una sola clave en lugar de todas. Para conectarse de inmediato, ejecute ssh -o IdentitiesOnly=yes -i ~/.ssh/your_key user@host. Para aplicar una solución permanente, añada un bloque a ~/.ssh/config con HostName, User, IdentityFile apuntando a esa clave, y IdentitiesOnly yes; después, ejecute chmod 600 ~/.ssh/config. Confírmelo con ssh -v: debería aparecer una sola línea Offering public key: para ese host.
¿Por qué ssh -i sigue ofreciendo mis otras claves?
Porque -i añade una identidad a la lista, pero no limita la lista. Las claves cargadas en ssh-agent permanecen en la lista y se siguen ofreciendo, a menudo antes que la suya. Por eso, el servidor puede alcanzar MaxAuthTries antes de que se ofrezca su clave. -o IdentitiesOnly=yes es la opción que limita ssh a las identidades que indique. Use -i y -o IdentitiesOnly=yes juntas, o -o IdentityAgent=none para ignorar por completo el agente en esa conexión.
¿Debo aumentar MaxAuthTries en el servidor para corregirlo?
No, casi nunca. El cliente está enviando claves que este servidor nunca aceptará. Un límite mayor sólo hace que el servidor evalúe más ofertas rechazadas por conexión, para todos los clientes y para cada intento de fuerza bruta que llegue al servidor. Además, el problema volverá a aparecer en cuanto se cargue otra clave en el agente. Compruebe el valor efectivo con sudo sshd -T | grep -i maxauthtries si quiere verificarlo y corrija el cliente con IdentitiesOnly.
¿Por qué empezó a ocurrir en un servidor que funcionaba bien el mes pasado?
El agente tiene más claves. AddKeysToAgent yes en ~/.ssh/config mantiene cargada cada clave que utiliza, y los agentes del almacén de claves del escritorio cargan las claves automáticamente al iniciar sesión. Cuando el número de claves cargadas supera MaxAuthTries en el servidor, cualquier servidor cuya clave aparezca tarde en el orden de oferta empieza a rechazar la conexión. Ejecute ssh-add -l y compare el número de claves con el límite del servidor.
¿Puede fail2ban bloquear mi dirección IP por esto?
Sí, aunque más lentamente de lo que indican los registros del servidor. El filtro predeterminado de fail2ban sshd no cuenta las líneas Failed publickey de un usuario válido. Cuenta la línea maximum authentication attempts exceeded, por lo que cada conexión que alcanza el límite cuenta como un fallo. Con los valores predeterminados incluidos, maxretry = 5 y findtime = 10m, unas cinco conexiones de este tipo en diez minutos bloquean su dirección. La señal es que el error se convierte en una espera y después en un tiempo de espera agotado, porque los paquetes se descartan en lugar de recibir una respuesta. Elimine el bloqueo desde la consola con sudo fail2ban-client set sshd unbanip <your address> y corrija el cliente antes de volver a conectarse.