Take the 2-minute tour ×
Super User is a question and answer site for computer enthusiasts and power users. It's 100% free, no registration required.

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':
share|improve this question

2 Answers 2

up vote 0 down vote accepted

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.

share|improve this answer
    
Thanks for you reply. In my case, I did add the keys through ssh-add, so this does not seem to work for me. –  Mathijs Kwik Dec 7 '12 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. –  Mathijs Kwik Dec 7 '12 at 11:30
    
@MathijsKwik Did you ever find a solution to this? –  crdx Apr 13 at 17:16

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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.