Comment créer un script bash pour vérifier la connexion SSH?

86

Je suis en train de créer un script bash qui se connecterait aux machines distantes et créerait des clés privées et publiques.

Mon problème est que les machines distantes ne sont pas très fiables et qu'elles ne sont pas toujours opérationnelles. J'ai besoin d'un script bash qui vérifierait si la connexion SSH est en place. Avant de créer les clés pour une utilisation future.

chutsu
la source
2
Typiquement, on s'exécute ssh-keygenpour générer une paire de clés sur la machine locale, puis ssh-copy-idpour copier la clé publique sur des machines distantes. Il semble que vous faites les choses différemment. Pourquoi, quel est votre objectif?
éphémère
1
Puisque vous changez évidemment la façon dont les machines distantes établissent les connexions, envisagez de déployer mosh . mosh.mit.edu Il est destiné à compléter SSH sur les connexions instables. J'ai de très bonnes expériences avec ça.
Aeyoun
@ephemient Je sais que c'est un peu tard, mais il semble assez simple que la clé ne soit pas pour la machine locale ou pas pour l'utilisateur local.
Panier abandonné

Réponses:

170

Vous pouvez vérifier cela avec la valeur de retour que ssh vous donne:

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

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

EDIT: Une autre approche serait d'utiliser nmap (vous n'aurez pas besoin d'avoir de clés ou de 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)

Mais vous devrez grep le message (nmap n'utilise pas la valeur de retour pour montrer si un port a été filtré, fermé ou ouvert).

EDIT2:

Si vous êtes intéressé par l'état réel du port ssh, vous pouvez le remplacer grep openpar egrep 'open|closed|filtered':

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

Juste pour être complet.

Tim Cooper
la source
Pour être complet, pouvez-vous indiquer quel code de retour signifie le succès et lequel signifie l'échec de SSH?
Henley Chiu
Vous vous demandez que se passe-t-il si la tentative SSH se bloque là?
Sibbs Gambling
2
Très bonne réponse! Cependant, vous ne mentionnez pas que la tentative d'accès à sshun hôte en panne échoue uniquement après un délai d'expiration de 60 secondes, par exemple, ce qui peut être prohibitif pour certaines utilisations. De plus, si un nom d'hôte est défini dans ~/.ssh/config, la première sshapproche fonctionne tandis que la seconde nmapéchoue avec Failed to resolve "<hostname>".
ssc
1
aucune explication sur les commandes ... ou ce que vous faites réellement ... qu'est-ce que c'est $?? etc
Toskan
Une forme encore plus concise du n ° 1: ssh -q user@downhost exit | echo $?
transposer
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
Brian Ott
la source
2
Sortie d'une ligne: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" [email protected] "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | tail -n1
Xdg
21

Vous pouvez utiliser quelque chose comme ça

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

Cela affichera "ok" si la connexion ssh est correcte

Adrià Cidre
la source
14

En complément de @Adrià Cidrevotre réponse, vous pouvez faire:

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
iarroyo
la source
7

Essayer:

echo quit | telnet IP 22 2>/dev/null | grep Connected
GUESSWHOz
la source
1
Un problème de cette approche est qu'elle ne reconnaît pas les hôtes définis dans ssh_config (c'est-à-dire / etc / ssh / config ou ~ / .ssh / config)
Ding-Yi Chen
1

La sshcommande ci-dessous doit avoir un code de sortie 0sur une connexion réussie et une valeur différente de zéro dans le cas contraire.

ssh -q -o BatchMode=yes [email protected] exit

if [ $? != "0" ]; then
    echo "Connection failed"
fi
mat
la source
Génial! Je recommande également d'ajouter -o ConnectTimeout = 5, pour une sortie plus rapide dans les cas où le port de destination est filtré.
Daniel
0

Juste au cas où quelqu'un souhaite seulement vérifier si le port 22 est ouvert sur une machine distante, cette simple commande netcat est utile. Je l'ai utilisé car nmap et telnet n'étaient pas disponibles pour moi. De plus, ma configuration ssh utilise l'authentification par mot de passe du clavier.

C'est une variante de la solution proposée par GUESSWHOz.

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

Si vous souhaitez vérifier qu'un dossier distant existe, ou tout autre test de fichier vraiment:

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

N'oubliez pas les guillemets "$(ssh ...)".

Jonathan H
la source
Cela ne répond pas à la question. L'OP veut vérifier si la connexion SSH peut être établie sans vérifier un fichier dans un emplacement ssh distant.
Rakib Fiha
0

Exemple utilisant le 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
Mike Q
la source
0

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

Le lien ci-dessus consiste à créer un script Python pour vérifier la connectivité. Vous pouvez utiliser une méthode similaire et utiliser:

ping -w 1 -c 1 "IP Address" 

Commande pour créer un script bash.

Dheeraj Kumar
la source
2
Cela ne fera qu'un ping sur l'adresse IP distante. Ne garantit pas si la connexion ssh est possible.
RJ
Merci d'avoir signalé cela, voici le code pour 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

J'ai l'impression que vous essayez de résoudre le mauvais problème ici. Ne devriez-vous pas essayer de rendre les démons ssh plus stables? Essayez d'exécuter quelque chose comme monit , qui vérifiera si le démon est en cours d'exécution et le redémarrera si ce n'est pas le cas (vous donnant le temps de trouver le problème racine derrière l'arrêt de sshd). Ou le service réseau est-il gênant? Essayez de regarder man ifup. The Whole Damn Thing aime-t-il juste s'arrêter sur vous? Eh bien, c'est un plus gros problème ... essayez de regarder vos journaux (commencez par syslog) pour trouver des pannes matérielles ou des services qui éteignent votre boîte (peut-être un moniteur de température?).

Rendre vos scripts tolérants aux pannes est génial, mais vous voudrez peut-être aussi rendre votre boxen tolérant aux pannes.

Sam Bisbee
la source
3
Sam: il existe des cas d'utilisation valides pour que le script le vérifie. Par exemple (comme moi): j'ai un travail cron en cours d'exécution sur ma machine pour sauvegarder mes données via rsync sur mon NAS domestique. Maintenant, je suis dehors ou même déconnecté assez souvent et j'ai besoin de replanifier si la connexion n'était pas disponible. Mon boxen fonctionne assez bien, mais comme le dit le dicton: c'est toujours le câble (aka réseau)
Stwissel