Posso ottenere SSH per utilizzare un programma askpass anche se è stato eseguito da un terminale?


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.

Vorrei che SSH usasse un programma askpass anche se fosse stato eseguito da un terminale.

A volte, devo collegarmi ai server, dove c'è qualche ritardo nel mostrare una richiesta di password (forse a causa di problemi di rete, forse a causa di tentativi di ricerca DNS inversa, ...). Mi infastidisco e passo a qualcos'altro e dimentico il tentativo di connessione. (Inserisci una battuta sull'intervallo di attenzione di un pesce rosso.) Quando finalmente torno ad esso, il prompt è scaduto e anche una password corretta si tradurrebbe in una connessione chiusa.

Le chiavi sarebbero una soluzione, ma non tutti i sistemi che uso hanno le mie solite chiavi SSH. Tuttavia, di solito utilizzo i sistemi Ubuntu e Ubuntu ha un programma askpass SSH installato per impostazione predefinita.

Se si aprisse una finestra askpass, ne sarei immediatamente consapevole. È un compromesso abbastanza buono per me, se solo riesco a farlo funzionare.


Buona domanda. Guardando il codice sorgente, non sembra. Dovresti indurlo a non aprire /dev/tty( LD_PRELOAD?).
Celada,

@Celada ciò causerebbe problemi all'avvio della shell?
Muru,

Probabilmente no ...
Celada,

Risposte:


7

Questo sarà un po 'più complicato, ma la combinazione di più pezzi lo farà funzionare:

Spiegazione

  1. Per forzare sshl'uso del $SSH_ASKPASSprogramma, non puoi permettere sshdi vedere il reale tty. È solo condizione. Questo può essere fatto usando setside usando -nswitch to ssh.

    Questo caso avvierebbe la connessione, ma non saresti in grado di interagire con la shell, che è probabilmente anche il tuo requisito;) (e rompe anche il tuo TTY locale).

    Ma puoi rinunciare alla "prima sessione". Dovresti anche aggiungere -Nswitch, che sopprimerà il comando remoto e farà solo l'autenticazione .

    Anche l'eventuale output "junk" può essere reindirizzato &> /dev/nullse non ti interessa.

  2. Impostare ControlMasterin ssh_config. È una funzionalità interessante e una volta stabilita la connessione, puoi "accendere" le sessioni abbastanza velocemente. Questo frammento ~/.ssh/configdovrebbe:

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

    Puoi aggiungerlo in un hostblocco che elenca i tuoi "candidati lenti", o semplicemente ovunque. Non è quasi nessun sovraccarico.

Linea finale

Quindi dovresti essere in grado di connetterti in questo modo all'host che prevedi ci vorrà del tempo:

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

L'intero processo potrebbe essere semplificato aliaso bash facendo entrambe le cose in un solo passaggio, ma è lasciato all'immaginazione dei lettori.

Solo argomenti da riga di comando

Puoi unire entrambe le cose insieme dalla riga di comando senza 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 seguente funzione dovrebbe funzionare quando non vengono specificate le opzioni SSH:

ssh() {
    if ! command ssh -o PasswordAuthentication=no "$1" true
    then
        setsid -w ssh -fnN "$1"
    fi
    command ssh "$@"
}
  • -f indica a SSH di passare in background subito prima dell'esecuzione del programma, ovvero dopo che ha ottenuto la password.
  • -wdice setsiddi aspettare che il programma finisca. In questo caso, ciò accade quando SSH passa in background. In combinazione con ssh -f, l'attesa manuale tra i due comandi SSH può essere eliminata.
  • La funzione presuppone che il primo argomento sia il nome host.
  • Il test è solo per prevenire connessioni SSH non necessarie.

ControlMasterè già configurato, proprio perché inserire tali password in tali casi è una vera seccatura. Non dovrebbe essere difficile scrivere una funzione che testa un master esistente e usa askpass se non riesce a trovarne uno. Grazie!
muru,

3

A per manuale SSH ( man ssh):

Se sshnon ha un terminale associato ma sono impostati DISPLAY e SSH_ASKPASS, eseguirà il programma specificato da SSH_ASKPASS.

Pertanto è necessario dissociare il terminale (ad esempio aggiungendo una pipe) e assicurarsi che DISPLAYnon sia impostato (se si desidera utilizzare invece il terminale per la passphrase).

Esempio semplice:

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

Lo stesso con ssh-add:

$ echo foo | SSH_ASKPASS=/my/cmd DISPLAY= ssh-add id_rsa
ssh_askpass: exec(/my/cmd): No such file or directory

Purtroppo questo non funziona per me. Dice Pseudo-terminal will not be allocated because stdin is not a terminal, quindi sembra che la pipa stia facendo qualcosa. ssh </dev/nullebbe lo stesso effetto. Tuttavia, in entrambi i casi richiede ancora una password e posso ancora digitarne una. Ho provato su Linux e Mac. Ho provato ssh -vvvma non dice nulla di utile.
Timmmm,

1
SSH_ASKPASS=/foo DISPLAY= setsid ssh hostfunziona però.
Timmmm,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.