¿Puedo hacer que SSH use un programa askpass incluso si se ejecutó desde una terminal?

9

man ssh dice:

SSH_ASKPASS
   If  ssh needs a passphrase, it will read the passphrase from the
   current terminal if it was run from a terminal.  If ssh does not
   have  a  terminal associated with it but DISPLAY and SSH_ASKPASS
   are set, it will execute the program  specified  by  SSH_ASKPASS
   and open an X11 window to read the passphrase.

Me gustaría que SSH use un programa askpass incluso si se ejecutó desde una terminal.

En ocasiones, tengo que conectarme a servidores, donde hay algún retraso en mostrar una solicitud de contraseña (tal vez debido a problemas de red, tal vez debido a intentos de búsqueda inversa de DNS, ...). Me molesto, cambio a otra cosa y me olvido del intento de conexión. (Inserte una broma sobre la capacidad de atención de un pez dorado). Cuando finalmente vuelvo a él, el aviso expiró e incluso una contraseña correcta solo resultaría en una conexión cerrada.

Las claves serían una solución, pero no todos los sistemas que uso tienen mis claves SSH habituales. Sin embargo, generalmente uso sistemas Ubuntu, y Ubuntu tiene un programa askpass SSH instalado por defecto.

Sin embargo, si apareciera una ventana askpass, me daría cuenta de inmediato. Es un compromiso lo suficientemente bueno para mí, si tan solo puedo lograr que funcione.

muru
fuente
Buena pregunta. Al mirar el código fuente, no lo parece. Tendrías que engañarlo para que no se abra /dev/tty( LD_PRELOAD?).
Celada
@Celada, ¿eso causaría problemas al iniciar el shell?
Muru
Probablemente no ...
Celada

Respuestas:

7

Esto será un poco más complicado, pero la combinación de varias piezas lo hará funcionar:

Explicación

  1. Para forzar el sshuso del $SSH_ASKPASSprograma, no puede permitir sshver lo real tty. Es solo condición. Esto se puede hacer usando setsidy usando -nswitch to ssh.

    Este caso iniciaría la conexión, pero no podría interactuar con el shell, que probablemente también sea su requisito;) (y también interrumpe su TTY local).

    Pero puedes renunciar a la "primera sesión". También debe agregar el -Ninterruptor, que suprimirá el comando remoto y solo realizará la autenticación .

    También se puede redirigir la posible salida "basura" &> /dev/nullsi no está interesado en ella.

  2. Configurar ControlMasteren ssh_config. Es una característica genial y una vez que se establece la conexión, puede "iniciar" las sesiones bastante rápido. Este fragmento ~/.ssh/configdebe hacer eso:

    ControlPath ~/.ssh/controlmasters/%r@%h:%p
    ControlMaster auto
    ControlPersist 5m
    

    Puede agregar eso en algún hostbloque que enumere sus "candidatos lentos", o simplemente en todas partes. Casi no hay gastos generales.

Línea final

Entonces debería poder conectarse de esta manera al host que espera que tarde un tiempo:

setsid ssh -nN host
# wait, insert password in the X11 prompt
ssh host
# will bring you directly to your session

Todo el proceso puede simplificarse mediante la aliasfunción bash haciendo ambas cosas en un solo paso, pero queda en la imaginación del lector.

Solo argumentos de línea de comando

Puede unir ambas cosas en la línea de comandos sin ssh_configparte:

setsid ssh -nNMS ~/.ssh/masters/%C host
# wait, insert password in the X11 prompt
ssh -S ~/.ssh/masters/%C host
# will bring you directly to your session

La siguiente función debería funcionar cuando no se especifican las opciones SSH:

ssh() {
    if ! command ssh -o PasswordAuthentication=no "$1" true
    then
        setsid -w ssh -fnN "$1"
    fi
    command ssh "$@"
}
  • -f le indica a SSH que vaya al fondo justo antes de la ejecución del programa, que es después de obtener la contraseña
  • -wle dice setsidque espere a que termine el programa. En este caso, eso sucede cuando SSH pasa a un segundo plano. En combinación con ssh -f, se puede eliminar la espera manual entre los dos comandos SSH.
  • La función asume que el primer argumento es el nombre de host.
  • La prueba es solo para evitar conexiones SSH innecesarias.
Jakuje
fuente
ControlMasterya está configurado, precisamente porque es muy difícil ingresar contraseñas en tales casos. No debería ser difícil escribir una función que pruebe un maestro existente y use el askpass si no puede encontrar uno. ¡Gracias!
muru
3

A por manual SSH ( man ssh):

Si sshno tiene un terminal asociado, pero DISPLAY y SSH_ASKPASS están configurados, ejecutará el programa especificado por SSH_ASKPASS.

Por lo tanto, debe desasociar el terminal (por ejemplo, agregando una tubería) y asegurarse de que DISPLAYno esté configurado (si desea usar el terminal para su frase de contraseña).

Ejemplo simple:

echo foo | SSH_ASKPASS=/my/cmd DISPLAY= ssh ...

Lo mismo con ssh-add:

$ echo foo | SSH_ASKPASS=/my/cmd DISPLAY= ssh-add id_rsa
ssh_askpass: exec(/my/cmd): No such file or directory
kenorb
fuente
Lamentablemente esto no funciona para mí. Sí dice Pseudo-terminal will not be allocated because stdin is not a terminal, por lo que parece que la tubería está haciendo algo. ssh </dev/nulltuvo el mismo efecto. Sin embargo, en ambos casos todavía pide una contraseña, y todavía puedo escribir una. Intenté en Linux y Mac. Lo intenté ssh -vvvpero no dice nada útil.
Timmmm
1
SSH_ASKPASS=/foo DISPLAY= setsid ssh hostfunciona sin embargo.
Timmmm