¿Cómo hacer que ssh-agent agregue automáticamente la clave a pedido?

51

Quiero ejecutar ssh-agent (con la opción de duración máxima), pero no agregar ninguna clave al inicio, sino agregarlas a pedido.

Como la primera vez que inicio sesión en algún servidor, debería pedir una frase de contraseña, la próxima vez (a menos que haya esperado más de una hora) debería conectarse limpiamente:

ssh server1
Enter passphrase for key '/home/vi/.ssh/id_dsa':
server1> ...

ssh server2
server2> # no passphrase this time

# wait for lifetime

ssh server2
Enter passphrase for key '/home/vi/.ssh/id_dsa':

No quiero recordar manualmente acerca de ejecutar 'ssh-add' cada vez. (por ejemplo, ingresó la frase de contraseña solo para ssh y "Oh, no lo ha recordado, necesita volver a escribir").

¿Cómo configurar ssh para agregar automáticamente la clave a ssh-agent si el usuario proporcionó la frase de contraseña?

Vi.
fuente

Respuestas:

58

ssh admite agregar una clave al agente en el primer uso (desde la versión 7.2). Puede habilitar esa función poniendo lo siguiente en ~/.ssh/config:

AddKeysToAgent yes

Esto también funciona cuando se usan herramientas derivadas, como git.

Desde el registro de cambios 7.2 :

  • ssh (1): agrega una opción de cliente AddKeysToAgent que se puede establecer en 'sí', 'no', 'preguntar' o 'confirmar', y el valor predeterminado es 'no'. Cuando está habilitado, una clave privada que se usa durante la autenticación se agregará a ssh-agent si se está ejecutando (con la confirmación habilitada si se establece en 'confirmar').
spheenik
fuente
Esto requiere que se esté ejecutando un agente ssh. Consulte stackoverflow.com/a/24347344/4573065 + sus comentarios para ver una buena manera de iniciarlo (solo una vez).
ST-DDT
18

Podrías hacer trampa y poner algo como alias ssh='ssh-add -l || ssh-add && ssh'en tu .bashrc/ .profile. Este primero se ejecuta ssh-add -l, que puede devolver 0 (hay claves en el agente), 1 (sin claves) o 2 (sin agente en ejecución); si devuelve 0, sshse ejecutará; si 1, ssh-addcorrerá y luego ssh; si 2, ssh-addfallará y sshno se ejecutará. Reemplace &&con ;si desea sshejecutar incluso cuando no hay ningún agente ejecutándose.

Jessidhia
fuente
3
Solicitará una frase de contraseña a la clave incluso cuando el comando ssh adicional no la use.
Vi.
@Vi. cierto, pero son raros los comandos que no los usan (a menos que se esté conectando a un servidor que usa teclado interactivo). Sin embargo, la clave estará en el agente cada vez que la necesite. Además, el alias afortunadamente (o desafortunadamente) no cambia los usos backend de ssh (como con git o rsync).
Jessidhia
2
(pensando en escribir el parche auto-call-ssh-add para el cliente ssh)
Vi.
Sobre la base de esta respuesta se puede crear un alias para un anfitriones específicos: alias ssh-hostname='(ssh-add -l | grep hostname > /dev/null) || ssh-add ~/.ssh/id_rsa_hostname && ssh -p 12345 username@hostname'. Incluso podría poner eso en un bucle para todas sus claves ssh y generar alias. Un truco sucio, pero funciona.
dset0x
5

Hasta que ssh admita auto-call-ssh-add, agregué esto en mi .bashrc, según la propuesta de Kovensky:

ssh-add -l >/dev/null || alias ssh='ssh-add -l >/dev/null || ssh-add && unalias ssh; ssh'

El alias se crea solo si no se agrega la identidad, y el alias se destruye a sí mismo una vez que se ejecuta.

De esta manera, el comando ssh normal se usa después de agregar la identidad.

Marc MAURICE
fuente
No funcionará en mi caso porque ssh-add también tiene un tiempo de espera configurado, pero la idea es lo suficientemente buena.
Vi.
@Vi. ¿Cómo afectaría un tiempo de espera a esto? Parece que funciona muy bien para mí.
Lanrat
1
@lanrat, comprueba si la clave está presente en ssh-agent y configura el alias en función de la presencia. Pero debido al tiempo de espera ( ssh-add -t ...), la clave agregada a ssh-agent puede desaparecer abruptamente, pero el alias se mantendrá ya que la clave todavía está en la memoria.
Vi.
1

Estoy usando la siguiente función de shell:

ssh() {
    local possible_keys=($(/usr/bin/env ssh -G $@ | grep '^identityfile' \
                           | cut -d " " -f 2- | sed -e "s|^~|$HOME|"))
    for k in $possible_keys; do
        if [[ -f $k ]]; then
            local fingerprint=$(ssh-keygen -lf $k)
            ssh-add -l | grep -q "$fingerprint" || ssh-add $k
        fi
    done
    /usr/bin/env ssh $@
    return $?
}

Primero resuelve la configuración del host al que estoy tratando de conectarme, luego agrega posibles claves para ese host al agente ssh si aún no se han agregado y finalmente se conecta al host. Estoy seguro de que se puede mejorar, así que estoy abierto a recibir comentarios.

mbrgm
fuente