Total Pageviews

Friday, 24 June 2016

Using ssh-agent with ssh

Over ten years ago (that would be back in 2002 as of this writing),
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.


Get a secure, encrypted connection from your machine (local) to a remote
machine (remote) without typing in a password.

Executive Summary

  1. Create a key pair on the local machine.
  2. Put the public key on any remote machines.
  3. Run ssh-agent to cache login credentials for the session. ssh-agent requires 
  4. the user to "unlock" the private key first.

Related Pages on this site

  1. Alternate agent startup scripts -- Working with KDE, Cygwin, or csh-derived shell?
  2.  Some scripts to help
  3. Troubleshooting -- Can't connect? Here's some ideas to help you troubleshoot 
  4. the problem.
  5. Automatic ssh -- Daemons, long-lived processes and ssh.


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
  1. Generate the keys. Do this on the host that you want to connect from — 
  2. your local computer. Do not do this over the internetNote: Older versions of 
  3. OpenSSH (1.2.xx) and, perhaps, commercial SSH may require that you have 
  4. to use RSA keys. In this case substitute "RSA" for "DSA" after "-t" and "identity" 
  5. for "id_dsa". Continue to substitute "RSA" where you see "DSA" throughout. 
  6. Everything else should be the same.
    Also Note: On Windows machines, the command prompt doesn't understand 
  7. the ~ which on Unix machines means "the home directory". Instead use %HOME% 
  8. wherever you see the tilde.
  9. you@local$ ssh-keygen -t dsa -f ~/.ssh/id_dsa -C ""
    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]
    Your public key has been saved in ~/.ssh/
  10. To use the key on other hosts you will be connecting from, copy the 
  11. ~/.ssh/id_dsa key to the other hosts:
    you@local$ scp ~/.ssh/id_dsa you@another-box:.ssh/
    However, it is probably better just to generate new keys for those hosts.
  12. Make sure the public key is in the ~/.ssh/authorized_keys file on the hosts you
  13.  wish to connect to. You can use a password authenticated connection to do this:
    you@local$ cat ~/.ssh/ | ssh you@remote 'cat - >> ~/.ssh/authorized_keys'
    you@remote's password:
    Note: If an older version of ssh is running on the remote host, you may have to use 
  14. the ~/.ssh/authorized_keys2 file.
    Note: If your local machine is Windows, try
    C:\> type %HOME%/.ssh/ | ssh you@other-host "cat - >> ~/.ssh/authorized_keys"
    you@other-host's password:
    Also note: If the remote server is Windows, you will probably want to use type 
  15. instead of cat for the second half of your command.
  16. Verify that DSA authentication works:
    you@local$ ssh you@remote
    Enter passphrase for DSA key '': ^D
    If you don't get the prompt for your DSA key, then something has gone wrong. 
  17. (One thing to check: verify that sshd_config on the server has been configured 
  18. to do DSA authentication. Look for DSAAuthentication yes or get your 
  19. system administrator to add it if necessary.)
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 
  2. the SSH_AUTH_SOCK environment variable, or you can run it as a daemon.
  3. Since I run gdm on Debian, ssh-agent is started automatically when I log in. 
  4. If you don't have this benefit, you can get it by putting the following line at the end 
  5. of your.xsession file (You can substitute your window manager for gnome-session 
  6. if that is what you use):
    ssh-agent gnome-session

  7. Which basically means that ssh-agent starts up, creates a socket, sets up 
  8. a couple of environment variables and then starts up gnome-session. 
  9. 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 
  10. another graphical login manager under *nix. However, if you login at the console, 
  11. 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. 
  12. Kyle Amon has provided the following bit for a .bash_profile:
    # setup ssh-agent
    # set environment variables if user's agent already exists
    [ -z "$SSH_AUTH_SOCK" ] && SSH_AUTH_SOCK=$(ls -l /tmp/ssh-*/agent.* 2> /dev/null | grep $(whoami) | awk '{print $9}')
    [ -z "$SSH_AGENT_PID" -a -z `echo $SSH_AUTH_SOCK | cut -d. -f2` ] && SSH_AGENT_PID=$((`echo $SSH_AUTH_SOCK | cut -d. -f2` + 1))
    [ -n "$SSH_AUTH_SOCK" ] && export SSH_AUTH_SOCK
    [ -n "$SSH_AGENT_PID" ] && export SSH_AGENT_PID
    # start agent if necessary
    if [ -z $SSH_AGENT_PID ] && [ -z $SSH_TTY ]; then  # if no agent & not in ssh
      eval `ssh-agent -s` > /dev/null
    # setup addition of keys when needed
    if [ -z "$SSH_TTY" ] ; then                     # if not using ssh
      ssh-add -l > /dev/null                        # check for keys
      if [ $? -ne 0 ] ; then
        alias ssh='ssh-add -l > /dev/null || ssh-add && unalias ssh ; ssh'
        if [ -f "/usr/lib/ssh/x11-ssh-askpass" ] ; then
          SSH_ASKPASS="/usr/lib/ssh/x11-ssh-askpass" ; export SSH_ASKPASS
    This brings SSH_AUTH_SOCK and SSH_AGENT_PID as environment variables into 
  13. the current shell.
    The trap should kill off any remaining ssh-agent process. If it doesn't, 
  14. you won't want the ssh-agent daemons sitting around, so you might want 
  15. the following in your.logout:
              ssh-add -D
              ssh-agent -k
    Finally, this solution from Joseph M. Reagle by way of Daniel Starin:
    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
    # 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 || {
    This last version is especially nice since it will see if you've already started ssh-agent 
  16. and, if it can't find it, will start it up and store the settings 
  17. 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 
  18. $HOME is necessary on Cygwin.)
  19. Finally, time to type a password. The last one of this session, maybe.
    you#local$ ssh-add ~/.ssh/id_dsa
    Need passphrase for /home/mah/.ssh/id_dsa (
    Enter passphrase:
  20. Now, you should test it:
    you#local$ ssh you@remote
    Last login: Tue Apr 25 13:40:21 1492 from
    Sun Microsystems Inc.   SunOS 5.7       Generic October 1998
    No mail.
    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.