Errore SSH: Too many authentication failures
Scopri perché SSH offre tutte le chiavi dell'agent, come verificare il problema con ssh -v e come usare IdentityFile e IdentitiesOnly per risolverlo.
Cosa significa "Too many authentication failures"
"Too many authentication failures" significa che il client SSH ha offerto al server più chiavi di quante fosse disposto a verificare. Il server ha quindi chiuso la connessione prima di provare la chiave corretta. Quasi sempre il problema è nel client. La chiave si trova sul disco, il server la contiene in authorized_keys, ma nessuno dei due fatti è sufficiente perché la connessione è terminata troppo presto.
Il flusso è questo. ssh-agent contiene tutte le chiavi private caricate. Il client offre queste chiavi al server una alla volta, perché non può sapere quale chiave sia accettata dall'account. Il server rifiuta ogni chiave che non è presente in authorized_keys e conta ogni rifiuto come un tentativo di autenticazione non riuscito. MaxAuthTries in sshd_config limita il numero di tentativi non riusciti consentiti per una singola connessione. Il valore predefinito è 6. Se l'agent contiene dieci chiavi e quella corretta è l'ottava, il server chiude la connessione prima di arrivare a provarla.
La soluzione consiste quindi nel fare in modo che il client offra una sola chiave: quella corretta.
Cosa conta il server e dove interviene MaxAuthTries
L’autenticazione con chiave pubblica inizia come un gioco di tentativi. Il client invia una chiave pubblica e chiede al server se accetterebbe una firma generata con quella chiave. Il server risponde sì o no. Un «no» è un tentativo fallito, esattamente come una password errata.
La pagina di manuale sshd_config(5) descrive il limite: «Specifica il numero massimo di tentativi di autenticazione consentiti per connessione. Quando il numero di errori raggiunge la metà di questo valore, gli errori successivi vengono registrati nei log. Il valore predefinito è 6.»
Sei tentativi sono più che sufficienti per chi digita una password. Non sono molti per un agent che gestisce dieci chiavi. Quando il conteggio degli errori supera il limite, sshd interrompe la connessione e scrive nel log di sistema una riga simile alla seguente:
error: maximum authentication attempts exceeded for deploy from 203.0.113.10 port 51292 ssh2Il client visualizza l’altra metà dello stesso evento:
Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22Questo errore è diverso da l’errore SSH di autorizzazione negata (publickey). In quel caso, il server aveva esaminato tutto ciò che avevi offerto e non aveva accettato nulla. Qui il server ha smesso di esaminare le chiavi. Confondere i due casi porta a passare un pomeriggio a ricopiare una chiave che era già corretta.
Perché la stessa chiave funziona dal portatile del tuo collega
La chiave e il server sono identici. Il suo agent contiene due chiavi, mentre il tuo ne contiene dodici. La chiave che per lui viene offerta per prima arriva per te al nono tentativo; a quel punto la connessione è già terminata.
Il numero di chiavi aumenta senza che te ne accorga. AddKeysToAgent yes in ~/.ssh/config aggiunge all'agent ogni chiave utilizzata e la lascia memorizzata. Gli agent dei portachiavi desktop, come GNOME Keyring su Linux o il portachiavi di accesso su macOS, caricano le chiavi all'accesso senza chiedere conferma. Se nell'arco di un anno aggiungi una chiave client, una chiave per un host Git e una chiave per un server di laboratorio, un giorno un server che ha sempre funzionato inizia a rifiutare la connessione. Sul server non è cambiato nulla. È aumentato il numero di chiavi nell'agent.
Come vedere le chiavi offerte con ssh -v
Esegui la connessione che fallisce con -v e leggi il trace.
ssh -v deploy@203.0.113.10Sono importanti due tipi di riga. Will attempt key: elenca le identità raccolte dal client, nell’ordine in cui verranno utilizzate. Offering public key: compare una volta per ogni chiave effettivamente inviata al server.
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... agentI percorsi, i tipi di chiave e le impronte digitali saranno diversi. Devi contare il numero di righe Offering public key: prima della disconnessione. Se le offerte continuano a susseguirsi e la sessione termina senza che compaia mai la chiave prevista, la diagnosi è chiara. La parola agent alla fine di una riga indica che l’identità proviene da ssh-agent. La parola explicit indica che proviene da una riga IdentityFile o da -i nella riga di comando.
Poi chiedi all’agent quali chiavi contiene:
ssh-add -lOgni riga dell’output corrisponde a una chiave caricata. Se viene visualizzato The agent has no identities., l’agent non è la causa del problema e devi esaminare le righe IdentityFile in ~/.ssh/config. Se viene visualizzato Could not open a connection to your authentication agent., non è in esecuzione alcun agent e le offerte provengono dai file di chiave predefiniti.
Correzione 1: IdentitiesOnly con una chiave per host
IdentitiesOnly yes indica a ssh di offrire soltanto le identità configurate e di ignorare quelle aggiuntive messe a disposizione dall'agent. Abbinatelo a una riga IdentityFile: il client invierà una sola offerta.
Host vps
HostName 203.0.113.10
User deploy
IdentityFile ~/.ssh/id_ed25519_vps
IdentitiesOnly yesSalvate il contenuto in ~/.ssh/config, quindi eseguite chmod 600 ~/.ssh/config. Un file scrivibile dal gruppo o da tutti gli utenti fa sì che ssh rifiuti di avviarsi e restituisca Bad owner or permissions on /home/you/.ssh/config. A questo punto ssh vps offre una sola chiave e ssh -v vps dovrebbe mostrare esattamente una riga Offering public key:.
Qui ci sono due dettagli che spesso sorprendono.
IdentitiesOnly yesda solo non significa "una chiave". I file di identità predefiniti contano come identità configurate, quindi ssh prova comunque~/.ssh/id_ed25519,~/.ssh/id_rsae gli altri file predefiniti disponibili. Serve anche la rigaIdentityFile.- L'agent esegue comunque la firma.
IdentitiesOnlycontrolla quali chiavi vengono offerte, non chi esegue la firma. Se la chiave privata indicata daIdentityFileè caricata nell'agent, è l'agent a produrre la firma e non viene mai richiesta una passphrase. Potete anche indicare conIdentityFileil file.pubcorrispondente; è la procedura da usare quando la chiave privata risiede soltanto nell'agent o in un token hardware.
Un'impostazione in ~/.ssh/config può annullare questa correzione senza messaggi evidenti. Per la maggior parte delle parole chiave viene usato il primo valore trovato; per questo i blocchi Host specifici devono precedere Host *. IdentityFile non segue questa regola. Il manuale specifica: "È possibile specificare più file di identità nei file di configurazione; tutte queste identità verranno provate in sequenza." Un IdentityFile all'interno di Host * viene aggiunto a quello definito per il singolo host, invece di sostituirlo. Una riga globale dimenticata reintroduce quindi un'offerta aggiuntiva in ogni connessione.
Se volete una protezione globale, impostate soltanto il flag alla fine del file:
Host *
IdentitiesOnly yesOgni host dovrà quindi avere il proprio IdentityFile, che è comunque il risultato desiderato. Indicare una sola chiave per server consente inoltre di revocare in seguito l'accesso a una singola macchina senza dover rigenerare tutto. È una pratica utile da adottare subito: consultate come gestire le chiavi SSH per macchina.
Correzione 2: svuotare o riavviare l'agent
Se non puoi ancora modificare la configurazione, svuota l'agent e carica soltanto ciò che ti serve.
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 needSe la connessione funziona subito dopo ssh-add -D, la causa era l'agent. Consideralo un test, non una correzione. Un agent del portachiavi del desktop ricarica le chiavi al login successivo, quindi il problema si ripresenterà domani. Una riga IdentitiesOnly in ~/.ssh/config persiste dopo un riavvio. Un agent vuoto no.
Puoi anche impostare una durata per una chiave, in modo che sia l'agent a rimuoverla:
ssh-add -t 1800 ~/.ssh/id_ed25519_vpsLa chiave viene rimossa 1800 secondi dopo essere stata aggiunta. Anche riavviare l'agent è una soluzione, ma la procedura dipende da ciò che lo ha avviato. Un ssh-agent avviato manualmente si arresta con ssh-agent -k. Se lo esegui tramite una user unit di systemd che hai creato, riavvia l'unità con systemctl --user restart <unit>. Un agent del portachiavi viene riavviato insieme alla sessione desktop.
Correzione 3: il comando una tantum per un server che utilizzi una sola volta
Per un host che non aggiungerai alla configurazione, specifica le stesse impostazioni nella riga di comando:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10-i da solo è la correzione errata più comune. -i aggiunge una chiave all’elenco delle identità. Non rimuove le chiavi dell’agent da quell’elenco, quindi tutte le altre chiavi vengono comunque offerte prima della tua e la connessione continua a interrompersi quando raggiunge il limite. Esegui ssh -v -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10 senza IdentitiesOnly per vedere che le chiavi dell’agent vengono offerte per prime. -i deve essere accompagnato da -o IdentitiesOnly=yes.
Per escludere completamente l’agent da una connessione:
ssh -o IdentityAgent=none -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10ssh legge quindi la chiave privata dal disco e ne richiede la passphrase, se impostata.
Gli strumenti basati su ssh accettano la stessa opzione:
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.gitPerché l'errore compare al secondo hop
Con ForwardAgent yes, il socket dell'agent viene reso disponibile sul server a cui ci si connette. Un comando ssh eseguito su quel server utilizza il proprio agent locale, con tutte le chiavi disponibili, tramite il socket inoltrato. Per questo motivo l'errore può comparire nell'hop dal jump host al server finale, anche se il primo hop ha funzionato correttamente. Esegui echo $SSH_AUTH_SOCK sulla macchina intermedia: un percorso del socket indica che un agent inoltrato è raggiungibile, mentre un output vuoto indica che non è disponibile.
L'agent forwarding comporta anche un secondo rischio. Chiunque disponga dell'accesso root sulla macchina intermedia può usare il tuo agent per autenticarsi come te finché la sessione resta aperta. ProxyJump evita entrambi i problemi:
ssh -J deploy@jump.example.com deploy@10.0.0.5ProxyJump apre una connessione attraverso il jump host e autentica la connessione al server finale dalla tua macchina, quindi il tuo ~/.ssh/config locale si applica a ogni hop, incluso IdentitiesOnly. Disabilitare ForwardAgent è una procedura standard per mettere in sicurezza SSH su un VPS.
Aumentare MaxAuthTries sul server?
Di norma, no. Controllare prima il valore corrente:
sudo sshd -T | grep -i maxauthtriessshd -T stampa la configurazione effettiva, inclusi i valori predefiniti, quindi restituisce il valore reale anche quando sshd_config non contiene alcuna impostazione al riguardo. Aggiungere -C user=deploy,host=example.com,addr=203.0.113.10 se si usano blocchi Match, perché vengono valutati per ogni connessione e altrimenti vengono ignorati.
Aumentare il limite funziona, in senso strettamente tecnico, perché un numero maggiore lascia più margine a un client che si comporta in modo errato:
MaxAuthTries 20Convalidare il file e ricaricare il servizio. Durante l'operazione, mantenere aperta una seconda sessione:
sudo sshd -t
sudo systemctl reload ssh # Debian and Ubuntu
sudo systemctl reload sshd # RHEL familySe systemctl is-enabled ssh.socket restituisce enabled su Ubuntu 24.04, sshd viene attivato tramite socket: per ogni connessione viene avviato un nuovo processo, che legge nuovamente sshd_config. Le nuove connessioni applicano quindi automaticamente la modifica.
Ora verificare l'effetto della modifica. Il client propone chiavi che il server non accetterà mai. Aumentare il limite indica al server di elaborare venti chiavi rifiutate per connessione invece di sei, per ogni client che si connette e per ogni tentativo di autenticazione tramite password proveniente da Internet. Ogni proposta richiede al server una ricerca in authorized_keys. Il proprio accesso resta lento, perché la chiave corretta continua a essere l'ultima nella sequenza. Aggiungere una tredicesima chiave al proprio agent riporta alla situazione iniziale e rende necessario aumentare nuovamente il valore.
Aumentare il limite solo quando un client legittimo deve realmente presentare diverse identità. In tutti gli altri casi, correggere la configurazione del client. Ridurre il limite è una misura di hardening ragionevole quando ogni utente accede con una chiave configurata, perché un numero più basso offre a chi tenta di indovinare la password meno tentativi per connessione.
Perché fail2ban può bloccare il tuo indirizzo
Con il livello di logging predefinito, sshd registra ogni chiave pubblica rifiutata:
Failed publickey for deploy from 203.0.113.10 port 51292 ssh2: ED25519 SHA256:AAAA...Una connessione da un agent completamente carico produce diverse righe di questo tipo dallo stesso indirizzo nell'arco di uno o due secondi. La jail sshd di fail2ban conta le righe di errore di sshd e blocca l'indirizzo sorgente quando viene raggiunto maxretry all'interno di findtime. Per impostazione predefinita, queste finestre temporali sono brevi, quindi due tentativi di una connessione non funzionante possono bastare per bloccare il proprio indirizzo.
A questo punto il sintomo cambia, ed è questo l'aspetto che crea confusione. Non viene più visualizzato il messaggio "Too many authentication failures". Non viene visualizzato più nulla: la connessione resta in attesa e infine va in timeout, perché il firewall ora scarta i pacchetti invece di rispondere. Un timeout al posto del precedente messaggio di errore è il segnale da osservare. La differenza è descritta in Connessione SSH rifiutata o connessione SSH in timeout.
Dalla console del provider, oppure da un altro indirizzo, controlla la jail e rimuovi il blocco:
sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10Inserisci il tuo indirizzo in ignoreip in jail.local mentre risolvi il problema del client, quindi rimuovilo al termine. La jail viene configurata nella guida a fail2ban per Ubuntu 24.04.
Cosa fare una volta sola per evitare che il problema si ripresenti
Assegna a ogni server un proprio blocco Host in ~/.ssh/config, con HostName, User, IdentityFile e IdentitiesOnly yes. In questo modo, ssh vps è breve da digitare, offre esattamente una chiave e non può attivare MaxAuthTries, anche quando il tuo agent contiene molte chiavi. Inoltre mantiene breve l'output di ssh -v, così resta leggibile quando si verifica un altro problema.
FAQ
Come posso risolvere subito il messaggio "Too many authentication failures"?
Usa una sola chiave invece di tutte. Per una connessione immediata, esegui ssh -o IdentitiesOnly=yes -i ~/.ssh/your_key user@host. Per una correzione permanente, aggiungi un blocco a ~/.ssh/config con HostName, User, IdentityFile che punti a quella chiave, quindi IdentitiesOnly yes e poi chmod 600 ~/.ssh/config. Verifica con ssh -v: per quell'host dovrebbe comparire una sola riga Offering public key:.
Perché ssh -i continua a proporre le altre chiavi?
Perché -i aggiunge un'identità all'elenco, ma non limita l'elenco. Le chiavi caricate in ssh-agent restano nell'elenco e continuano a essere proposte, spesso prima della tua. Il server può quindi raggiungere MaxAuthTries prima che venga proposta la tua chiave. -o IdentitiesOnly=yes è l'opzione che limita ssh alle identità specificate. Usa insieme -i e -o IdentitiesOnly=yes oppure -o IdentityAgent=none per ignorare completamente l'agent per quella connessione.
Devo aumentare MaxAuthTries sul server per risolvere il problema?
No, nella quasi totalità dei casi. Il client invia chiavi che il server non accetterà mai. Un limite più alto fa soltanto valutare al server più tentativi rifiutati per connessione, per ogni client e per ogni tentativo di brute force che lo raggiunge. Il problema si ripresenta inoltre non appena un'altra chiave viene caricata nell'agent. Se vuoi controllare il valore effettivo, usa sudo sshd -T | grep -i maxauthtries, quindi correggi il client con IdentitiesOnly.
Perché il problema è comparso su un server che il mese scorso funzionava correttamente?
Il tuo agent contiene più chiavi. AddKeysToAgent yes in ~/.ssh/config mantiene caricata ogni chiave utilizzata, mentre gli agent del keyring del desktop caricano autonomamente le chiavi al login. Quando il numero di chiavi caricate supera MaxAuthTries sul server, qualsiasi server la cui chiave si trova più avanti nell'ordine delle proposte inizia a rifiutare la connessione. Esegui ssh-add -l e confronta il numero ottenuto con il limite configurato sul server.
Questo problema può far bloccare il mio indirizzo IP da fail2ban?
Sì. Ogni chiave rifiutata produce una riga Failed publickey for ... nel log del server. Una sola connessione può quindi generare diversi errori dal tuo indirizzo in pochi secondi. Il jail sshd di fail2ban blocca l'indirizzo quando entro findtime viene raggiunta la soglia maxretry. Il segnale più evidente è che l'errore si trasforma prima in un'attesa prolungata e poi in un timeout, perché i pacchetti vengono scartati invece di ricevere una risposta. Rimuovi il blocco dalla console con sudo fail2ban-client set sshd unbanip <your address> e correggi il client prima di riconnetterti.