Cron, SSH, Rsync, and a ssh key with a passphrase (Ubuntu)

I recently scheduled some backup tasks on my VPS using backup-manager which is a neat program for this job. Everything is fine for that.
Then I wanted to set up a cron on my home computer to download the backup archives everyday. This wasn't as easy as it sounded at first.
You might even get those errors:

Permission denied, please try again.
Permission denied, please try again.
Permission denied (publickey,password).
rsync: connection unexpectedly closed (0 bytes received so far) [receiver]
rsync error: unexplained error (code 255) at io.c(635) [receiver=3.0.3]

I need to connect to my VPS using a SSH key that is protected by a passphrase (password). This ssh key is added to my ssh agent (at login time).

The main problem is that cron is run using a restricted environment, meaning it doesn't give environment variables like SSH_AUTH_SOCK.
This variable is needed by the ssh client in order to communicate with the ssh agent that will provide the information on the ssh key.

Here's a workaround for it. It's a quite secure way to fix this.

The technique is to find the socket path in the /tmp directory. Usually for ubuntu, it is /tmp/keyring-*/ssh.
Note that this may not work and might need a little customization if you have multiple ssh-agents running.

So here's how I do it:

Open your crontab, type:
crontab -e

And add or edit your command to look like mine:

SHELL=/bin/bash
BASH_ENV=/home/YOURUSER/.bashrc
# m    h  dom mon dow   command
  0    9  *   *   *     SSH_AUTH_SOCK="$(find /tmp/keyring*/ -perm 0755 -type s -user YOURUSER -group YOURUSER -name '*ssh' | head -n 1)" /home/YOURUSER/PATH/TO/backup-script >> /home/YOURUSER/backup.log 2>&1

Replace YOURUSER with the concerned user name.

This is quite secure as the find command is very specific with permissions, ownership, type (socket) and names.

Any ideas to improve this are welcome!

7 Comments so far »

  1. Matthias Ehrhard said

    May 3 2009 @ 4:58 PM

    Have you tried to source in the environment instead?
    Matthias

  2. Emby said

    August 13 2009 @ 6:06 PM

    I'm trying to get this to work, but my backup.log reads like this:

    Permission denied, please try again.
    Permission denied, please try again.
    Permission denied (publickey,password).
    rsync: connection unexpectedly closed (0 bytes received so far) [sender]
    rsync error: error in rsync protocol data stream (code 12) at io.c(635) [sender=3.0.3]
    Permission denied, please try again.
    Permission denied, please try again.
    Permission denied (publickey,password).
    lost connection

    From this I recon that I need to put in the password for the key, but how do I do that for cron?

    Best regards
    Emby

  3. Arnaud Soyez said

    August 13 2009 @ 6:14 PM

    Emby,
    My ssh key is unlocked at login time using seahorse, that might be why I don't get these errors, so you might have to do that too.
    Try:
    $ ssh yourserver.domain.com
    it will pop up the password prompt window, from there I think there is a checkbox to tell to unlock this key at login time.

  4. benjou said

    May 1 2010 @ 11:29 AM

    Great! It solved my long standing issue. Thanks!

    However, there my be a typo in your command

    find /tmp/keyring*/ -perm 0755 -type s -user YOURUSER -group YOURUSER -name 'ssh' | head -n 1

    will not work since the -name is not ssh but socket.ssh

    changing the command to

    find /tmp/keyring*/ -perm 0755 -type s -user YOURUSER -group YOURUSER -name '*ssh' | head -n 1

    did the deal in my hands.

    Thanks again!

  5. Arnaud Soyez said

    May 1 2010 @ 11:32 AM

    Oh, okay, I just checked on Ubuntu 10.04 and it is actually just 'ssh', what distro do you have?

  6. benjou said

    May 3 2010 @ 9:53 AM

    I'm still on 9.10. This explains that...

  7. El Blog de Marcelo! » Sincronizar carpetas a un Servidor Casero automáticamente said

    June 18 2010 @ 7:17 AM

    [...] Lo más interesante es que a pesar de ser ejecutado desde Cron, aprovecha las llaves SSH desbloqueadas por Gnome en la sesión de escritorio del usuario, es decir que la primera sincronización, si previamente no me había conectado al equipo remoto, me pide la frase de paso para desbloquear la clave privada; a partir de ese momento ésta queda compartida, gracias al ssh-agent que utiliza Gnome en background. Luego, mientras siga la sesión de escritorio establecida, va a aprovechar la llave desbloqueada por el usuario y hacer la sincronización sin mayor problema. Esto es mucho mejor en cuanto a seguridad que usar una clave privada sin frase de paso contra el servidor, y me permite desbloquearla sólo la primera vez y no cada vez que se hace la sincronización, siendo un perfecto balance (al menos para mí) entre seguridad, automatización y comodidad. Lógicamente esto sirve para utilizar en cualquier conexión SSH que se quiera establecer, y la solución, después de dar muchas vueltas y probar muchas alternativas (¡el ssh del cron no “veía” al agente!), la encontré en este post. [...]

Comment RSS · TrackBack URI

Leave a comment

Name: (Required)

eMail: (Required)

Website:

Comment: