2009-09-10 6 views
46

Sono in procinto di creare uno script di bash che consente di accedere alle macchine remote e creare chiavi private e pubbliche.Come creare uno script bash per verificare la connessione SSH?

Il mio problema è che le macchine remote non sono molto affidabili e non sono sempre attive. Ho bisogno di uno script bash che controlli se la connessione SSH è attiva. Prima di creare effettivamente le chiavi per un utilizzo futuro.

+2

In genere, si esegue 'ssh-keygen' per generare una coppia di chiavi sul computer locale, quindi' ssh-copy-id' per copiare la chiave pubblica su macchine remote. Sembra che tu stia facendo le cose in modo diverso. Perché, qual è il tuo obiettivo? – ephemient

+1

Dato che ovviamente stai cambiando il modo in cui i computer remoti stabiliscono connessioni, prendi in considerazione la distribuzione di * mosh *. http://mosh.mit.edu/ È inteso per integrare SSH su connessioni instabili. Ho ottime esperienze con questo. – Aeyoun

risposta

92

È possibile controllare questo con l'ssh ritorno-valore che si dà:

$ ssh -q [email protected] exit 
$ echo $? 
255 

$ ssh -q [email protected] exit 
$ echo $? 
0 

EDIT: Un altro approccio sarebbe quello di utilizzare nmap (non è necessario avere le chiavi o login-stuff):

$ a=`nmap uphost -PN -p ssh | grep open` 
$ b=`nmap downhost -PN -p ssh | grep open` 

$ echo $a 
22/tcp open ssh 
$ echo $b 
(empty string) 

Ma è necessario annullare il messaggio (nmap non utilizza il valore restituito per mostrare se una porta è stata filtrata, chiusa o aperta).

EDIT2:

Se siete interessati nello stato attuale del ssh-porta, è possibile sostituire con grep openegrep 'open|closed|filtered':

$ nmap host -PN -p ssh | egrep 'open|closed|filtered' 

solo per essere completa.

+0

Per essere completo, si può indicare quale codice di ritorno significa successo e che significa guasto a SSH? –

+0

Ti chiedi cosa succede se il tentativo SSH si blocca lì? –

+1

Ottima risposta! Tuttavia, non si menziona che il tentativo di 'ssh' in un host inattivo fallisce solo dopo un timeout di es.60 secondi - che potrebbe essere proibitivo per alcuni usi. Inoltre, se un hostname è definito in '~/.ssh/config', il primo approccio' ssh' funziona mentre il secondo modo 'nmap' fallisce con' Failed to resolve "" '. – ssc

-2

Mi sembra che tu stia cercando di risolvere il problema sbagliato qui. Non dovresti provare a rendere i demoni ssh più stabili? Prova a eseguire qualcosa come monit, che controllerà se il demone è in esecuzione e lo riavvierà se non lo è (dando il tempo di trovare il problema alla radice dietro sshd che si spegne). O il servizio di rete è fastidioso? Prova a guardare man ifup. L'intera dannata cosa ti piace proprio spegnerti? Bene, questo è un problema più grande ... prova a guardare i tuoi registri (inizia con syslog) per trovare guasti hardware o servizi che stanno chiudendo il tuo boxen (forse un monitor della temperatura?).

Rendere gli script tolleranti agli errori è ottimo, ma è anche possibile che si desideri rendere tollerante ai guasti il ​​boxen.

+2

Sam: ci sono casi d'uso validi per avere lo script che lo controlla. E.g (come me): ho un cron job in esecuzione sulla mia macchina per eseguire il backup dei miei dati tramite rsync sul mio home nas. Ora sono fuori o anche disconnesso abbastanza spesso e ho bisogno di riprogrammare se la connessione non fosse disponibile. Il mio boxen funziona abbastanza bene, ma come si suol dire: è sempre il cavo (noto anche come rete) – stwissel

2

Prova:

echo quit | telnet IP 22 2>/dev/null | grep Connected 
+1

Un problema di questo approccio è che non riconosce gli host definiti in ssh_config (cioè/etc/ssh/config o ~/.ssh/config) –

16
ssh -q -o "BatchMode=yes" -i /home/sicmapp/.ssh/id_rsa <ID>@<Servername>.<domain> "echo 2>&1" && echo $host SSH_OK || echo $host SSH_NOK 
+1

Un output di linea: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" [email protected] "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | coda -n1 – Xdg

11

si può usare qualcosa di simile

$(ssh -o BatchMode=yes -o ConnectTimeout=5 [email protected] echo ok 2>&1) 

Questa uscita volontà "ok" se la connessione ssh è ok

4

A complemento della risposta del @Adrià Cidre voi può fare:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 [email protected] echo ok 2>&1) 

if [[ $status == ok ]] ; then 
    echo auth ok, do something 
elif [[ $status == "Permission denied"* ]] ; then 
    echo no_auth 
else 
    echo other_error 
fi