ssh-under-cron deja de funcionar en OS X 10.7 Lion

Acabo de actualizar de Snow Leopard a Lion, y mis trabajos cron que usan ssh han dejado de funcionar. Parece que ssh-agent ya no funciona como se esperaba.

Aquí hay una versión exprimida de mi script llamado desde cron que funcionó muy bien con Snow Leopard:

#!/bin/bash
whoami # just to verify I'm running as myself, not root
ssh-agent # just to see what it outputs    
eval `ssh-agent`
ssh -vvv REMOTESERVER ls

Cuando se ejecuta desde el símbolo del sistema, este script funciona como se esperaba.

Cuando se ejecuta desde cron, no funciona. La salida del agente ssh parece normal:

SSH_AUTH_SOCK=/tmp/ssh-QRxPUMRxbu/agent.17147; export SSH_AUTH_SOCK;
SSH_AGENT_PID=17148; export SSH_AGENT_PID;
echo Agent pid 17148;
Agent pid 17150

Pero el ssh -vvvresultado muestra que falla justo cuando se debe leer la clave privada:

debug1: Server accepts key: pkalg ssh-dss blen 818
debug2: input_userauth_pk_ok: fp ...
debug3: sign_and_send_pubkey: DSA ...
debug1: PEM_read_PrivateKey failed
debug1: read PEM private key done: type <unknown>
debug1: read_passphrase: can't open /dev/tty: Device not configured
debug2: no passphrase given, try next key

En otras palabras, espera que escriba la frase de contraseña para ~/.ssh/id_dsa, que por supuesto no funciona en trabajos cron.

Todo esto funcionó en Snow Leopard.

Tenga en cuenta que tengo la configuración de Acceso a llaveros para que ssh, ssh-agenty ssh-addpuedan leer mi frase de contraseña para mi .ssh/id_dsaarchivo; como resultado, puedo usar SSH desde un indicador de terminal sin tener que ingresar mi frase de contraseña.

¿Es este problema que necesito ejecutar ssh-adden algún momento de mi proceso de inicio de sesión? Ejecutarlo desde un indicador de bash estándar no ayuda al trabajo cron (aunque, curiosamente, me solicita mi frase de contraseña... lo que creo que no es necesario debido a la configuración de Acceso a Llaveros).

NOTA 1: antes de redirigirme, sé que aquí hay una pregunta similar ( Mac OS X Lion y sshpass ), pero se trata específicamente de un programa sshpassque no uso (aunque creo que esta pregunta también sería respondida por este ) ).

NOTA 2: me doy cuenta de que las claves SSH sin contraseña resolverían mi problema; sin embargo, prefiero no ir por este camino.

cron se ha ido. Consulte la etiqueta de lanzamiento aquí para obtener todo tipo de ayuda (haga el movimiento: maneja puertos, entorno y mucho más, mucho mejor que cron). Espero que alguien tenga una solución, pero el cron mojo aquí está envejeciendo. .
cron todavía se ejecuta en Lion ... pero tienes razón, debería hacer el movimiento. Sin embargo, un archivo XML de más de 10 líneas para hacer el trabajo de una sola LÍNEA de crontab es bastante aburrido. Tal vez en 10 años cambien los archivos plist a JSON, y habrá mucho regocijo, y 10 años después volverán a crontab, y los barbas grises de BSD se reirán. Supongo que seré un BSD barba gris para entonces...
Acabo de cambiar a launchd, funciona de maravilla. La secuencia de comandos llamada no necesita interactuar con ssh-agent en absoluto; puede saltar directamente al comando ssh después del hashbang. Si tu comentario fuera una respuesta, lo aceptaría =)
JSON ciertamente brilla sobre XML en muchos casos, pero todas las listas anteriores probablemente forzaron el problema. Estoy encantado de que tengamos un reemplazo basado en datos estructurados, eficientes y unificados. cron y seguro que nos sirvió bien durante mucho tiempo.
He estado buscando por todas partes recursos web adicionales, pero siempre termino de nuevo en esta publicación. ¿Seguro que alguien tiene más que aportar a la discusión? Intenté usar un plist simple para ejecutar mi script de shell, pero luego mailx no envía mis notificaciones. Todavía me gusta cron y lo uso en Ubuntu todo el tiempo. No quiero volver a 10.6, pero este problema me está matando. No me gusta que me obliguen a usar launchctl y tener que aprender lo que me parece un marco muy amplio para automatizar básicamente los scripts de shell. ¿Alguien tiene nuevas ideas?
Cambiar a launchctl solucionó mi problema por completo, así que dejé de preocuparme por cron. Si no recuerdo mal, esta página fue lo que usé. Generar un archivo plist run-this-script para launchctl es bastante sencillo.
Obtenga 'Lingon X' o LaunchControl y launchdserá mucho más fácil de manejar.

Respuestas (4)

Para cualquiera que termine en esta página, me di cuenta de que debería publicar la respuesta:

El uso de launchd en lugar de cron soluciona el problema de autorización. Sus trabajos de inicio de usuario (que se ejecutan solo cuando está conectado) utilizan correctamente la información del agente SSH que se desbloqueó a través de su llavero como parte del inicio de sesión (como parte de la gestión de claves OS X estándar, no se requiere ningún otro software).

Para minimizar mis interacciones con launchd, creé un solo trabajo de launchd que llama a un script bash. De esta manera, simplemente puedo editar el script sin tener que lidiar con launchd.

Aquí está el archivo launchd:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <key>Label</key>
  <string>com.mycron.hourly</string>

  <key>ProgramArguments</key>
  <array>
    <string>/Users/john/bin/cron.hourly</string>
  </array>

  <key>Nice</key>
  <integer>1</integer>

  <key>StartInterval</key>
  <integer>3600</integer> <!-- start every X seconds -->

  <key>RunAtLoad</key>
  <true/>
</dict>
</plist>

Guardé el archivo en ~/Library/LaunchAgents/com.mycron.hourly.plisty luego lo cargué con:

launchctl load ~/Library/LaunchAgents/com.mycron.hourly.plist

Una vez cargado, se ejecutará de inmediato y luego nuevamente cada 60 minutos.

Si sigue el mismo procedimiento, querrá cambiar la cadena `ProgramArguments' con la ruta correcta a su script.

De hecho, cron está en desuso al menos en Lion. Felicitaciones por encontrar la respuesta: puede ser difícil acceder a launchctl inicialmente.

Agregar el siguiente código a su script bash Shell solucionará el problema:

declare -x SSH_AUTH_SOCK=$( find /tmp/launch-*/Listeners -user your_user -type s | head -1 )

Reemplácelo your_usercon su propio nombre de usuario.

Este código establece el valor correcto para SSH_AUTH_SOCKesa información ssho scpsobre cómo comunicarse ssh-agentcuando se inicia el script de shell desde cron.

Esto resolvió el problema que tenía donde scp no funcionaba a través de launchd en un script de shell a pesar de que funcionaba bien a través de la línea de comando normal (iTerm o Terminal). Excelente consejo.
Solo para que conste, en El Capitán 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners

Esperaría que la seguridad mejorada como sandbox y los cambios para mover aún más las cosas a 64 bits estén causando problemas inesperados.

No es una respuesta per se, pero launchd está recibiendo todo el amor de Apple en estos días.

No soluciona el problema de cron, pero es más estable y más personas pueden ayudar con él.

Muy buena respuesta allí . Gracias por publicarlo.

Para cualquiera que encuentre esto ahora, que intente hacer que esto funcione en El Capitán, y aún sea reacio a convertir su trabajo cron de una línea en un script de inicio, la respuesta de Werner Antweiler aún funciona, pero el camino cambió. Lo siguiente funcionó para mí:

declare -x SSH_AUTH_SOCK=$(find /var/folders/*/*/*/*/agent.* -user your_user -type s | head -1)

NOTA : ¡recuerde reemplazar your_user con su nombre de usuario!

No me permitiría enviar esto como un comentario sobre su respuesta porque carezco de reputación, pero no quería dejarla sin actualizar esto, ya que definitivamente me ayudó a configurarlo finalmente.

Edición: 30 de marzo de 2016

Después de probar esto por un tiempo, debo agregar que esto solo funciona una vez que el agente se ha utilizado al menos una vez durante ese inicio de sesión. Iniciar una conexión ssh o ejecutar manualmente ssh-agent es suficiente para hacerlo. También se puede usar un script de inicio si desea que se ejecute automáticamente. Creé un startup.sh que solo ejecuta ssh-agent y luego usé Script Editor para guardar un .app con lo siguiente y agregué la aplicación resultante a mis elementos de inicio de sesión:

do shell script "/path/to/startup.sh"
Estoy resolviendo esto ahora mismo, y esta no es la mejor manera. launchd aparentemente es el camino a seguir, pero para cron, desea configurar su clave ssh (con frase de contraseña) en su llavero. Una vez que haya hecho eso, simplemente inicie sesión en la Mac para configurar todo. La ruta del socket que publicó es donde se guardan si USTED ejecuta ssh-agent manualmente (y escribe su frase de contraseña manualmente). En El Cap, una vez que se cargue el llavero, busque el zócalo a través de ls /private/tmp/com.apple.launchd.*/Listeners. No tienes que hacer nada excepto iniciar sesión en mac.
launchd definitivamente es la forma "oficial" de hacerlo, pero para aquellos que quieren seguir usando cron, esto sirve como una solución viable. En mis pruebas, simplemente iniciar sesión no fue suficiente para que una clave guardada en el llavero funcionara a través de cron. Sin embargo, la ruta que enumeraste definitivamente existe. Si eso se genera tan pronto como inicia sesión y aún funciona para cron, es probable que sea suficiente para poder omitir el método de secuencia de comandos de inicio que enumeré. Ciertamente vale la pena probarlo al menos, ¡gracias!
Instalé esto para un proceso de copia de seguridad, y ha estado funcionando sin problemas, entre reinicios, durante más de una semana.