Wie erstelle ich ein Bash-Skript, um die SSH-Verbindung zu überprüfen?


86

Ich bin gerade dabei, ein Bash-Skript zu erstellen, das sich bei den Remotecomputern anmeldet und private und öffentliche Schlüssel erstellt.

Mein Problem ist, dass die Remote-Maschinen nicht sehr zuverlässig sind und nicht immer in Betrieb sind. Ich benötige ein Bash-Skript, das überprüft, ob die SSH-Verbindung hergestellt ist. Bevor Sie die Schlüssel für die zukünftige Verwendung erstellen.


2
In der Regel ssh-keygenwird ein Schlüsselpaar auf dem lokalen Computer generiert und anschließend ssh-copy-idder öffentliche Schlüssel auf Remotecomputer kopiert. Es scheint, dass Sie die Dinge anders machen. Warum, was ist dein Ziel?
Ephemient

1
Da Sie offensichtlich ändern, wie die Remotecomputer Verbindungen herstellen, sollten Sie mosh bereitstellen . mosh.mit.edu Es ist beabsichtigt, SSH bei instabilen Verbindungen zu ergänzen. Ich habe sehr gute Erfahrungen damit gemacht.
Aeyoun

@ephemient Ich weiß, dass es etwas spät ist, aber es scheint ziemlich einfach zu sein, dass der Schlüssel nicht für den lokalen Computer oder nicht für den lokalen Benutzer war.
Verlassener Wagen

Antworten:


169

Sie können dies mit dem Rückgabewert überprüfen, den ssh Ihnen gibt:

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

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

EDIT: Ein anderer Ansatz wäre die Verwendung von nmap (Sie benötigen keine Schlüssel oder Login-Zeug):

$ 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)

Sie müssen die Nachricht jedoch überprüfen (nmap verwendet den Rückgabewert nicht, um anzuzeigen, ob ein Port gefiltert, geschlossen oder geöffnet wurde).

EDIT2:

Wenn Sie am aktuellen Status des SSH-Ports interessiert sind, können Sie Folgendes ersetzen grep opendurch egrep 'open|closed|filtered':

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

Nur um vollständig zu sein.


Können Sie angeben, welcher Rückkehrcode Erfolg bedeutet und welcher Fehler bei SSH?
Henley Chiu

Sie fragen sich, was passiert, wenn der SSH-Versuch nur dort hängt?
Sibbs Gambling

2
Gute Antwort! Sie erwähnen jedoch nicht, dass der Versuch, sshin einen ausgefallenen Host zu gelangen, erst nach einer Zeitüberschreitung von z. B. 60 Sekunden fehlschlägt - was für einige Verwendungen möglicherweise unerschwinglich ist. Wenn ein Hostname in definiert ist ~/.ssh/config, sshfunktioniert der erste Ansatz, während der zweite nmapWeg mit fehlschlägt Failed to resolve "<hostname>".
SSC

1
Überhaupt keine Erklärung zu den Befehlen ... oder was Sie tatsächlich tun ... was ist das $?? etc
Toskan

Eine noch prägnantere Form von # 1: ssh -q user@downhost exit | echo $? Pipe das Verbindungsergebnis in Echo
Philn5d

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
Einzeilige Ausgabe: (ssh -q -o "BatchMode = yes" -o "ConnectTimeout = 3" user@host.com "echo 2> & 1" && echo SSH_OK || echo SSH_NOK) | Schwanz -n1
Xdg

20

Sie können so etwas verwenden

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

Dies gibt "ok" aus, wenn die SSH-Verbindung in Ordnung ist


14

Wenn Sie die Antwort von @Adrià CidreIhnen ergänzen , können Sie Folgendes tun:

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

Versuchen:

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

1
Ein Problem dieses Ansatzes ist, dass die in ssh_config (dh / etc / ssh / config oder ~ / .ssh / config) definierten Hosts nicht erkannt werden
Ding-Yi Chen

1

Der folgende sshBefehl sollte einen Exit-Code für 0eine erfolgreiche Verbindung und ansonsten einen Wert ungleich Null haben.

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

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

Toll! Ich empfehle außerdem, -o ConnectTimeout = 5 hinzuzufügen, um das Beenden in Fällen zu beschleunigen, in denen der Zielport gefiltert wird.
Daniel

0

Nur für den Fall, dass jemand nur überprüfen möchte, ob Port 22 auf einem Remotecomputer geöffnet ist, ist dieser einfache Befehl netcat hilfreich. Ich habe es benutzt, weil nmap und Telnet für mich nicht verfügbar waren. Darüber hinaus verwendet meine SSH-Konfiguration die Tastaturkennwortauthentifizierung.

Es ist eine Variante der von GUESSWHOz vorgeschlagenen Lösung.

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

0

Wenn Sie überprüfen möchten, ob ein Remote-Ordner vorhanden ist oder ein anderer Dateitest wirklich:

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

Vergessen Sie nicht die Anführungszeichen in "$(ssh ...)".


Dies beantwortet die Frage nicht. Das OP möchte prüfen, ob eine SSH-Verbindung hergestellt werden kann, ohne eine Datei an einem entfernten SSH-Speicherort zu prüfen.
Rakib Fiha

0

So stellen Sie eine Verbindung zu einem Server mit mehreren Schnittstellen her

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

0

Beispiel mit dem BASH 4+ -Skript:

# -- 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

Der obige Link dient zum Erstellen eines Python-Skripts zum Überprüfen der Konnektivität. Sie können eine ähnliche Methode verwenden und Folgendes verwenden:

ping -w 1 -c 1 "IP Address" 

Befehl zum Erstellen eines Bash-Skripts.


2
Dadurch wird nur die Remote-IP gepingt. Garantiert nicht, ob eine SSH-Verbindung möglich ist.
RJ

Vielen Dank für den Hinweis, hier ist der Code für ssh xlinu.blogspot.com/2019/09/… export user = "Benutzername" export pass = "Passwort" export i = "Hostname" export SSHPASS = $ pass sshpass -e ssh $ Benutzer @ $ i -q "Echo $ i ist zugänglich"
Dheeraj Kumar

-7

Ich habe das Gefühl, Sie versuchen hier das falsche Problem zu lösen. Sollten Sie nicht versuchen, die SSH-Dämonen stabiler zu machen? Versuchen Sie, so etwas wie monit auszuführen , um zu überprüfen, ob der Dämon ausgeführt wird, und starten Sie ihn neu, wenn dies nicht der Fall ist (damit Sie Zeit haben, das Grundproblem hinter dem Herunterfahren von sshd zu finden). Oder ist der Netzwerkdienst problematisch? Versuchen Sie es anzuschauen man ifup. Mag das ganze verdammte Ding dich nur abschalten? Nun, das ist ein größeres Problem ... Sehen Sie sich Ihre Protokolle an (beginnen Sie mit Syslog), um Hardwarefehler oder Dienste zu finden, die Ihre Box herunterfahren (möglicherweise einen Temperaturmonitor?).

Es ist großartig, Ihre Skripte fehlertolerant zu machen, aber Sie möchten möglicherweise auch Ihre Boxen fehlertolerant machen.


3
Sam: Es gibt gültige Anwendungsfälle, in denen das Skript dies überprüft. ZB (wie ich): Ich habe einen Cron-Job auf meinem Computer, um meine Daten über rsync auf meinem Heim-Nas zu sichern. Jetzt bin ich draußen oder sogar ziemlich oft getrennt und muss neu planen, wenn die Verbindung nicht verfügbar war. Mein Boxen läuft ganz gut, aber wie heißt es so schön: Es ist immer das Kabel (auch bekannt als Netzwerk)
Stwissel
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.