2010-02-05 8 views
26

Escribí un script simple que envía por correo los registros de actividad de svn a nuestros desarrolladores. Hasta ahora, lo había ejecutado en la misma máquina que el repositorio svn, así que no tenía que preocuparme por la autenticación, solo podía usar el estilo de dirección svn file: ///.ssh-agent y crontab: ¿hay una buena manera de que se cumplan?

Ahora estoy ejecutando el script en una computadora hogareña, accediendo a un repositorio remoto, así que tuve que cambiar a svn + ssh: // paths. Con ssh-key muy bien configurado, nunca tengo que ingresar contraseñas para acceder al repositorio svn en circunstancias normales.

Sin embargo, crontab no tuvo acceso a mis ssh-keys/ssh-agent. He leído acerca de este problema un par de lugares en la web, y también es aludido aquí, sin resolución:

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

Mi solución fue la de añadir esto a la parte superior de la secuencia de comandos:

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

Parece que esto funciona en MacOSX 10.6.

Mi pregunta es, ¿qué tan terrible es esto, y hay una manera mejor?

Respuesta

21

Cuando ejecuta ssh-agent -s, inicia un proceso en segundo plano que deberá eliminar más adelante. Por lo tanto, el mínimo es cambiar su truco para algo como:

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

Sin embargo, no entiendo cómo este truco está trabajando. Simplemente ejecutar un agente sin ejecutar también ssh-add no cargará ninguna clave. Quizás el agente ssh de MacOS se comporte de manera diferente a como dice manual page.

+0

Me sorprendió también, pero creo que la respuesta para eso está aquí: http://serverfault.com/questions/108798/ssh-passphrase-remembered-in-macosx-snow-leopard Supongo que es una combinación de contraseñas almacenadas en el llavero del sistema, y tener ssh-keys agregadas hasta el cierre de sesión del sistema. Pero eso es solo una suposición. ¡Gracias por el consejo sobre matar el proceso de cron ssh-agent! – khedron

+0

Votando porque tenía alrededor de una docena de procesos de ssh-agent ejecutándose en segundo plano, después de mi prueba de anoche. ¡Gracias! – khedron

8

Tuve un problema similar. Mi script (que dependía de las claves ssh) funcionó cuando lo ejecuté manualmente pero falló al ejecutarlo con crontab.

definir manualmente la tecla adecuada con

ssh -i /path/to/key 

no funcionó.

Pero finalmente descubrí que el SSH_AUTH_SOCK estaba vacío cuando el crontab ejecutaba SSH. No estaba muy segura de por qué, pero yo sólo

env | grep SSH 

copiado el valor devuelto y ha añadido esta definición a la cabeza de mi crontab.

SSH_AUTH_SOCK="/tmp/value-you-get-from-above-command" 

que estoy fuera de profundidad en cuanto a lo que está pasando aquí, pero me arregló el problema. El crontab funciona sin problemas ahora.

+0

esto funcionó para mí, gracias! –

+0

¿Is/path/to/key uno con una frase de contraseña vacía? No creo que deba usar un socket de autorización si no requiere una frase de contraseña. –

+1

Tenga en cuenta el '/ tmp' en el cuadro anterior. Esto se refiere a un archivo temporal que se eliminará cuando 'ssh-agent' se cierre o la computadora se apague. – Mikkel

27

Además ...

Si la clave tiene un passhphrase, llavero le pedirá que una vez (válido hasta que se reinicie la máquina o matar al ssh-agent).

¡keychain es lo que necesitas! Simplemente instálalo y agrega el siguiente código en tu.bash_profile:

keychain ~/.ssh/id_dsa 

a fin de utilizar el código de abajo en el script para cargar las variables de entorno ssh-agent:

. ~/.keychain/$HOSTNAME-sh 

Nota: llavero también genera código a csh y conchas de pescado.

respuesta Copiado de https://serverfault.com/questions/92683/execute-rsync-command-over-ssh-with-an-ssh-agent-via-crontab

+2

La página de inicio de keychain me dijo que usara 'keychain --noask --eval id_dsa 'en las secuencias de comandos cron que funcionó para mí, no estoy seguro de qué es lo más preferible. Ver http://www.funtoo.org/Keychain – Zitrax

6

Una manera de recuperar el PID y el zócalo de ejecutar ssh-agent sería.

SSH_AGENT_PID=`pgrep -U $USER ssh-agent` 
for PID in $SSH_AGENT_PID; do 
    let "FPID = $PID - 1" 
    FILE=`find /tmp -path "*ssh*" -type s -iname "agent.$FPID"` 
    export SSH_AGENT_PID="$PID" 
    export SSH_AUTH_SOCK="$FILE" 
done 

Por supuesto, esto presupone que ha instalado pgrep en el sistema y solo hay un ssh-agent en ejecución o en el caso de los múltiples que tomará el que se encuentra pgrep pasado.

4

Mi solución - basado en de PRA - mejoró ligeramente a matar el proceso, incluso en caso de fallo de la escritura:

eval `ssh-agent` 
function cleanup { 
    /bin/kill $SSH_AGENT_PID 
} 
trap cleanup EXIT 
ssh-add 
svn-stuff 

Tenga en cuenta que debo llamar a ssh-add en mi máquina (Scientific Linux 6).

+0

¡Manejo de errores! Idea loca. ;-) Esto parece una buena adición, ¡gracias! – khedron

1

Suponiendo que ya configuró la configuración SSH y que la secuencia de comandos funciona bien desde la terminal, usar el llavero es definitivamente la manera más fácil de garantizar que la secuencia de comandos también funcione bien en crontab.

Dado que el llavero no está incluido en la mayoría de las derivaciones de Unix/Linux, aquí está el procedimiento paso a paso.

1. Descargue el paquete de rpm adecuado según la versión de su sistema operativo de http://pkgs.repoforge.org/keychain/. Ejemplo para CentOS 6:

wget http://pkgs.repoforge.org/keychain/keychain-2.7.0-1.el6.rf.noarch.rpm 

2. instalar el paquete:

sudo rpm -Uvh keychain-2.7.0-1.el6.rf.noarch.rpm 

3. generar archivos de llavero para su clave SSH, que estarán ubicados en el directorio .keychain ~ /. Ejemplo para id_rsa:

keychain ~/.ssh/id_rsa 

4. Añadir la siguiente línea a su script en cualquier lugar antes de que el primer comando que usa la autenticación SSH:

source ~/.keychain/$HOSTNAME-sh 

personalmente trató de evitar el uso de programas adicionales para esto, pero todo lo demás que probé no funcionó. Y esto funcionó bien.

2

Aquí hay una solución que funcionará si no puede usar el llavero y si no puede iniciar un ssh-agent desde su secuencia de comandos (por ejemplo, porque su clave está protegida por contraseña).

Ejecutar una vez:

nohup ssh-agent > .ssh-agent-file & 
. ssh-agent-file 
ssh-add # you'd enter your passphrase here 

En el script se ejecuta desde cron:

# start of script 
. ${HOME}/.ssh-agent-file 
# now your key is available 

Por supuesto, esto permite que cualquiera que pueda leer '~/.ssh-agent-archivo' y el zócalo correspondiente para usar sus credenciales ssh, por lo que debe usarse con precaución en cualquier entorno multiusuario.

+0

Otra alternativa es configurar una clave de contraseña vacía y restringir su aplicabilidad en authorized_keys. –

3

Para configurar procesos automatizados sin hack contraseña/contraseña automatizada, Utilizo un IdentityFile independiente que no tiene frase de contraseña, y restrinjo las entradas de authorized_keys de las máquinas de destino con from = "automated.machine.com" ... etc.

I configurar un host remoteAuto en .ssh/config:

Host remoteAuto 
    HostName remote.machine.edu 
    IdentityFile ~/.ssh/id_localAuto 

y los remote.machine.edu:.ssh/authorized_keys con:

... 
from="192.168.1.777" ssh-rsa ABCDEFGabcdefg.... 
... 

Entonces ssh no necesita la autorización autenticada externamente proporcionada por ssh-agent o keychain.

1

Su solución funciona pero generará un nuevo proceso de agente cada vez como ya se indicó por alguna otra respuesta.

Me enfrenté a problemas similares y encontré este blogpost útil, así como el guión de shell de Wayne Walker mencionado en el blog en github.

¡Buena suerte!

3

Inspirado por algunas de las otras respuestas aquí (en particular de VPK) me ocurrió la siguiente entrada crontab, que no requiere un script externo:

PATH=/usr/bin:/bin:/usr/sbin:/sbin 

* * * * * SSH_AUTH_SOCK=$(lsof -a -p $(pgrep ssh-agent) -U -F n | sed -n 's/^n//p') ssh hostname remote-command-here 
+0

Tuve que agregar '| uniq' antes de 'sed' porque mi sistema estaba reajustando líneas dup por alguna razón –

+0

Tuve que agregar' | ordenar | uniq', ya que las dos líneas duplicadas no eran adyacentes. – thenickdude

Cuestiones relacionadas