Come creare uno script bash per controllare la connessione SSH?


90

Sto creando uno script bash che acceda alle macchine remote e crei chiavi private e pubbliche.

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


2
In genere, si esegue ssh-keygenper generare una coppia di chiavi sulla macchina locale, quindi ssh-copy-idper copiare la chiave pubblica su macchine remote. Sembra che tu stia facendo le cose in modo diverso. Perché, qual è il tuo obiettivo?
effimero

1
Dal momento che stai ovviamente cambiando il modo in cui le macchine remote stabiliscono le connessioni, valuta la possibilità di distribuire mosh . mosh.mit.edu Ha lo scopo di integrare SSH su connessioni instabili. Ho ottime esperienze con esso.
Aeyoun

@ephemient So che è un po 'tardi, ma sembra abbastanza semplice che la chiave non fosse per la macchina locale o non per l'utente locale.
Carrello abbandonato

Risposte:


176

Puoi verificarlo con il valore di ritorno che ssh ti dà:

$ ssh -q user@downhost exit
$ echo $?
255

$ ssh -q user@uphost exit
$ echo $?
0

EDIT: un altro approccio sarebbe usare nmap (non avrai bisogno di chiavi o elementi di accesso):

$ 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 dovrai grep il messaggio (nmap non usa il valore di ritorno per mostrare se una porta è stata filtrata, chiusa o aperta).

EDIT2:

Se sei interessato allo stato attuale della porta ssh, puoi sostituire grep opencon egrep 'open|closed|filtered':

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

Solo per essere completo.


1
Per essere completo, puoi indicare quale codice di ritorno significa successo e quale significa fallimento per SSH?
Henley Chiu

Ti chiedi cosa succede se il tentativo SSH si blocca semplicemente lì?
Sibbs Gambling

2
Bella risposta! Tuttavia, non si menziona che il tentativo di sshentrare in un host inattivo fallisce solo dopo un timeout di, ad esempio, 60 secondi, il che potrebbe essere proibitivo per alcuni utilizzi. Inoltre, se un hostname è definito in ~/.ssh/config, il primo sshapproccio funziona mentre il secondo nmapmetodo fallisce con Failed to resolve "<hostname>".
ssc

2
nessuna spiegazione sui comandi ... o su cosa stai effettivamente facendo .. che cos'è $?? ecc
Toskan

Una forma ancora più concisa del n. 1: ssh -q user@downhost exit | echo $?
convoglia

23

Puoi usare qualcosa di simile

$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host echo ok 2>&1)

Questo produrrà "ok" se la connessione ssh è ok


22
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

2
Una riga di output: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" user@host.com "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | tail -n1
Xdg

15

Completando la risposta di @Adrià Cidrete puoi fare:

status=$(ssh -o BatchMode=yes -o ConnectTimeout=5 user@host 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

7

Provare:

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)
Ding-Yi Chen

1

Il sshcomando seguente dovrebbe avere un codice di uscita 0su una connessione riuscita e un valore diverso da zero in caso contrario.

ssh -q -o BatchMode=yes user@remote.com exit

if [ $? != "0" ]; then
    echo "Connection failed"
fi

Grande! Consiglio anche di aggiungere -o ConnectTimeout = 5, per un'uscita più rapida nei casi in cui la porta di destinazione è filtrata.
Daniel

0

Nel caso in cui qualcuno desideri solo controllare se la porta 22 è aperta su una macchina remota, questo semplice comando netcat è utile. L'ho usato perché nmap e telnet non erano disponibili per me. Inoltre, la mia configurazione ssh utilizza l'autenticazione della password della tastiera.

È una variante della soluzione proposta da GUESSWHOz.

nc -q 0 -w 1 "${remote_ip}" 22 < /dev/null &> /dev/null && echo "Port is reachable" || echo "Port is unreachable"

0

Se desideri verificare l'esistenza di una cartella remota o di qualsiasi altro test di file:

if [ -n "$(ssh "${user}@${server}" [ -d "$folder" ] && echo 1; exit)" ]; then
    # exists
else
    # doesn't exist
fi

Non dimenticare le virgolette in "$(ssh ...)".


Questo non risponde alla domanda. L'OP vuole verificare se è possibile stabilire una connessione SSH senza controllare un file in una posizione ssh remota.
Rakib Fiha

0

Per connettersi a un server con più interfacce

ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.61;[ $? = 1 ] || ssh -o ConnectTimeout=1 -q Necktwi@192.168.1.51

0

Esempio di utilizzo dello script BASH 4+:

# -- ip/host and res which is result of nmap (note must have nmap installed)
ip="192.168.0.1"
res=$(nmap ${ip} -PN -p ssh | grep open)

# -- if result contains open, we can reach ssh else assume failure) --
if [[ "${res}" =~ "open" ]] ;then
    echo "It's Open! Let's SSH to it.."
else
    echo "The host ${ip} is not accessible!"
fi

0

https://onpyth.blogspot.com/2019/08/check-ping-connectivity-to-multiple-host.html

Il collegamento sopra serve per creare uno script Python per il controllo della connettività. Puoi utilizzare un metodo simile e utilizzare:

ping -w 1 -c 1 "IP Address" 

Comando per creare script bash.


2
Questo eseguirà solo il ping dell'IP remoto. Non garantisce se la connessione ssh è possibile.
RJ

Grazie per averlo sottolineato, ecco il codice per ssh xlinu.blogspot.com/2019/09/… export user = "username" export pass = "password" export i = "hostname" export SSHPASS = $ pass sshpass -e ssh $ user @ $ i -q "echo $ i is Accessible"
Dheeraj Kumar

-7

Mi sembra che tu stia cercando di risolvere il problema sbagliato qui. Non dovresti provare a rendere i daemon ssh più stabili? Prova a eseguire qualcosa come monit , che controllerà se il demone è in esecuzione e lo riavvierà se non lo è (dandoti il ​​tempo di trovare il problema alla radice dietro l'arresto di sshd su di te). O il servizio di rete è fastidioso? Prova a guardare man ifup. A Whole Damn Thing piace semplicemente spegnerti? Bene, questo è un problema più grande ... prova a guardare i tuoi log (inizia con syslog) per trovare guasti hardware o servizi che stanno spegnendo il tuo boxen (forse un monitor della temperatura?).

Rendere i tuoi script a tolleranza di errore è fantastico, ma potresti anche voler rendere i tuoi boxen a tolleranza di errore.


4
Sam: ci sono casi d'uso validi per fare in modo che lo script lo controlli. Ad esempio (come me): ho un cron job in esecuzione sulla mia macchina per eseguire il backup dei miei dati tramite rsync sul mio nas di casa. Ora sono fuori o addirittura disconnesso abbastanza spesso e devo riprogrammare se la connessione non era disponibile. Il mio boxen gira abbastanza bene, ma come si suol dire: è sempre il cavo (aka network)
stwissel
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.