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

12

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 bowdlerizada 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 Llaves de manera que ssh, ssh-agenty ssh-addse les permite leer mi frase de contraseña para mi .ssh/id_dsaarchivo - como resultado que puedo SSH en un terminal sin tener que entrar en mi contraseña.

¿Es este problema el 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 ... que creo que no es necesaria b / c de la configuración de Keychain Access).

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

NOTA 2 - Me doy cuenta de que las claves SSH sin frase de contraseña resolverían mi problema; Sin embargo, preferiría no seguir esta ruta.

John Hart
fuente
2
cron se ha ido. Vea la etiqueta de launchd aquí para obtener todo tipo de ayuda (haga el movimiento, maneja los puertos, el medio ambiente y mucho más, mucho mejor que el cron) - Espero que alguien tenga una solución, pero el cron mojo aquí está envejeciendo con seguridad .
bmike
3
cron todavía corre 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 lamentable. 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 las barbas grises de BSD se reirán. Supongo que para entonces seré una barba gris de BSD ...
John Hart
1
Acabo de cambiar a launchd, funciona de maravilla. El script llamado no necesita interactuar con ssh-agent en absoluto; simplemente puede saltar directamente al comando ssh después del hashbang. Si su comentario fuera una respuesta, lo aceptaría =)
John Hart
JSON ciertamente brilla sobre XML en muchos casos, pero todos los plists que vinieron antes probablemente forzaron el problema. Me hace cosquillas que tengamos un reemplazo unificado, eficiente y estructurado basado en datos. ¡cron y seguro que nos sirvió durante mucho tiempo!
bmike
He estado buscando altos y bajos recursos web adicionales, pero siempre termino en esta publicación. ¿Seguramente alguien tiene más para contribuir 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 expansivo para automatizar básicamente los scripts de shell. Alguien tiene alguna idea nueva?

Respuestas:

10

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 sí soluciona el problema de autorización. Los trabajos iniciados por el usuario (que se ejecutan solo cuando está conectado) usan 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 administració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 ~/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 secuencia de comandos.

John Hart
fuente
2
De hecho, cron está en desuso al menos en Lion. Felicitaciones por encontrar la respuesta: launchctl puede ser difícil de ingresar inicialmente.
zwerdlds
7

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

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

Reemplace 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 cron.

Werner Antweiler
fuente
Esto resolvió el problema que tenía cuando scp no funcionaría 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 regular (iTerm o Terminal). Excelente propina.
TJ Luoma
Solo para que conste, en El Capitán 10.11.2:zsh: no matches found: /tmp/launch-*/Listeners
Ivan Balashov
1

Esperaría una seguridad mejorada como sandbox y los cambios para mover aún más las cosas a 64 bits están causando un dolor inesperado.

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

No está solucionando el problema de cron, pero es más estable y más personas pueden ayudarlo.

bmike
fuente
Muy buena respuesta allí . Gracias por publicarlo.
bmike
1

Para cualquiera que encuentre esto ahora, tratando de hacer que esto funcione en El Capitán, y aún reacio a convertir su trabajo cron de una línea en un script lanzado, la respuesta de Werner Antweiler todavía 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 permitió enviar esto como un comentario sobre su respuesta, ya que me falta la reputación, pero no quería dejarla sin actualizar esto, ya que definitivamente me ayudó a configurarlo.

Editar: 30 de marzo de 2016

Después de probar esto por un tiempo, necesito 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 ssh-agent manualmente es suficiente para hacerlo. Un script de inicio también se puede utilizar 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"
Petie
fuente
Estoy resolviendo esto ahora, y esta no es la mejor manera. Al parecer, launchd es el camino a seguir, pero para cron, desea configurar su clave ssh (con frase de contraseña) en su llavero. Una vez que hayas hecho eso, solo iniciar sesión en Mac configura 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 carga el llavero, busque el zócalo mediante ls /private/tmp/com.apple.launchd.*/Listeners. No tiene que hacer nada excepto iniciar sesión en mac.
Joe
launchd definitivamente es la forma "oficial" de hacerlo, pero para aquellos que desean seguir usando cron, esto sirve como una solución viable. En mis pruebas, simplemente iniciar sesión no fue suficiente para hacer que una clave guardada en un llavero funcione a través de cron. Sin embargo, la ruta que enumeró definitivamente existe. Si se genera tan pronto como inicie sesión y todavía funciona para cron, es probable que sea suficiente para poder omitir el método de script de inicio que enumeré. Ciertamente vale la pena probar al menos, ¡gracias!
Petie
Puse esto en marcha para un proceso de copia de seguridad, y ha estado funcionando de manera limpia, a través de reinicios, durante más de una semana.
Joe