Updated! (20 Nov 2001) Includes instructions for OpenSSH version 3.x. (This means that I removed references to authorized_keys2 as it is obsolete. If an earlier version of ssh is running on the server, you will have to substitute authorized_keys2 for authorized_keys below.)

Updated! (9 Nov 2001) Includes the SSH2 instructions and some corrections suggested by David Greaves.

I went searching for a good, general page that would explain how to do passwordless logins using ssh-agent and didn't find much. So I wrote this page.

Goals

Get a secure, encrypted connection to a remote machine without typing in a password.

Methods

Use OpenSSH to handle the authentication. If you are using putty, you might have trouble with this since the author says

Forms of SSH authentication other than password. I don't believe many of these can be made sensibly secure from a Windows box, even NT, and the ones that can tend to require the client to perform RSA private-key operations, which my current RSA code is too slow to do usefully. Plus they involve more typing than a password.

Note: Since the above was written, putty has included RSA key support.

(This misfeature has frustrated me before. And he is wrong about them requiring more typing.)

For Windows users, I recommend using the OpenSSH that is part of the CygWin toolset. I provide the minimum set of binaries that will provide the necessary functionality for the steps needed here. (Since the license on cygwin requires that source be distributed with the binaries, I'll point you to the website where you can find the source.) Note: If you are using this package, you may need to replace ~ with %HOME% throughout these directions.

Anyway, here is how to set up a pair of keys for passwordless authentication via ssh-agent.

  1. Generate the keys. Do this on the host that you want to connect from.
    $ ssh-keygen -t dsa -f ~/.ssh/id_dsa -C "you@example.com" Generating DSA keys: Key generation complete. Enter passphrase (empty for no passphrase): USE-A-PASSPHRASE Enter same passphrase again: USE-A-PASSPHRASE Your identification has been saved in ~/.ssh/id_dsa Your public key is: 1024 35 [really long string] you@example.com Your public key has been saved in ~/.ssh/id_dsa.pub $
  2. To use the key on other hosts you will be connecting from, copy the ~/.ssh/id_dsa key to the other hosts:
    	  $ scp ~/.ssh/id_dsa you@another-box:.ssh/
    	
    However, it is probably better just to generate new keys for those hosts.
  3. Make sure the public key is in the ~/.ssh/authorized_keys file on the hosts you wish to connect to. You can use a password authenticated connection to do this:
    	  $ cat ~/.ssh/id_dsa.pub | ssh you@other-host 'cat - >> ~/.ssh/authorized_keys'
    	  you@other-host's password: 
    	  $
    	

    Note: If an older version of ssh is running on the remote host, you may have to use the ~/.ssh/authorized_keys2 file.

    Note: If your local machine is Windows, try

    	  $ type ~/.ssh/id_dsa.pub | ssh you@other-host "cat - >> ~/.ssh/authorized_keys"
    	  you@other-host's password: 
    	  $
    	

  4. Verify that DSA authentication works:
          $ ssh you@example.com
          Enter passphrase for DSA key 'you@example.com': ^D
          $
          
    If you don't get the prompt for your DSA key, then something has gone wrong.

Now that that works, you will want the passwordless part, right?

  1. Start up ssh-agent. You can have it create a subprocess which inherits the SSH_AUTH_SOCK environment variable, or you can run it as a daemon.

    Since I run gdm on Debian Testing, ssh-agent is started automatically when I log in. If you don't have this benefit, you can get it by putting the following line at the end of my .xsession file:

          ssh-agent gnome-session
          

    Which basically means that ssh-agent starts up, creates a socket, sets up a couple of environment variables and then starts up gnome-session. That way all of the programs run in Gnome have access to the agent.

    If you want to, say, put it in your .profile, then you might try the following setup. In my .bash_profile, I have

    SSHAGENT=/usr/bin/ssh-agent if [ -z "$SSH_AUTH_SOCK" -a -x "$SSHAGENT" ]; then eval `$SSHAGENT` fi

    This brings SSH_AUTH_SOCK and SSH_AGENT_PID as environment variables into the current shell.

    Of course, you won't want the ssh-agent daemons sitting around, so you might want the following in your .logout:

    kill $SSH_AGENT_PID
  2. Finally, time to type a password. The last one of this session, maybe.
    $ ssh-add ~/.ssh/id_dsa Need passphrase for /home/mah/.ssh/id_dsa (you@example.com). Enter passphrase: $
  3. Now, you should test it:
    $ ssh you@example.com Last login: Tue Apr 25 13:40:21 1492 from europe.com Sun Microsystems Inc. SunOS 5.7 Generic October 1998 No mail. [you@example.com]$

    Jubilation! It worked! Go forth and conquer!

Ok, so, did it work or no? Let me know.

And, please, unless you want someone else to use your keys, protect them with a passphrase. I didn't for a while, till I discovered ssh-agent.

If you want to use this setup for editing remote files in emacs under Windows, check out my Tramp-on-NT page.