¿Cómo solicitar una frase de contraseña de clave SSH una vez y solo cuando sea necesario?

15

(He leído muchas de las preguntas en este sitio que parecen relacionadas y creo que esta es una pregunta realmente nueva).

Tengo muchas claves en muchos servidores y todas están protegidas con frases de contraseña.

Me gusta ingresar frases de contraseña tanto como me gusta ingresar contraseñas: es una verdadera pérdida de productividad.

  • Los comandos ssh-agent + ssh-add se pueden usar en un shell de inicio de sesión para significar que solo tiene que ingresar su frase de contraseña una vez al iniciar sesión

  • El llavero se puede usar para mantener vivo un agente ssh más allá del cierre de sesión, por ejemplo, puede tenerlo para que solo tenga que ingresar la frase de contraseña una vez en el arranque, o puede hacer que lo mantenga vivo durante una hora más o menos.

El problema que tengo es que estas dos soluciones generalmente se inician en un inicio de sesión de shell (por ejemplo .zshrc), confían en que ingrese mi frase de contraseña cuando inicie sesión, incluso si no voy a necesitar que se desbloquee. (No estoy contento con el llavero que mantiene vivo a un agente indefinidamente).

Lo que me gustaría es que se me solicite una frase de contraseña (para un agente) solo cuando sea necesario .

Entonces puedo iniciar sesión en el servidor A, hacer algunas cosas, luego enviar ssh al servidor B y en ese momento se me pedirá la frase de contraseña. Haga algunas cosas en el servidor B, cierre la sesión. De vuelta en A, haga algunas cosas más, vuelva a enviar ssh a B y no necesite mi frase de contraseña (está en manos de un agente).

Observo que esto es posible en escritorios gráficos como Gnome: aparece una ventana emergente que solicita la frase de contraseña para desbloquear su clave privada tan pronto como intenta ssh. Entonces esto es lo que busco, pero desde una consola.

artfulrobot
fuente
¿Por qué no solo generar claves ssh sin frases de contraseña? Si vas a pasar por todos estos problemas de todos modos?
devnull
1
Si alguien ingresa y hay claves sin contraseña (o un agente ssh activo), también pueden tener acceso a muchos otros servidores. Además, las claves sin contraseña pueden ser robadas y utilizadas en otros lugares.
artfulrobot
Hasta donde yo sé, no hay forma de hacer lo que quieres sin sacrificar algún nivel de seguridad, lo que parece que no quieres hacer. Aquí hubo una respuesta profunda de Thomas Nyman que entra en muchas posibilidades si aún no la ha leído: unix.stackexchange.com/a/90869/82289 . Me soluciono esto en mi empresa mediante el uso de un servidor intermedio que gestiona sesiones ssh con Tmux.
devnull
@DevNull parece extraño que puedas hacerlo con un escritorio pero no con una terminal, ¿no? ¿Seguramente solo necesita que el agente salte al tty si no se han agregado claves? ¿Esta debe ser la forma en que funcionan los gui?
artfulrobot
Puede consultar mi respuesta aquí: unix.stackexchange.com/a/184160/89706 (Enlace de la pregunta: unix.stackexchange.com/questions/90853/… )
Johnny Wong

Respuestas:

16

No agregue nada a ninguno de sus scripts de inicio de shell, esto es piratería innecesaria.

En cambio, agregue

AddKeysToAgent yes

a su .ssh / config

De esta manera, ssh-add se ejecuta automáticamente la primera vez que ssh en otro cuadro. Solo tiene que volver a ingresar su clave cuando caduque de ssh-agent o después de reiniciar.

Toby
fuente
Desearía que la gente comentara cuando rechaza la votación Si no está bien, es importante, sabemos por qué no está bien. Gracias por publicar, no he tenido tiempo de probar tu sugerencia.
artfulrobot
También me preguntaba, ¿tal vez por mis publicaciones cruzadas?
Toby
Esto funciona para mi. Sin embargo, es una adición muy reciente a openssh (7.2). En caso de que ayude a alguien, openssh 7.3 está disponible en Debian Sid.
artfulrobot el
@artfulrobot: Extraño, ya que tuve este mismo comportamiento (auto-ssh-add en la primera llamada de ssh) trabajando durante años, hasta que finalmente se detuvo hace algún tiempo. Buscando la causa, encontré AddKeysToAgent y asumí que la razón por la que se detuvo fue que, por accidente, debí haber limpiado mi .ssh / config y AddKeysToAgent junto con él. Ahora me pregunto por qué funcionaba mucho antes de que se lanzara OpenSSH 7.2. No me estoy imaginando esto :-)
Toby
@Toby esto es exactamente lo que necesito. Desafortunadamente, ssh-agent no parece iniciarse automáticamente en kubuntu, así que eso es lo siguiente que necesito resolver.
Ogaday
7

Zsh tiene unpreexec gancho que ejecuta una función antes de ejecutar un comando ingresado en la línea de comando. Aquí hay un gancho que busca sshen su línea de comando y, si lo encuentra, verifica la existencia de un agente ssh. Si eso no se encuentra, ejecuta keychain.

De esta manera, el llavero solo se ejecuta antes de los comandos ssh, y luego solo si es necesario.

Pon esto en tu ~/.zshrc:

function check_ssh {
  [[ $3 =~ '\bssh\b' ]] || return
  [[ -n "$SSH_AGENT_PID" && -e "/proc/$SSH_AGENT_PID" ]] \
    && ssh-add -l >/dev/null && return
  eval `keychain --eval id_dsa --timeout 60`
}    
autoload -U add-zsh-hook
add-zsh-hook preexec check_ssh

Lo que sucede aquí es que cada vez que se escribe un comando, check_sshse llama antes de que se ejecute el comando.

La primera línea de la función verifica el comando expandido para sshusar una expresión regular Zsh. sshdebe tener límites de palabras a \bambos lados. Si esto no se encuentra, la función vuelve.

La siguiente línea verifica que hay un proceso de agente SSH en la variable de entorno, y que ese proceso todavía existe en la tabla de procesos, y que al menos una clave se ha agregado al agente. Si todo eso está bien, entonces el agente ssh está configurado y no necesitamos hacer nada, por lo que regresa.

Finalmente comenzamos el llavero, con el agente que se mantendrá vivo durante una hora.

Todavía deja el problema sobre las cosas ssh incrustadas, como gitor rsynco scpas que no activarán la función (puede agregarlas a la expresión regular).

artfulrobot
fuente
Incluso sin él zsh, se podría crear un script corto con el mismo efecto y colocarlo PATHante el sshcliente real . Incluso podría funcionar con rsyncet al, si leen en PATHlugar de ejecutarse /usr/bin/sshdirectamente.
ilkkachu
2

Para zsh, he escrito un conjunto de utilidades y envoltorios para hacer más o menos lo que quieres: https://www.vinc17.net/unix/index.en.html#zsh-ssh-utils

En realidad, esto hace aún más, porque el ssh-agent que será compartido por todas las sesiones de inicio de sesión (escritorio o mediante SSH, y GNU Screen también es compatible si inicia shells de inicio de sesión desde allí, por ejemplo, shell -zshen el ~/.screenrcarchivo), y se cerrará solo después de La última sesión termina.

Nota: Solo uso una frase de contraseña para todas mis claves. No estoy seguro del comportamiento de diferentes frases de contraseña; Es posible que necesite algunos cambios.

vinc17
fuente
Wow, eso es bastante código. Buen trabajo y gracias por compartir. Creo que necesito algo más simple: SSH es una herramienta básica para mí.
artfulrobot