This document describes how I setup ssh to be usable on OSX. The main thing I want to have a workable ssh-agent setup.
The first step is to set the SSH_AUTH_SOCK
variable,
so that any ssh
based programs can find the ssh
agent. However, to set an environment variable that is inherited by
all the user processes a bit of magic is required, as things are a bit
different to Linux. On startup OS X reads the file
~/.MacOSX/environment.plist
. This describes which environment
variables should be set. The format is Apples standard property list format
which ends up with some verbose XML:
<?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/benno/.ssh/ssh_agent</string> </dict> </plist>
So this has set things up so that every process has SSH_AUTH_SOCK
set
to /Users/benno/.ssh/ssh_agent
.
The next step starting ssh-agent
when I login.
Before we can get to running ssh-agent
we need to sort out
how to run things on startup in general. What we want to have is a login
shell script that is executed on startup.
Mac OSX supports running applications when a user logs in. This is controlled through: System Preferences -> Accounts -> Login Items. This UI lets you add arbitrary programs to run on login, unfortunately it seems that a simple shell script just doesn't work, and instead we need to have a GUI application. To get around this we call on AppleScript.
Open the AppleScript editor from Application -> AppleScript -> Script Editor. We can now create a simple AppleScript application. The application is really simple and just consists of:
do shell script "/Users/benno/local/bin/login"
All this application does is run the shell script
/Users/benno/local/bin/login
. You should obviously
change this to reflect your setup.
You should then save it is login.app
. When you save it be
sure to change the format to Application. Make sure you save
it somewhere where can you easily find it again. I put all my user
application into ~/local/bin
Now that you have a GUI application, you can add this login.app to your Login Items as described above.
login
shell scriptWe now have a setup so that a login
shell script is run
whenever we login. Now the trick is to get it to run ssh-agent
for us.
My login scripts looks like this:
#!/bin/sh killall ssh-agent > /dev/null; rm -f $SSH_AUTH_SOCK; ssh-agent -a $SSH_AUTH_SOCK > /dev/null
Firstly we use killall
to ensure that we don't have any extra copies of
ssh-agent
around. Then we remove the socket file, in case it is stale. Note
that we use the SSH_AUTH_SOCK
environment variable that was set in
environment.plist
. Finally we run ssh-agent
with the
-a
option to get it to use a specific authentication socket, rather
than creating a random one.
ssh-add
So far, so good, however the one remaining piece is to get it such that on login
we run ssh-add
so that we can add our key to the ssh-agent
keychain. This is slightly tricky, because usually ssh-add
expects
to get input from stdin
, which unfortunately doesn't exist.
ssh-add
has a way of calling an external program to get the passphrase
string, but Apple doesn't provide an Aqua based program to do this. Luckily
there is a program SSHPassKey which provides an Aqua
based program key program.
#!/bin/sh killall ssh-agent > /dev/null; rm -f $SSH_AUTH_SOCK; ssh-agent -a $SSH_AUTH_SOCK > /dev/null export SSH_ASKPASS=/Users/benno/local/bin/SSHPassKey.app/Contents/MacOS/SSHPassKey export DISPLAY="" ; ssh-add < /dev/null
So we set SSH_ASKPASS
to the SSHPassKey program, so that ssh-add
will call it instead of trying on the console. Unfortunately we need to do a bunch of other
seed to actually make ssh-add
do what we want. The first it setting
DISPLAY
to trick it into thinking it has X running, and then we need to redirect
input from /dev/null
to fool it into thinking it doesn't have a terminal.
And after all that I now have a setup so that when I login I can type in my passphrase and
have ssh
just work.
Of course the above steps might not work for you for any number of reasons, in which case you can try e-mailing me.