Monday, March 15, 2010

Follow-up to "Using passphrase-protected SSH keys in Cron"

So I wrote a while back about automating SSH jobs in Cron when the keys were passphrase-protected.  I was very excited about being able to automate tasks over SSH and I was sure I had it working but a few days later I realized that it wasn't working at all.  It was failing without any error I could see.

I'll spare you the gory details of how many hours I spent and how many things I tried when getting it working.  The bottom line is that this evening I realized that when my Cron job or script ran "ssh-agent -s" another ssh-agent process was being created!  I figured that that command was simply exporting the environment variables necessary for me to use the process created by the Gnome session (you may remember that I have seahorse set to automatically unlock my ssh key when I log in), but instead I was inadvertently creating a new ssh-agent process with no keys in it.  Then when I tried to run Unison, it found the wrong ssh-agent process.

To fix it, I needed to find a way to keep from starting another ssh-agent process, and instead gain access to the one seahorse starts every time I log in.  I made a change to my crontab that would search for the existing ssh-agent process ID and authentication socket and import them into the cron environment.  This is kind of a hack but it actually works (not like last time).  Just add the following to your script before trying to connect to your SSH server (or do what I did and put them right into the cron job, separated by semicolons):

    export SSH_AGENT_PID=`ps -a | grep ssh-agent | grep -o -e [0-9][0-9][0-9][0-9]`
    export SSH_AUTH_SOCK=`find /tmp/ -path '*keyring-*' -name '*ssh*' -print 2>/dev/null`

4 comments:

  1. THANK YOU! THIS WORKS BRILLIANTLY!!

    I've been searching for a solution to make my backup script via SSHFS work for an entire year, and this post finally saved me!

    Cheers, and keep up the good work!!!

    Michael

    ReplyDelete
  2. I find that this is more reliable at getting the SSH_AGENT_PID:

    ps axww | grep -v grep | grep ssh-agent | egrep -o -e '^[0-9]{2,5}'

    ReplyDelete
  3. I combined Jizldrangs suggestion with Anonymous's for my install. I also needed to change the path for find from /tmp/ to /run/ (just search your root directory for the path containing the folder *keyring-* and associated file *ssh* if it doesn't work and use that path).

    set -x SSH_AGENT_PID (ps axww | grep -v grep | grep ssh-agent | grep -o -e [0-9][0-9][0-9][0-9])

    set -x SSH_AUTH_SOCK (find /run/ -path '*keyring-*' -name '*ssh*' -print 2>/dev/null)

    This is for the fish shell so I use () to surround the command. You may need to use "" or `` instead.

    ReplyDelete
  4. This post helped me a lot in year 2016.
    But for Ubuntu I had to use:

    export SSH_AGENT_PID=`ps axww | grep -v grep | grep ssh-agent | grep -v ' -s' | awk '{print $1}'`
    export SSH_AUTH_SOCK=`find /run/user -path '*keyring-*' -name '*ssh*' -print 2>/dev/null`

    ReplyDelete