ssh-agent and crontab -- is there a good way to get these to meet?

Viewed 30428

I wrote a simple script which mails out svn activity logs nightly to our developers. Until now, I've run it on the same machine as the svn repository, so I didn't have to worry about authentication, I could just use svn's file:/// address style.

Now I'm running the script on a home computer, accessing a remote repository, so I had to change to svn+ssh:// paths. With ssh-key nicely set up, I don't ever have to enter passwords for accessing the svn repository under normal circumstances.

However, crontab did not have access to my ssh-keys / ssh-agent. I've read about this problem a few places on the web, and it's also alluded to here, without resolution:

Why ssh fails from crontab but succedes when executed from a command line?

My solution was to add this to the top of the script:

### TOTAL HACK TO MAKE SSH-KEYS WORK  ###
eval `ssh-agent -s`

This seems to work under MacOSX 10.6.

My question is, how terrible is this, and is there a better way?

11 Answers

When you run ssh-agent -s, it launches a background process that you'll need to kill later. So, the minimum is to change your hack to something like:

eval `ssh-agent -s` 
svn stuff
kill $SSH_AGENT_PID

However, I don't understand how this hack is working. Simply running an agent without also running ssh-add will not load any keys. Perhaps MacOS' ssh-agent is behaving differently than its manual page says it does.

Not enough reputation to comment on @markshep's answer, just wanted to add a simpler solution. lsof was not listing the socket for me without sudo, but find is enough:

* * * * * SSH_AUTH_SOCK="$(find /tmp/ -type s -path '/tmp/ssh-*/agent.*' -user $(whoami) 2>/dev/null)" ssh-command

The find command searches the /tmp directory for sockets whose full path name matches that of ssh agent socket files and are owned by the current user. It redirects stderr to /dev/null to ignore the many permission denied errors that will usually be produced by running find on directories that it doesn't have access to.

The solution assumes only one socket will be found for that user.

The target and path match might need modification for other distributions/ssh versions/configurations, should be straightforward though.

Related