SSD Nodes Learn Hosting plans →
Guias Matt ConnorPor Matt Connor

SSH: corrija o erro Too many authentication failures

O erro Too many authentication failures ocorre quando o SSH oferece chaves demais. Use ssh -v para diagnosticar e force a chave correta com IdentitesOnly.

O que significa "Too many authentication failures"

"Too many authentication failures" significa que o cliente SSH ofereceu ao servidor mais chaves do que este estava disposto a verificar, e o servidor encerrou a ligação antes de a chave correta ser sequer testada. Isto é quase sempre um problema no cliente. A chave está no seu disco, o servidor tem-na em authorized_keys, e nenhum desses factos ajuda, porque a ligação terminou demasiado cedo.

A sequência é esta. ssh-agent contém todas as chaves privadas que carregou. O cliente oferece essas chaves ao servidor uma de cada vez, porque não tem como saber qual delas é aceite pela conta. O servidor rejeita cada chave que não está em authorized_keys e conta cada rejeição como uma tentativa de autenticação falhada. MaxAuthTries em sshd_config limita o número de falhas permitido numa ligação. O valor predefinido é 6. Se o seu agente tiver dez chaves e a correta for a oitava da sequência, o servidor encerra a ligação antes de chegar a essa chave.

Por isso, a solução é fazer com que o cliente ofereça uma única chave: a correta.

O que o servidor contabiliza e onde entra o MaxAuthTries

A autenticação por chave pública começa como um processo de tentativa. O cliente envia uma chave pública e pergunta se o servidor aceitaria uma assinatura feita com ela. O servidor responde sim ou não. Um "não" é uma tentativa falhada, exatamente como uma palavra-passe incorreta.

A página de manual sshd_config(5) descreve o limite: "Especifica o número máximo de tentativas de autenticação permitidas por ligação. Quando o número de falhas atinge metade deste valor, as falhas adicionais são registadas. O valor predefinido é 6."

Seis tentativas são suficientes para uma pessoa introduzir uma palavra-passe. Não são muitas para um agente que tenha dez chaves. Quando o contador de falhas atinge o limite, o sshd termina a ligação e escreve uma linha semelhante a esta no log do sistema:

error: maximum authentication attempts exceeded for deploy from 203.0.113.10 port 51292 ssh2

O cliente apresenta a outra metade do mesmo evento:

Received disconnect from 203.0.113.10 port 22:2: Too many authentication failures
Disconnected from 203.0.113.10 port 22

Esta é uma falha diferente do erro SSH de permissão negada (publickey). Nesse caso, o servidor analisou tudo o que foi oferecido e não aceitou nada. Aqui, o servidor deixou de analisar as opções. Confundir uma situação com a outra leva a passar uma tarde a copiar novamente uma chave que já estava correta.

Por que a mesma chave funciona no portátil do seu colega

Não há nenhuma diferença na chave nem no servidor. O agente dele tem duas chaves, e o seu tem doze. A chave que chega primeiro para ele chega em nono lugar para você. Nesse momento, a ligação já terminou.

A quantidade aumenta sem chamar atenção. AddKeysToAgent yes em ~/.ssh/config adiciona cada chave que você usa ao agente e mantém-na lá. Agentes de chaveiro do ambiente de trabalho, como o GNOME Keyring no Linux ou o chaveiro de início de sessão no macOS, carregam chaves durante o início de sessão sem pedir confirmação. Adicione uma chave de cliente, uma chave de um servidor Git e uma chave de um servidor de laboratório ao longo de um ano. Um dia, um servidor que sempre funcionou começa a recusá-lo. Nada mudou no servidor. O seu agente ficou mais cheio.

Como ver as ofertas com ssh -v

Execute a ligação que falha com -v e leia o rastreio.

ssh -v deploy@203.0.113.10

Há dois tipos de linha importantes. Will attempt key: lista as identidades que o cliente reuniu, pela ordem em que as utilizará. Offering public key: aparece uma vez para cada chave efetivamente enviada ao 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... agent

Os seus caminhos, tipos de chave e impressões digitais serão diferentes. O que deve contar é o número de linhas Offering public key: antes da desligação. Se as ofertas continuarem a ser apresentadas e a sessão terminar sem que a chave pretendida apareça, o diagnóstico está confirmado. A palavra agent no fim de uma linha significa que essa identidade veio de ssh-agent. A palavra explicit significa que veio de uma linha IdentityFile ou de -i na linha de comandos.

Depois, consulte o que o agente tem carregado:

ssh-add -l

Cada linha da saída corresponde a uma chave carregada. Se for apresentada The agent has no identities., o agente não é o problema. Nesse caso, consulte as linhas IdentityFile em ~/.ssh/config. Se for apresentada Could not open a connection to your authentication agent., não há nenhum agente em execução e as ofertas vêm dos ficheiros de chave predefinidos.

Correção 1: IdentitiesOnly com uma chave por host

IdentitiesOnly yes faz o ssh oferecer apenas as identidades que configurou e ignorar as restantes que o agente disponibiliza. Combine-o com uma linha IdentityFile para que o cliente envie uma única oferta.

Host vps
  HostName 203.0.113.10
  User deploy
  IdentityFile ~/.ssh/id_ed25519_vps
  IdentitiesOnly yes

Guarde isso em ~/.ssh/config e execute chmod 600 ~/.ssh/config. Um ficheiro com permissões de escrita para o grupo ou para outros utilizadores faz o ssh recusar a execução, com Bad owner or permissions on /home/you/.ssh/config. Agora ssh vps oferece uma chave, e ssh -v vps deve mostrar exatamente uma linha Offering public key:.

Há dois detalhes que surpreendem muitos utilizadores.

  • IdentitiesOnly yes, por si só, não significa "uma chave". Sem uma linha IdentityFile, os ficheiros de identidade predefinidos contam como identidades configuradas, por isso o ssh continua a tentar ~/.ssh/id_ed25519, ~/.ssh/id_rsa e os restantes ficheiros predefinidos que encontrar. Também precisa da linha IdentityFile: quando esta é definida, o ssh deixa de adicionar os ficheiros predefinidos.
  • O agente continua a fazer a assinatura. IdentitiesOnly controla quais chaves são oferecidas, não quem faz a assinatura. Se a chave privada indicada por IdentityFile estiver carregada no agente, o agente produz a assinatura e nunca lhe é pedida uma frase-passe. Também pode apontar IdentityFile para o ficheiro .pub correspondente. É isso que deve fazer quando a chave privada existe apenas no agente ou num token de hardware.

Uma armadilha em ~/.ssh/config desfaz esta correção silenciosamente. A maioria das palavras-chave usa o primeiro valor encontrado, razão pela qual os blocos Host específicos devem ficar acima de Host *. IdentityFile não segue essa regra. O manual diz: "É possível especificar vários ficheiros de identidade nos ficheiros de configuração; todas estas identidades serão tentadas em sequência." Um IdentityFile em Host * é adicionado ao definido para o host, em vez de o substituir. Assim, uma linha global esquecida volta a adicionar uma oferta a todas as ligações.

Se quiser uma proteção global, defina apenas a flag no fim do ficheiro:

Host *
  IdentitiesOnly yes

Cada host passa então a precisar do seu próprio IdentityFile, que é precisamente o resultado pretendido. Indicar uma chave por servidor também permite revogar mais tarde o acesso de uma única máquina sem emitir tudo novamente. Vale a pena criar esse hábito desde cedo: consulte como gerir chaves SSH por máquina.

Correção 2: limpe ou reinicie o agente

Se ainda não puder editar a configuração, esvazie o agente e carregue apenas o que precisa.

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 need

Se a ligação funcionar logo depois de ssh-add -D, o agente era a causa. Considere isso um teste, não uma correção. Um agente de porta-chaves do ambiente de trabalho volta a carregar as chaves no próximo início de sessão, por isso o problema regressa amanhã. Uma linha IdentitiesOnly em ~/.ssh/config persiste depois de um reboot. Um agente vazio não.

Também pode definir uma duração para uma chave, para que o agente a remova automaticamente:

ssh-add -t 1800 ~/.ssh/id_ed25519_vps

A chave é removida 1800 segundos depois de ser adicionada. Reiniciar o agente também funciona, mas o procedimento depende do que o iniciou. Um ssh-agent que iniciou manualmente é parado com ssh-agent -k. Se o executar a partir de uma unidade de utilizador do systemd que criou, reinicie essa unidade com systemctl --user restart <unit>. Um agente de porta-chaves reinicia com a sessão do ambiente de trabalho.

Correção 3: o comando único para um servidor que utiliza uma vez

Para um host que não vai adicionar à sua configuração, coloque as mesmas definições na linha de comandos:

ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10

-i, usado isoladamente, é a correção errada mais comum. -i adiciona uma chave à lista de identidades. Não remove as chaves do agent dessa lista. Por isso, todas as outras ofertas continuam a ser enviadas antes da sua e a ligação continua a falhar ao atingir o limite. Execute ssh -v -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10 sem IdentitiesOnly e verá as chaves do agent a serem oferecidas primeiro. -i precisa de -o IdentitiesOnly=yes junto dele.

Para excluir completamente o agent de uma ligação:

ssh -o IdentityAgent=none -i ~/.ssh/id_ed25519_vps deploy@203.0.113.10

O ssh lê então a chave privada do disco e pede a respetiva passphrase, se existir.

As ferramentas baseadas em ssh aceitam a mesma opção:

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.git

Por que o erro aparece no segundo salto

Com ForwardAgent yes, o socket do agente fica disponível no servidor ao qual se liga. Um comando ssh executado nesse servidor usa o seu agente local, com todas as suas chaves, através do socket encaminhado. Por isso, o erro pode aparecer no salto de um jump host para o servidor final, mesmo que o primeiro salto tenha funcionado corretamente. Execute echo $SSH_AUTH_SOCK na máquina intermédia: uma saída vazia significa que não há nenhum agente acessível. Um caminho de socket significa que existe algum agente, mas não necessariamente o seu, porque um agente iniciado nessa máquina define a mesma variável. Execute também ssh-add -l nessa máquina: se listar as chaves da sua própria máquina, o encaminhamento está ativo.

O encaminhamento do agente tem um segundo custo. Qualquer pessoa com root nessa máquina intermédia pode usar o seu agente para se autenticar como você enquanto a sua sessão estiver aberta. ProxyJump evita ambos os problemas:

ssh -J deploy@jump.example.com deploy@10.0.0.5

ProxyJump abre uma ligação através do jump host e autentica-se no servidor final a partir da sua própria máquina. Assim, o seu ~/.ssh/config local aplica-se a todos os saltos, incluindo IdentitiesOnly. Desativar ForwardAgent é um procedimento padrão ao reforçar a segurança do SSH num VPS.

Deve aumentar MaxAuthTries no servidor?

Normalmente, não. Verifique primeiro o valor atual:

sudo sshd -T | grep -i maxauthtries

sshd -T mostra a configuração efetiva, incluindo os valores predefinidos. Assim, apresenta o valor real mesmo quando sshd_config não o define. Adicione -C user=deploy,host=example.com,addr=203.0.113.10 se usar blocos Match, porque estes são avaliados por ligação e, sem essa opção, são ignorados.

Aumentar o limite funciona, no sentido restrito de dar mais margem a um cliente com comportamento incorreto:

MaxAuthTries 20

Valide o ficheiro e recarregue o serviço. Mantenha uma segunda sessão aberta enquanto faz isso:

sudo sshd -t
sudo systemctl reload ssh      # Debian and Ubuntu
sudo systemctl reload sshd     # RHEL family

Se systemctl is-enabled ssh.socket apresentar enabled no Ubuntu 24.04, o sshd é ativado por socket. O ssh.socket do Ubuntu não inicia um daemon novo para cada ligação. Inicia ssh.service quando chega a primeira ligação, e esse serviço continua em execução para tratar as ligações seguintes. O recarregamento acima continua a ser o procedimento que aplica a alteração. Se ssh.service ainda não estiver ativo, não há nada para recarregar. A ligação seguinte inicia-o com o novo ficheiro.

Agora veja o efeito dessa alteração. O cliente está a oferecer chaves que este servidor nunca aceitará. Aumentar o limite faz o servidor processar vinte ofertas rejeitadas por ligação em vez de seis, para cada cliente que se liga e para cada processo de tentativa de palavras-passe na Internet. Cada oferta obriga o servidor a consultar authorized_keys. O seu início de sessão continua lento, porque a chave correta permanece no fim da fila. Adicione uma décima terceira chave ao seu agente e voltará ao ponto de partida, precisando novamente de pedir um número maior.

Aumente o limite apenas quando um cliente legítimo precisar realmente de apresentar várias identidades. Em todos os outros casos, corrija o cliente. Reduzir o limite é uma medida de reforço razoável depois de todos os utilizadores iniciarem sessão com uma chave configurada, porque um número menor dá menos tentativas por ligação a quem tentar adivinhar credenciais.

Por que o fail2ban pode bloquear o seu endereço neste caso

O sshd não regista todas as chaves rejeitadas. Com o valor predefinido de LogLevel INFO, uma chave rejeitada de uma conta existente só é escrita no log quando o número de falhas da ligação atinge metade de MaxAuthTries. É isso que o manual quer dizer com "Once the number of failures reaches half this value, additional failures are logged." Com o valor predefinido de 6, as três primeiras ofertas rejeitadas não são escritas no log. As três últimas aparecem em linhas como esta, seguidas da linha maximum authentication attempts exceeded:

Failed publickey for deploy from 203.0.113.10 port 51292 ssh2: ED25519 SHA256:AAAA...

Estas linhas parecem representar várias falhas, mas o filtro sshd do fail2ban não as contabiliza. O valor predefinido fornecido, publickey = nofail, lê uma linha Failed publickey de um utilizador válido apenas para obter o endereço e o nome de utilizador. A linha contabilizada é maximum authentication attempts exceeded. Portanto, uma ligação que atinja o limite acrescenta uma falha, não várias. O jail bloqueia o endereço de origem quando maxretry falhas ocorrem dentro de findtime. O próprio jail.conf do fail2ban define estes valores para 5 e 10 minutos. Cerca de cinco ligações falhadas em dez minutos são suficientes para bloquear o seu próprio endereço. Um script ou uma ferramenta que repita a tentativa num ciclo atinge esse limite rapidamente.

O sintoma muda. É esta parte que costuma causar confusão. Deixa de ver "Too many authentication failures" e passa a não ver nada: a ligação fica bloqueada e acaba por atingir o tempo limite, porque a firewall agora descarta os seus pacotes em vez de responder. Um timeout onde antes recebia uma mensagem de erro é o sinal. Esta distinção é explicada em ligação SSH recusada versus ligação SSH que excedeu o tempo limite.

Na consola do seu fornecedor, ou a partir de um endereço diferente, verifique o jail e remova o bloqueio:

sudo fail2ban-client status sshd
sudo fail2ban-client set sshd unbanip 203.0.113.10

Coloque o seu próprio endereço em ignoreip dentro de jail.local enquanto corrige o cliente. Remova-o novamente quando terminar. A configuração do jail está descrita em o guia do fail2ban para Ubuntu 24.04.

O que fazer uma vez para isto deixar de voltar

Dê a cada servidor o seu próprio bloco Host em ~/.ssh/config, com HostName, User, IdentityFile e IdentitiesOnly yes. Depois disso, ssh vps é curto de escrever, oferece exatamente uma chave e não pode acionar MaxAuthTries, por mais cheia que a sua agent fique. Também mantém a saída de ssh -v curta o suficiente para ser lida no dia em que algo diferente avariar.

FAQ

Como corrijo agora o erro "Too many authentication failures"?

Ofereça uma única chave em vez de todas. Para uma ligação imediata, execute ssh -o IdentitiesOnly=yes -i ~/.ssh/your_key user@host. Para uma correção permanente, adicione um bloco a ~/.ssh/config com HostName, User e IdentityFile a apontar para essa chave, e IdentitiesOnly yes; depois execute chmod 600 ~/.ssh/config. Confirme com ssh -v: deverá ver uma única linha Offering public key: para esse host.

Porque é que ssh -i continua a oferecer as minhas outras chaves?

Porque -i adiciona uma identidade à lista, mas não limita a lista. As chaves carregadas em ssh-agent continuam na lista e continuam a ser oferecidas, muitas vezes antes da sua. Por isso, o servidor ainda pode atingir MaxAuthTries antes de chegar à sua chave. -o IdentitiesOnly=yes é a opção que limita o ssh às identidades indicadas. Use -i e -o IdentitiesOnly=yes em conjunto, ou -o IdentityAgent=none para ignorar completamente o agent nessa ligação.

Devo aumentar MaxAuthTries no servidor para corrigir isto?

Não, em quase todos os casos. O cliente está a enviar chaves que este servidor nunca aceitará. Um limite maior apenas faz o servidor avaliar mais ofertas rejeitadas por ligação, para todos os clientes e todas as tentativas de brute force que o alcancem. O problema também regressa assim que outra chave é adicionada ao seu agent. Consulte o valor efetivo com sudo sshd -T | grep -i maxauthtries, se quiser, e corrija o cliente com IdentitiesOnly.

Porque é que isto começou num servidor que funcionava bem no mês passado?

O seu agent ficou maior. AddKeysToAgent yes em ~/.ssh/config mantém carregada cada chave que utiliza, e os agents do keyring do desktop carregam chaves automaticamente no login. Quando o número de chaves carregadas ultrapassa o MaxAuthTries do servidor, qualquer servidor cuja chave fique mais tarde na ordem de oferta começa a falhar. Execute ssh-add -l e compare a contagem com o limite configurado no servidor.

Isto pode fazer com que o fail2ban bloqueie o meu endereço IP?

Sim, embora mais lentamente do que o log do servidor sugere. O filtro sshd predefinido do fail2ban não conta linhas Failed publickey para um utilizador válido. Conta a linha maximum authentication attempts exceeded, pelo que cada ligação que atinge o limite corresponde a uma falha. Com os valores predefinidos fornecidos, maxretry = 5 e findtime = 10m, cerca de cinco dessas ligações em dez minutos bloqueiam o seu endereço. O sinal revelador é a transformação do erro numa espera e depois num timeout, porque os pacotes estão a ser descartados em vez de receberem resposta. Limpe o bloqueio a partir da consola com sudo fail2ban-client set sshd unbanip <your address> e corrija o cliente antes de voltar a ligar-se.

#ssh#ssh-agent#openssh#ssh-config#troubleshooting