Ejecutar ssh-agent desde un script de shell

19

Estoy tratando de crear un script de shell que, entre otras cosas, inicie ssh-agent y agregue una clave privada al agente. Ejemplo:

#!/bin/bash
# ...
ssh-agent $SHELL
ssh-add /path/to/key
# ...

El problema con esto es que ssh-agent aparentemente inicia otra instancia de $ SHELL (en mi caso, bash) y desde la perspectiva del script se ejecuta todo y ssh-add y todo lo que está debajo nunca se ejecuta.

¿Cómo puedo ejecutar ssh-agent desde mi script de shell y mantenerlo en movimiento en la lista de comandos?

Dan
fuente

Respuestas:

8

Se supone que ssh-agent inicia una sesión y cuando finaliza la sesión del usuario termina. Entonces, cualquier comando después de ssh-agent quizás se ejecute después de cerrar sesión.

Lo que quieres es un session-scriptque contenga tus comandos de sesión como este:

#!/bin/bash
ssh-add /path/to/key
bash -i # or other session starter

Entonces comienza ssh-agent session-script.

Michael Suelmann
fuente
¡Gracias! Crear un guión separado y terminar el guión con exithizo el truco.
Dan
2
¿Qué es un script de sesión?
Alexander Mills
15

Ponga lo siguiente en la parte superior de su script:

eval `ssh-agent`

Su script debería verse así:

#!/bin/bash
eval `ssh-agent`
ssh-add /path/to/key
...
...

Explicación

Los backticks alrededor ssh-agentrecogen su salida. evalrecopila esa salida, la concatena en un solo comando y luego ejecuta el comando. Luego puede usar ssh-addpara proporcionar sus credenciales clave.

scottyseus
fuente
99
Esto es exactamente lo que necesitaba, gracias, aunque vale la pena señalar que los backticks están saliendo. En la nueva forma de bash, debería sereval $(ssh-agent)
sibaz
Esta solución no funcionó para mí hasta que puse bash -ial final del guión.
Adolfo Correa el
6

Tiendo a hacer algo como esto en los scripts que requieren un agente.

#!/bin/bash

# if we can't find an agent, start one, and restart the script.
if [ -z "$SSH_AUTH_SOCK" ] ; then
  exec ssh-agent bash -c "ssh-add ; $0"
  exit
fi

... and so on.

Básicamente, lo primero que comprueba el script para ver si se está ejecutando un agente. Si no es exec, se utiliza para iniciar un nuevo proceso en lugar del script. Se inicia el agente, se agregan claves y, finalmente, se vuelve a llamar al script (consulte el $0).

Zoredache
fuente
Pero eso no preservará ningún parámetro de script. Y si alguno de los parámetros tiene espacios en blanco, no será fácil pasarlos.
Denilson Sá Maia
3
Puede usar .. "ssh-add ; $0 $*", o en su .. "ssh-add ; $0 $@"lugar, lo que puede funcionar. Lo cual no sería perfecto, pero ciertamente funcionaría en muchos casos. La mejor solución es casi siempre hacer que su agente se ejecute antes que cualquier otra cosa, esto es algo que podría ser útil en casos oscuros.
Zoredache
6

Encontré que esto funciona para mí.

eval `ssh-agent` # create the process
ssh-add ~/.ssh/priv_key # add the key
git -C $repo_dir pull # this line is the reason for the ssh-agent
eval `ssh-agent -k` # kill the process

Creo el proceso ssh-agent, agrego la clave, hago lo que tengo que hacer y luego lo mato. No es necesario verificar si se está ejecutando más tarde.

vapor accionado
fuente
4

Es mejor usar llavero en este caso

Debian / Ubuntu:

apt-get install keychain

RHEL / Fedora / CentOS

yum install keychain

Agregue en su .bashrc lo siguiente:

eval `keychain --eval id_rsa`
ZIADI Mohamed ali
fuente
¿Mejor? ¿Por qué es mejor?
JFlo
@JFlo "Mejor" en eso, guardará las variables env en $ HOME / .keychain / <file>. Ejecutar ese comando nuevamente recogerá un agente ssh existente si aún se está ejecutando. Luego se puede reutilizar entre shells / scripts. En algunos escenarios que no son súper seguros, entonces debes hacer esa llamada. Para mí, es una mejora con respecto a algunos guiones que había escrito para realizar la misma tarea
Scott Carlson el
2

Descubrí que con la solución de Zoredache, la clave estaría disponible para cualquier shell que comparta el mismo agente ssh que el shell que llamó al script. Quería evitar esto en un script que requería acceso de root a una máquina remota, por razones obvias de seguridad.

He encontrado que poner el siguiente shebang en la parte superior del script funciona:

#!/usr/bin/ssh-agent bash

ssh-add /path/to/ssh-key
ssh root@remotehost "remote commands"
Andy Wood
fuente
-2

Lo intenté y la solución que finalmente funcionó fue reemplazar mi frase de contraseña con una cadena vacía.

ssh-keygen -p
Stephan Weinhold
fuente
Esta es una práctica muy insegura. ¿Por qué molestarse en usar ssh? Si no protege su clave privada, bien podría estar hablando en texto claro.
JFlo
@JFlo: no si su sistema cliente es lo suficientemente seguro, que podría ser. Especialmente si usted (puede y hace) agregar ACL, SELinux o similar, lo cual es fácil con un archivo estático pero menos con el socket aleatorio de ssh-agent. Dicho esto, normalmente no lo recomendaría como primera opción.
dave_thompson_085
Si bien ese es un proceso muy útil que proporciona, no creo que responda nada sobre la pregunta del OP.
Alexander Bird