2

I have a lot of ssh keys, they are all passphrase protected and managed by ssh-agent. As a result of this, I am now getting "Too many authentication failures" on some connections.

As has been explained on this site before, this is because ssh will try all keys the agent throws at it.

The proposed solution is to use IdentitiesOnly in the config, together with an IdentityFile. While this indeed stops offering wrong keys, it seems it completely disables the agent in full, so now I have to type the passphrase on every connection.

I could not find clear info about this. Does IdentitiesOnly just disable getting keys from ssh-agent in full? Or should it just block out the keys that aren't mentioned?

Thanks, Mathijs

# here's my config
~% cat .ssh/config
Host bluemote
  HostName some.host.com
  IdentitiesOnly yes
  IdentityFile /home/mathijs/.ssh/keys/bluebook_ecdsa

# I had the key loaded into the agent, shown here
~% ssh-add -L
ecdsa-sha2-nistp521 SOME_LONG_BASE64_NUMBER== /home/mathijs/.ssh/keys/bluebook_ecdsa

# but it doesn't seem to get used
~% ssh bluemote
Enter passphrase for key '/home/mathijs/.ssh/keys/bluebook_ecdsa':
1
  • I have a server which is key authentication only, I have added the 'IdentitiesOnly yes' with IdentityFile and it connects normally if I ssh -vvv I can see it only offers my specified key, I then connect to another host not in .ssh/config I can connect fine, what do you mean by 'disables the agent in full'?
    – Joel Davey
    May 1, 2018 at 10:43

2 Answers 2

1

Does IdentitiesOnly just disable getting keys from ssh-agent in full? Or should it just block out the keys that aren't mentioned?

&

it seems it completely disables the agent in full

This is intended behaviour as described in the manpage ssh_config(5):

 IdentitiesOnly
         Specifies that ssh(1) should only use the authentication identity
         files configured in the ssh_config files, even if ssh-agent(1)
         offers more identities.  The argument to this keyword must be
         “yes” or “no”.  This option is intended for situations where ssh-
         agent offers many different identities.  The default is “no”.

 IdentityFile
         Specifies a file from which the user's DSA, ECDSA or DSA authen‐
         tication identity is read.  The default is ~/.ssh/identity for
         protocol version 1, and ~/.ssh/id_dsa, ~/.ssh/id_ecdsa and
         ~/.ssh/id_rsa for protocol version 2.  Additionally, any identi‐
         ties represented by the authentication agent will be used for
         authentication.  ssh(1) will try to load certificate information
         from the filename obtained by appending -cert.pub to the path of
         a specified IdentityFile.

There's one workround: ssh-add. While a regular SSH key agent seems to be disabled using IdentitiesOnly, the ones I add using ssh-add are used anyway.

5
  • Thanks for you reply. In my case, I did add the keys through ssh-add, so this does not seem to work for me. Dec 7, 2012 at 11:28
  • I must say I think this intended behaviour is strange. This basically makes an agent unusable when you have 6+ keys. Reverting to passphrase-less keys does not sound like a good option. Dec 7, 2012 at 11:30
  • @MathijsKwik Did you ever find a solution to this?
    – crdx
    Apr 13, 2014 at 17:16
  • Please can you clarify what "disabled" means?
    – Joel Davey
    May 1, 2018 at 11:34
  • @JoelDavey Disregard the keys offered by the agent; don't query it - only consider keys accessible as a file directly.
    – gertvdijk
    Jul 26, 2018 at 21:38
0

I have a lot of keys too and just figured out a way to do this this evening:

#!/bin/bash
remove_public () { # remove the public key after 2 seconds
  sleep 2
  rm -f $HOME/.ssh/public_key $HOME/.ssh/config
}

get_public () { # get the public key from ssh-add
  ssh-add -L | grep "$1" > $HOME/.ssh/public_key
  if [ ! -s "$HOME/.ssh/public_key" ] #identity hasn't yet been loaded
  then
    export KEY="$1" #use the private key it'll be added to the agent for next time assuming agent is configured.
  else
    export KEY="$HOME/.ssh/public_key" #use the public key
    ( remove_public & ) >/dev/null 2>&1
  fi
  chmod 700 "$KEY"
  echo "IdentitiesOnly=yes" > "$HOME/.ssh/config"
  echo "IdentityFile $KEY" >> "$HOME/.ssh/config"
}

ssh_connect () {
  chmod -R 700 $HOME/.ssh
  if [[ -z "$1" || -z "$2" ]]
  then
    echo "Username or server not specified!"
    exit 1;
  else
    get_public "$HOME/.ssh/$2"
    ssh "$2@$1" -i "$HOME/.ssh/$2"
  fi
}

Connect using:

ssh_connect "server" "user"

This assumes that your private key is $HOME/.ssh/{username} but it could be adapted of course.

It exports the public key from the agent and uses that. If it hasn't been added to the agent yet, it uses the private key instead.

Note that it'll delete your ssh config so it should be modified to rewrite your config instead of removing it if you have anything in there you need to keep.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .