MacTechNotes

Thursday, September 08, 2005

ssh-agent on Mac OS X

Overview
There are several methods one can use to make sure ssh-agent is running for you and that other Aqua apps can take advantage of it. This describes the one I use, which is simply two files: one to setup the environment for all Aqua apps, and one which is automatically run when a Terminal (or xterm, or iTerm, etc) window is opened.


Environment
The important part of using ssh-agent is an environment variable, SSH_AUTH_SOCK, which points to a socket used to communicate with ssh-agent. What I do is set this in ~/.MacOSX/environment.plist to point to /Users/blb/tmp/ssh/ssh-agent.socket (which, for the paranoid like myself, should be in a directory readable only to the user, ie, mode 700 for /Users/blb/tmp/ssh).

Setting it involves writing the file environment.plist, which is a property list (hence the plist extension). The format is XML, and mine is as such:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
"http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>SSH_AUTH_SOCK</key>
<string>/Users/blb/tmp/ssh/ssh-agent.socket</string>
</dict>
</plist>

This gets SSH_AUTH_SOCK in your environment on future logins. Be sure to restart Terminal (at least) so it can pick up the change. Of course, it doesn't do much until ssh-agent is running.

Running ssh-agent
ssh-agent itself needs to be running, and setting the environment variable doesn't help with that. The other step is to modify your login shell script to run one new script (which I've called check_ssh_agent) that runs ssh-agent if it isn't already running. This means that you do have to pop up a Terminal window once so your login shell script will run, but then no more worries. My check_ssh_agent is:

#!/bin/sh
#
# Check that the ssh-agent is running, and if not, kick it off
#

if [[ -z $SSH_AUTH_SOCK ]]; then
SOCKETFILE=/Users/${USER}/tmp/ssh/ssh-agent.socket
else
SOCKETFILE=${SSH_AUTH_SOCK}
fi

/bin/ps -wU ${USER} | /usr/bin/grep "[s]sh-agent" > /dev/null
if [[ $? -gt 0 ]]; then
/bin/rm -f ${SOCKETFILE}
/usr/bin/ssh-agent -a ${SOCKETFILE} > /dev/null
/bin/chmod 600 ${SOCKETFILE}
fi

You'll note that my paranoia continues as, after ssh-agent is run, the script sets the socket to mode 600 for extra safety.

Once ssh-agent is running, you can run ssh-add to add whichever keys you use.

Caveats
There are a few issues which must be pointed out with this method. The first is the previously-mentioned one where you have to open a Terminal window to get ssh-agent running. For me, this is simple since I have Terminal running most of the time. For some, it may be a bit annoying. One solution to this would be to change the check_ssh_agent script to be a .command file and set that to be run on login (I haven't tested this method, however).

Another is that ssh-agent will continue to run after logout. Since the process is running with your ID, and is communicating through a socket to which only you have access, you only need to worry about others accessing your account, and root. But this also applies for the time while you are logged in as well, so it shouldn't be to major a concern. And if you don't trust root on your machine, you shouldn't be using sensitive passwords with any process on that machine. Besides, how often do you log out anyway?

9 Comments:

  • By Anonymous sjk, at October 7, 2005 at 3:21 PM  

  • Two items of note:

    I'd like to point out that instead of the slower "ps|grep", you can simply run "ssh-add -l".

    If ssh-add can't communicate with ssh-agent, it will return error 2.

    So you could write

    ssh-add -l &> /dev/null
    if [ $? -le 1 ]; then
    /bin/rm -f ${SOCKETFILE}
    /usr/bin/ssh-agent -a ${SOCKETFILE} > /dev/null
    /bin/chmod 600 ${SOCKETFILE}
    fi

    Furthermore, there's a patch for ssh-agent so you can run it as a launchd agent. That way, ssh-agent gets started when you log in, and gets killed when you log out. The disadvantage is that you need to compile ssh-agent yourself. Check it out at landonf's site

    By Anonymous Wout Mertens, at January 25, 2006 at 3:24 AM  

  • Why don't you use SSHKeychain, which does all of this and more. Its free, it integrates nicely with the GUI to ask you for your passphrase when needed, and it has a useful tunnel manager. It also sets up the environment so everything can use it.

    By Anonymous Anonymous, at June 1, 2006 at 3:48 AM  

  • I tried out SSHKeychain, available here. It's easy to install and set up, and enables other ssh-capable aqua applications. Recommended. See the FAQ for simple install instructions; you do have to do a bit more than just drag it into the Applications folder. But once you've followed them, It Just Works.

    By Blogger Steve Simmons, at July 18, 2007 at 10:05 AM  

  • I've tried both ssh-agent and SSHKeychain and SSHKeychain is far easier to install. Just read the instructions and make sure to catch the little note during the installation that ports below <1024 have been disabled for tunneling (if you want to forward any of those ports). I would recommend SSHKeychain on any OSX setup. ssh-agent on any other unix or linux ENV.

    By Anonymous Anonymous, at September 3, 2007 at 11:47 AM  

  • Thanks for the info..See I too have earlier worked on it..and I thinks that Ssh-agent lacks an easy way to use it for multiple shell/terminal sessions. This is best explained by example. I log onto my Mac OS X/FreeBSD machine at the console. I needs to administrate a server so I open a terminal window. Now I must launch ssh-agent followed by ssh-add and then type in my passphrase to set up my ssh key(s). Now my ssh key is authenticated and ready for use during the rest of this session. So far, so good.

    While I’m working on that first server, I needs to connect to another machine to see how I configured something there. This is where ssh-agent becomes onerous. I open another terminal window and must once again launch ssh-agent, and then ssh-add, type in my passphrase, and finally connect. But now I have two instances of ssh-agent running.

    Having multiple ssh-agents is the default behavior because ssh-agent has no built-in mechanism for detecting and reusing an existing ssh-agent process. To do so, one must determine the correct path to the socket file and set SSH_AUTH_SOCK accordingly.

    By Anonymous aquabot, at September 22, 2007 at 1:58 AM  

  • For the record, in the above post aquabot is not using ssh-agent as it was intended. Proper usage on under X11 would have the window manager executed as a child of the ssh-agent process. (e.g., the last line in your .xsession might be "ssh-agent $wm", $wm being the path to your window manager.) Your password then needs to be authenticated via ssh-add only once per login session - regardless of how many shells you open.

    This setup is a little trickier to achieve under OSX, due to it's inherent schizophrenia.

    By Anonymous Anonymous, at October 2, 2007 at 3:19 AM  

  • Leopard users have it easier. OSX 10.5 now starts the agent for you via launchd, and ssh now looks for passphrases in your keychain. Just go to a terminal and type ssh-add -K .

    By Anonymous Anonymous, at December 29, 2008 at 2:02 PM  

  • This stuff really works, keep up the good work mate.

    read ya soon

    By Anonymous macgeek, at December 19, 2009 at 6:28 PM  

Post a Comment

<< Home