How-To: "Password-less" SSH
Back to the How-To Index ]

Setting up "password-less" SSH is pretty simple---it's really just a matter of understanding the file formats involved. This crash-course should get you rolling.

First, create a key:

% ssh-keygen -t dsa
(See the man page if you want to create a key of a certain length, or something else specific or "advanced.")

At this point, it's probably useful to mention that there are two formats for SSH-2 keys like the ones you created: the "SECSH" format and the "OpenSSH" format. (The latter is similar to the format used for SSH-1 keys.) The version of ssh-keygen distributed with OpenSSH allows you to translate between the two key formats. (The proprietary distribution of ssh-keygen does not include such a facility.)

So, find a copy of OpenSSH laying around somewhere and use its ssh-keygen utility to translate your generated key into the other format. (The ssh-keygen you used to generate your DSA keypair may have been OpenSSH's version---try typing ssh -V to get your installation's vital statistics.

Anyway, once you find the OpenSSH version of the ssh-keygen tool, run one of the following two commands:

If you generated your key initially with OpenSSH:
% ssh-keygen -ef id_dsa.pub > my-secsh-key.pub
If you generated your key initially with non-OpenSSH:
% ssh-keygen -if id_dsa_2048_a.pub > my-openssh-key.pub

If you generated your key initially with OpenSSH, skip to the next section.

If you generated your key initially with non-OpenSSH, you need to explicitly tell the client to use the key as your identity:
% echo 'IdKey id_dsa_2048_a' > .ssh2/identification

Now copy your public key to a server someplace. You will want to know which kind of SSH the server runs---the open-source OpenSSH or the "commercial but free for educational use" SSH---and copy the proper key. It will look something like this:

% scp id_dsa.pub cvs.doc.wustl.edu:mykey.pub Password: id_dsa.pub 100% |*****************************| 1234 00:00

Get a shell on that machine. For example:

% ssh cvs.doc.wustl.edu Password: Last login: Mon May 12 15:10:09 2003 from limbo.cs.wustl.edu ***** Please remember to point your .forward to a real email address. ****** ***** Never, ever, access the CVS repository directly. ********************* bash-2.05a$

Now, we need to put the key in the right place:

If the server there is OpenSSH, then do this:
% mkdir -p .ssh % cat mykey.pub >> .ssh/authorized_keys2
If the server there is non-OpenSSH, then do this:
% mkdir -p .ssh2 % mv mykey.pub .ssh2 % echo 'Key mykey.pub' >> .ssh2/authorization

And there you have it. Nothing to it. However, you might want to generate an additional keypair (or translate the private key you generated above) into the other format and set that up too. Because our home directories are set up on an NFS-shared drive, and there are OpenSSH and non-OpenSSH clients and servers lurking around, you will have all the bases covered if you do this, and, conceptually at least, you'll be able to use SSH to get from any box to any other box if you set up the files correctly, as shown above. (Above, of course, it is assumed that the client and server don't share your home directory.)

Now, to set up your personal SSH agent...

Now that you have "password-less" SSH access, you may be wondering what the point was, since now you have to enter your passphrase everytime. You may be wondering, "Can I get passphrase-less SSH now?"

Well, you can. Or, rather, you can set it up so that you only need to enter your passphrase once per session and your key remains ready for use until you next log out. This is done with the ssh-agent utility.

There are two main ways to run ssh-agent. Let's see what happens if we just run it:

% ssh-agent SSH_AUTH_SOCK=/tmp/ssh-XXQ3QdKZ/agent.12080; export SSH_AUTH_SOCK; SSH_AGENT_PID=12081; export SSH_AGENT_PID; echo Agent pid 12081;
So by running ssh-agent we get shell commands describing how to communicate with a running agent. But these are Bourne-flavored shell commands---to get C-shell-flavored commands, we need to run it with the -c option:
% ssh-agent -c setenv SSH_AUTH_SOCK /tmp/ssh-XXQ3QdKZ/agent.12080; setenv SSH_AGENT_PID 12081; echo Agent pid 12081;

Is the agent really running? Yes:

% ps 12081 PID TTY STAT TIME COMMAND 12081 ? S 0:00 ssh-agent

To get these commands to mean something to the current shell, we can do this:

% eval `ssh-agent -c` Agent pid 12081

Now, instead of printing the shell commands out to the terminal, the shell interprets them. You can then see the effect:

% echo $SSH_AGENT_PID 12081

But there is a problem---when are these agents stopped? They aren't. You have to manually kill the buggers or set up a way to automatically clean them up periodically. It's not pretty.

So, there's a better way to run ssh-agent. You can set it up as the parent of your session. For example, in your ~/.xsession file, you can write this to start KDE under ssh-agent:

ssh-agent startkde

Or, if you prefer GNOME:

ssh-agent gnome-session

This starts KDE/GNOME when you log in---as a subprocess of ssh-agent. When the kdestart (or gnome-session) process completes (i.e., when you log out, or the machine reboots, or X crashes, etc.), ssh-agent will exit. The benefits of this are twofold. First, you don't have extraneous ssh-agent processes lying around. Second, every terminal you open---indeed, any process you execute---when you are logged into your KDE/GNOME session will have easy access to the agent, because the SSH_AGENT_PID and SSH_AUTH_SOCK are in the environment.


Morgan Deters / Last updated: 15 August 2005