http://mah.everybody.org/docs/ssh
Using ssh-agent with ssh
p::docs
Using ssh-agent with ssh
by Mark A. Hershberger (weblog)
I went searching for a good, general page that would explain how to do
passwordless
logins using ssh-agent and didn't find much at the time
(now there is much more out there). So I wrote this
page.
Goals
Get a secure, encrypted connection to a remote machine without typing
in a password.
Executive Summary
Create a key pair on the local machine.
Put the public key on any remote machines.
Run ssh-agent to cache login credentials for the
session. ssh-agent requires the user to "unlock" the
private key first.
Related Pages
Alternate agent startup scripts --
Working with KDE, Cygwin, or csh-derived shell? Some scripts to help
Troubleshooting -- Can't
connect? Here's some ideas to help you troubleshoot the problem.
Automatic ssh -- Daemons, long-lived
processes and ssh.
Methods
Use OpenSSH to handle the
authentication.
For Windows users, the methods I describe here will work
with the OpenSSH that is part of the
CygWin toolset.
Anyway, here is how to set up a pair of keys for passwordless
authentication via ssh-agent.
Generate the keys. Do this on the host that you want to connect
from.
Note: Older versions of OpenSSH (1.2.xx) and,
perhaps, commercial SSH may require that you have to use
RSA keys. In this case substitute "RSA" for "DSA" after
"-t" and "identity" for "id_dsa". Continue to substitute
"RSA" where you see "DSA" throughout. Everything else should
be the same.
Also Note: On Windows machines, the command
prompt doesn't understand the ~ which on Unix machines
means "the home directory". Instead use %HOME%
wherever you see the tilde.
$ 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
$
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.
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
C:\> type %HOME%/.ssh/id_dsa.pub | ssh you@other-host "cat - >> ~/.ssh/authorized_keys"
you@other-host's password:
C:\>
Also note: If the remote server is Windows, you
will probably want to use type instead of
cat for the second half of your command.
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. (One thing to check: verify that
sshd_config on the server has been configured to
do DSA authentication. Look for DSAAuthentication
yes or get your system administrator to add it if
necessary.)
Now that that works, you will want the passwordless part, right?
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, 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 your .xsession file (You can
substitute your window manager for gnome-session
if that is what you use):
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.
The above solution is the best one if you are logging in via
GDM or another graphical login manager under *nix. However, if
you login at the console, or want to use ssh-agent under Cygwin,
you'll have to use one of the following solutions.
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
SSHAGENTARGS="-s"
if [ -z "$SSH_AUTH_SOCK" -a -x "$SSHAGENT" ]; then
eval `$SSHAGENT $SSHAGENTARGS`
trap "kill $SSH_AGENT_PID" 0
fi
(If you use csh or tcsh, see this
note for the equivilent piece of code for your .login
shell.)
This brings SSH_AUTH_SOCK and
SSH_AGENT_PID as environment variables into the
current shell.
The trap should kill off any remaining
ssh-agent process. If it doesn't, you won't want the
ssh-agent daemons sitting around, so you might want the
following in your .logout:
kill $SSH_AGENT_PID
An alternative, provided by John Buttery, is
if [ ${SSH_AGENT_PID+1} == 1 ]; then
ssh-add -D
ssh-agent -k > /dev/null 2>&1
unset SSH_AGENT_PID
unset SSH_AUTH_SOCK
fi
Finally, this solution from Joseph
M. Reagle by way of Daniel Starin:
SSH_ENV="$HOME/.ssh/environment"
function start_agent {
echo "Initialising new SSH agent..."
/usr/bin/ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
echo succeeded
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
/usr/bin/ssh-add;
}
# Source SSH settings, if applicable
if [ -f "${SSH_ENV}" ]; then
. "${SSH_ENV}" > /dev/null
#ps ${SSH_AGENT_PID} doesn't work under cywgin
ps -ef | grep ${SSH_AGENT_PID} | grep ssh-agent$ > /dev/null || {
start_agent;
}
else
start_agent;
fi
This last version is especially nice since it will see if
you've already started ssh-agent and, if it can't find it,
will start it up and store the settings so that they'll be
usable the next time you start up a shell.
(Update 25 Sep 2007: Adam Piper pointed out that quoting
anything that uses $HOME is necessary on Cygwin.)
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:
$
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! (If it doesn't
work, try chmod -R go-rw ~/.ssh on the server and try again.)
Ok, so, did it work or no? Let
me know.
If you want to use this setup for editing remote files in emacs under
Windows, check out my Tramp-on-NT
page.
If you want to understand a little bit more about how all this
works,
read An
Illustrated Guide to SSH Agent Forwarding.
Acknowlegements
27 Aug 2002: David Previti offered the working
Windows-client to Windows-server key copy command as well as
other Window-isms.
9 Aug 2002: Lloyd Smith suggested verifying that
sshd_config is set up to do DSA authentication if it
fails initially.
3 Jul 2002: David Newcomb offered the trick of
putting trap 0 in the login/profile script.
18 May 2002: A more complete logout script
from John Buttery. Also added tips on using RSA rather than
DSA keys.