ssh-agent and Mac OS X

Introduction: I am beefing up security by requiring password protected SSH keys (two factor) for authentication. With this change, the use of ssh-agent is quite important. Because I use ssh frequently, it’s worth making its use as transparent as possible.

The Problem: 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.

Research: I researched the options available for solving this issue on my Mac. I found Xander Schrijen’s SSH Agent for Mac OS X but had several issues that prevented me from falling into love with it. There is also SSHKeychain but it didn’t work at all on my Intel macs (it has since been fixed).

The Solution: After giving up on a easy point-and-click solution, I decided the best solution is one that works equally well on all the UNIX-like systems I use regularly: Mac OS 10.4, 10.5, Linux, and FreeBSD. I wrote a simple shell script, then a more complex one, then a perl script, and finally another shell script that I think is just about perfect. Its only requirement (beyond openssh) is bash.

Documentation is contained in the script. It has been tested on Mac OS X and FreeBSD. It should run without modification on any UNIX-like OS and requires the [ba]sh shell. I attempted a script that worked with both bash and tcsh but it simply wouldn’t work. Tcsh is a perfectly adequate shell but a miserable programming environment.

Demonstration: Opening a new Terminal window:

Last login: Sat Jul 28 20:41:10 on ttys001
cleaning up stale ssh agent
starting ssh-agent -a /Users/matt/.ssh/agent.sock
ssh agent for matt found at pid 30268.
adding ssh key(s) to agent
Identity added: /Users/matt/.ssh/id_rsa (/Users/matt/.ssh/id_rsa)
Identity added: /Users/matt/.ssh/id_dsa (/Users/matt/.ssh/id_dsa)
[matt@IntelliBigMac] ~ %

Opening a second Terminal window:

Last login: Sat Jul 28 20:52:54 on ttys002
ssh agent for matt found at pid 30268.
[matt@IntelliBigMac] ~ %