I sometimes see this issue when trying to ssh to a host. Most often when going through git (since I ssh with git more often than I ssh directly).
The output from ssh looks like this:
Received disconnect from <server ip> port 22:2: Too many authentication failures
Disconnected from <server ip> port 22
I've also gone through an SSH proxy, and in that case the output looks like this:
Received disconnect from UNKNOWN port 65535:2: Too many authentication failures
Disconnected from UNKNOWN port 65535
Killed by signal 1.
From the face of the error message, it looks like my account has been locked out - i.e. typically what happens if you enter your password incorrectly too many times. But I only authenticate using ssh keys, and this had worked a few days prior.
Looking at the verbose output (using ssh -v), I don't see much more that helps, but it does tell me that it has tried to use all IdentityFile
s configured for this host pattern in my .ssh/config
file as well as all identities available in my ssh-agent.
I have recently added new keys to the agent due to our quarterly key rotation.
Check the verbose output using ssh -v
and see which keys and how many keys are being used.
For example, the output might contain the following:
debug1: get_agent_identities: bound agent to hostkey
debug1: get_agent_identities: agent returned 7 keys
debug1: Will attempt key: .ssh/Key-2022-Q3 ED25519 SHA256:xxxxxxxx explicit agent
debug1: Will attempt key: .ssh/Key-2022-03-14 RSA SHA256:xxxxxxxx explicit agent
debug1: Will attempt key: .ssh/Key-2023-02-13 RSA SHA256:xxxxxxxx explicit agent
debug1: Will attempt key: Key-2023-01-20 ED25519 SHA256:xxxxxxxx agent
debug1: Will attempt key: Key-2022-04-12 ED25519 SHA256:xxxxxxxx agent
debug1: Will attempt key: Key-2022-12-14 ED25519 SHA256:xxxxxxxx agent
debug1: Will attempt key: Key-2023-03-20 ED25519 SHA256:xxxxxxxx agent
In the above example, we see that ssh will attempt to use 7 keys to authenticate with the remote server. The first 3 are specified explicitly via either an entry in your .ssh/config
file that matches the Host pattern, or via the -i
command line parameter.
In my case, my .ssh/config
file contains this:
<global section>
IdentityFile .ssh/Key-2022-03-14
...
Host *.<domain match>
IdentityFile .ssh/Key-2022-Q3
...
Host <exact match>
IdentityFile .ssh/Key-2023-02-13
Basically, 3 identity files that match the conditions for this host:
ssh will attempt all three of these keys.
All these keys are also loaded into my running ssh-agent
along with 4 additional keys.
Run ssh-add -L
to get a list of keys that the agent will supply. In my case it includes all 7 of the keys listed above.
The problem here is that each incorrect key that is offered and fails, counts as a failed login attempt. In this case, there will be multiple failed login attempts before we get to the correct key, and this results in the "Too many authentication failures" error.
To solve this, we update the .ssh/config
file and tell ssh to explicitly only use this key. We need to add the following two lines to the exact host match section:
IdentitiesOnly yes
IdentityAgent none
The first tells ssh to only use the Identity file specified in the config file, and the second says to disable the agent when using this host:
IdentitiesOnly
Specifies that ssh(1) should only use the configured authentication identity and certificate files (either the default files, or those explicitly configured in the ssh_config files or passed on the ssh(1) command-line), even if ssh-agent(1) or a PKCS11Provider or
SecurityKeyProvider offers more identities. The argument to this keyword must be yes or no (the default). This option is intended for situations where ssh-agent offers many different identities.
IdentityAgent
Specifies the UNIX-domain socket used to communicate with the authentication agent.
This option overrides the SSH_AUTH_SOCK environment variable and can be used to select a specific agent. Setting the socket name to none disables the use of an authentication agent. If the string "SSH_AUTH_SOCK" is specified, the location of the socket will be read
from the SSH_AUTH_SOCK environment variable. Otherwise if the specified value begins with a ‘$’ character, then it will be treated as an environment variable containing the location of the socket.
If we attempt the ssh
after making these changes, we see that the list of keys offered is reduced to just one:
debug1: Will attempt key: .ssh/Key-2023-02-13 RSA SHA256:xxxxxxxx explicit
It also no longer lists agent
as the source of this key.
Authentication now succeeds on the first key, and access is granted.