You may have read in my journal about how I have my ssh-agent set up on Mac OS X; briefly, I use a login plugin called SSHAgentStartup which creates an ssh-agent before logging in, and sets up the environment in ~/.MacOSX/environment.plist, so it is global to all my apps. I have it also create a ~/.bash_ssh_env file that I can source from my bash init files.
Then I have a startup script that calls ssh-add without a terminal attached (ssh-add </dev/null works, though in this case it is a startup AppleScript that just does do shell script "/usr/bin/ssh-add" in a try/end try block), with SSH_ASKPASS set to the path of an app called SSHPassKey, which retrieves my ssh passphrase from the Keychain. Since the Keychain is unlocked upon logging in, and the ssh-agent is run and its environment vars are set before this script is run, this automatically adds my keys to the ssh-agent without any extra user interaction.
So I just log in, and this is all set up for me: a global ssh-agent for all my GUI apps and shells, with my keys added to the agent and ready to go.
The only problem I have with this setup is that I like to have my Keychain lock automatically after inactivity or sleep, for security's sake; but this does not also disable the ssh-agent. So there's a little security issue there that I wanted to address.
So, this ssh-lock script was born. It checks to see if the Keychain named for the current user is locked, and if so, it removes my identities from the ssh-agent. Mmmm, security!
[ Keychain Scripting is a little Faceless Background App; it will launch, but it won't show up in the Dock, and it will stay open. The glue for this app is created automatically when you install Mac::Glue, along with several other FBAs that reside in the /System/Library/ScriptingAdditions folder (such as URL Access Scripting, which is pretty much useless from Perl, since we have LWP). ]
use Mac::Glue;
my $ssh_add = '/usr/bin/ssh-add';
my $kc = new Mac::Glue 'Keychain_Scripting';
my $locked = $kc->prop(locked => keychain => scalar getpwuid($<));
if ($ENV{SSH_AGENT_PID} && kill 0, $ENV{SSH_AGENT_PID}) {
system($ssh_add, '-d') if $locked->get;
}
I call this from crontab (note that it sets up the ssh-agent vars first):
And I also wrote a little front-end to ssh, that checks to see if my ssh-agent has my identities in it, and if not, adds them automatically, just like the startup script does, with no user interaction, unless the Keychain is locked, in which case SSHPassKey will prompt me for the Keychain password. Then, it just goes ahead and calls ssh.
my $ssh = '/usr/bin/ssh';
my $ssh_add = '/usr/bin/ssh-add';
if ($ENV{SSH_AGENT_PID} && kill 0, $ENV{SSH_AGENT_PID}) {
if (`$ssh_add -l` =~ /no identities/) {
`$ssh_add
system($ssh, @ARGV);
Mmmmm, glue.
Re:Stupid Mac::Glue/SSH Tricks
pudge on 2003-11-20T15:45:48
I've ssen this, but have been using SSHAgentStartup/SSHPassKey since before it existed, and I've never been able to figure out if it is able to set my ssh-agent environment system-wide at login, so I didn't bother switching to it. Besides, I am happy with the setup, except for the one thing it didn't do... but SSHKeychain did plant the seed in my head about ssh-agent being secured when the Keychain was locked.