Super User is a question and answer site for computer enthusiasts and power users. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I've learned at myriad sources online that (roughly), in order to login to a remote server without a password: generate an ssh key, put the pub version in authorized_keys on the remote system; put the private version in your local ~/.ssh/ directory; chmod it to 0600 and poof, you're in. While that is mostly correct, I find that the key (pair) has to be named id_rsa (id_rsa.pub) or id_dsa (id_dsa.pub) for SSH to offer it to remote servers.

Let me back up a bit. I have a login, SurnameG on my local Mac. I have a SurnameG account on a remote system, otherserver.

I copied the contents of ~/.ssh/surnameg.pub to that system's /home/surnameg/.ssh/authorized_keys. I've tested with the -i option from my Mac to ssh in and it works fine.

I have an ~/.ssh/id_rsa (which I generated for use with github.com).

And of course, I have ~/.ssh/surnameg and even some other keys there, which are not being "tried" when I try to login the following way to otherserver.com :

ssh 1.2.3.4

Here, I am trying to use SurnameG (the current local logged in user) to login to my SurnameG account on otherserver. I am wanting openssh to offer ~/.ssh/surnameg in its attempt to connect, but it does not - let's take a closer look with the verbose option:

BOX:~ SurnameG$ ssh -v 1.2.3.4
OpenSSH_5.9p1, OpenSSL 0.9.8y 5 Feb 2013
debug1: Reading configuration data /Users/SurnameG/.ssh/config
debug1: Reading configuration data /etc/ssh_config
debug1: /etc/ssh_config line 20: Applying options for *
debug1: Connecting to 1.2.3.4 [50.112.132.124] port 22.
debug1: Connection established.
debug1: identity file /Users/SurnameG/.ssh/id_rsa type 1
debug1: identity file /Users/SurnameG/.ssh/id_rsa-cert type -1
debug1: identity file /Users/SurnameG/.ssh/id_dsa type -1
debug1: identity file /Users/SurnameG/.ssh/id_dsa-cert type -1
debug1: Remote protocol version 2.0, remote software version OpenSSH_5.3
debug1: match: OpenSSH_5.3 pat OpenSSH*
debug1: Enabling compatibility mode for protocol 2.0
debug1: Local version string SSH-2.0-OpenSSH_5.9
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
debug1: kex: server->client aes128-ctr hmac-md5 none
debug1: kex: client->server aes128-ctr hmac-md5 none
debug1: SSH2_MSG_KEX_DH_GEX_REQUEST(1024<1024<8192) sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_GROUP
debug1: SSH2_MSG_KEX_DH_GEX_INIT sent
debug1: expecting SSH2_MSG_KEX_DH_GEX_REPLY
debug1: Server host key: RSA ax:64:3e:4a:e3:2c:e4:30:dd:36:a4:a0:9x:fa:ba:6b
debug1: Host '1.2.3.4' is known and matches the RSA host key.
debug1: Found key in /Users/SurnameG/.ssh/known_hosts:88
debug1: ssh_rsa_verify: signature correct
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug1: Roaming not allowed by server
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic
debug1: Next authentication method: publickey
debug1: Offering RSA public key: /Users/SurnameG/.ssh/id_rsa
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic
debug1: Trying private key: /Users/SurnameG/.ssh/id_dsa
debug1: No more authentication methods to try.

Curiously, openssh only offers ~/.ssh/id_rsa, but that's not all. It "tries" ~/.ssh/id_dsa also? I'm not sure on the difference between the two (offering versus trying) Anyway, if I am reading that correctly, openssh never tries any of my other private keys in ~/.ssh/*.

Okay, I know I can explicitly describe each server in ~/.ssh/config with something like

Host otherserver
   HostName 1.2.3.4
   User surnameg
   IdentityFile ~/.ssh/surnameg

and then login with

ssh otherserver

and that's fine and dandy and works great. But really, my ~/.ssh/config is getting unwieldy. Sadly I didn't cd ~/.ssh && git init a long time ago. But I digress.

My question is this: Is there a simpler, faster, more automated way to get ssh to try more keys in the ~/.ssh directory dynamically when attempting logins, or is editing your ~/.ssh/config for every server you need to connect to the only way to configure ssh? Have I misunderstood anything above about how SSH is supposed to work?

share|improve this question
1  
You are supposed to use helper programs like ssh-add and ssh-copy-id. Check those manpages. – micke Jul 9 '14 at 23:40
    
As far as I'm concerned you answered your question (well, not answered the part about whether or not you understood ssh), you're supposed to use your ~/.ssh/config for this. The things ssh tries by itself are the hardcoded names of id-files it will generate automatically when you a) chose a type and b) don't provide a name. – tink Jul 9 '14 at 23:57
up vote 1 down vote accepted

If you want to offer the same keys to all hosts, load them into a SSH agent using ssh-add. Many Linux distributions start one automatically – try ssh-add -l to check if it's running, then load your keys:

ssh-add ~/.ssh/id_rsa ~/.ssh/surnameg etc.

If the agent not started automatically, put the following in your ~/.profile:

agent_running() {
    [ "$SSH_AUTH_SOCK" ] && { ssh-add -l >/dev/null 2>&1 || [ $? -eq 1 ]; }
}

env=~/.ssh/agent.env
if ! agent_running && [ -s "$env" ]; then
    . "$env" >/dev/null
fi
if ! agent_running; then
    ssh-agent >"$env"
    . "$env" >/dev/null
    ssh-add ~/.ssh/id_*
fi    
unset env
share|improve this answer
    
Thanks @grawity - this is going to work out fine. When I ran ssh-add -l it says The agent has no identities. Does that mean it's running, but I am loading no additional keys (yet)? Also for future readers, you will need to rename private keys to id_* to match glob on line 11 in the script above. – phpguru Jul 10 '14 at 22:35
    
@phpguru: Yes, it's running but empty. And yes, the rename is intentional, as ~/.ssh/* would catch too many irrelevant files. – grawity Jul 11 '14 at 7:17

There is another possible approach. You can use placeholders in the IdentityFile option in ssh_config. As per man ssh_config:

  • %d—local user's home directory
  • %u—local user name
  • %l—local host name
  • %h—remote host name
  • %r—remote user name

I use it like this (in the global ssh_config file):

IdentityFile ~/.ssh/%r@%h

This means my private key files are named like daniel@example.com.

share|improve this answer
    
Thanks for the useful info, but it doesn't really answer my question. – phpguru Jul 10 '14 at 22:36

You must log in to answer this question.

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