2010-01-04 1 views
25

Ich habe eine small bash script geschrieben, die einen SSH-Tunnel benötigt Daten von einem entfernten Server zu ziehen, so dass es fordert den Benutzer:ssh: überprüfen, ob ein Tunnel am Leben ist

echo "Please open an ssh tunnel using 'ssh -L 6000:localhost:5432 example.com'" 

Ich möchte, ob der Benutzer überprüfen hatte diesen Tunnel geöffnet und mit einer Fehlermeldung beendet, wenn kein Tunnel existiert. Gibt es eine Möglichkeit, den SSH-Tunnel abzufragen, d. H. Zu prüfen, ob der lokale Port 6000 wirklich zu diesem Server getunnelt ist?

Danke,

Adam

+0

diese aufgelistet finden könnte teilweise helfen „lsof -i | grep ssh“ – qartal

Antwort

26

Dies ist mein Test. Ich hoffe, es ist nützlich.

# $COMMAND is the command used to create the reverse ssh tunnel 
COMMAND="ssh -p $SSH_PORT -q -N -R $REMOTE_HOST:$REMOTE_HTTP_PORT:localhost:80 [email protected]$REMOTE_HOST" 

# Is the tunnel up? Perform two tests: 

# 1. Check for relevant process ($COMMAND) 
pgrep -f -x "$COMMAND" > /dev/null 2>&1 || $COMMAND 

# 2. Test tunnel by looking at "netstat" output on $REMOTE_HOST 
ssh -p $SSH_PORT [email protected]$REMOTE_HOST netstat -an | egrep "tcp.*:$REMOTE_HTTP_PORT.*LISTEN" \ 
    > /dev/null 2>&1 
if [ $? -ne 0 ] ; then 
    pkill -f -x "$COMMAND" 
    $COMMAND 
fi 
+0

Sieht so aus, als ob im obigen Code ein Fehler enthalten ist. wenn [$? -ne 0] sollte die 0 wahrscheinlich eine 1 sein. Der Remote-Egrep setzt $? auf 0, wenn es erfolgreich eine Übereinstimmung findet. In jedem Fall musste ich 1 verwenden, damit dieser Befehl den vorhandenen Tunnel nicht jedes Mal löschte, wenn ich den Befehl ausführte. – user2495504

7

Das ist wirklich eher eine Frage serverfault-Typ, aber Sie können netstat verwenden.

so etwas wie:

# netstat -lpnt | grep 6000 | grep ssh 

Dies wird Ihnen sagen, ob ein SSH-Prozess auf dem angegeben Port hören gibt. es wird Ihnen auch die PID des Prozesses mitteilen.

Wenn Sie wirklich nochmals überprüfen möchten, dass die SSH-Prozess mit den richtigen Optionen gestartet wurde, können Sie dann den Prozess, durch PID nachschlagen in so etwas wie

# ps aux | grep PID 
+2

Beachten Sie, dass diese Lösung funktioniert unter OS X nicht, da sich Netstat unter OS X unterscheidet. – hlin117

5

Verwenden Sie autossh. Es ist das Tool, das für die Überwachung der SSH-Verbindung gedacht ist.

16

autossh ist die beste Wahl - Prüfprozess nicht in allen Fällen funktioniert (zB Zombie-Prozess, netzwerkbezogene Probleme)

Beispiel:

autossh -M 2323 -c arcfour -f -N -L 8088:localhost:80 host2 
25

Netcat ist dein Freund:

nc -z localhost 6000 || echo 'no tunnel open'; exit 1 
+0

Wow, das ist verdammt nützlich.Ich mache ein Skript, das zuerst einen SSH-Tunnel erstellt, und ich benutze jetzt Netcat, um zu wissen, wann es bereit ist, Verbindungen zu akzeptieren. Klappt wunderbar. – Hubro

0
#!/bin/bash 

# Check do we have tunnel to example.com server 
lsof -i [email protected]:6000 > /dev/null 

# If exit code wasn't 0 then tunnel doesn't exist. 
if [ $? -eq 1 ] 
then 
    echo ' > You missing ssh tunnel. Creating one..' 
    ssh -L 6000:localhost:5432 example.com 
fi 

echo ' > DO YOUR STUFF < ' 
0

Diese sind detaillierte Schritte einen SSH-Tunnel zu testen oder zu beheben. Sie können einige von ihnen in einem Skript verwenden. Ich füge diese Antwort hinzu, weil ich die Verbindung zwischen zwei Anwendungen beheben musste, nachdem sie aufgehört haben zu arbeiten. Just grepping für den ssh-Prozess war nicht genug, da es immer noch da war. Und ich konnte nc -z nicht benutzen, weil diese Option auf meiner Beschwörung von netcat nicht verfügbar war.

Beginnen wir von Anfang an. Angenommen, es gibt eine Maschine, die lokal mit der IP-Adresse 10.0.0.1 genannt wird und eine andere, die remote heißt, bei 10.0.3.12. Ich werde diese Hostnamen den unten stehenden Befehlen voranstellen, so dass es offensichtlich ist, wo sie ausgeführt werden.

Ziel ist es, einen Tunnel zu erstellen, der TCP-Datenverkehr von der Loopback-Adresse auf dem Remote-Computer auf Port 123 zum lokalen Computer auf Port 456 weiterleitet.Dies kann mit dem folgenden Befehl ein, auf der lokalen Maschine erfolgen:

local:~# ssh -N -R 123:127.0.0.1:456 10.0.3.12 

Um zu überprüfen, dass der Prozess läuft, können wir tun:

local:~# ps aux | grep ssh 

Wenn Sie den Befehl in der Ausgabe sehen wir kann fortfahren. Überprüfen Sie andernfalls, ob der SSH-Schlüssel in der Fernbedienung installiert ist. Beachten Sie, dass ssh den aktuellen Benutzernamen verwendet, wenn der Benutzername vor der Remote-IP ausgeschlossen wird.

Als nächstes wollen wir prüfen, ob der Tunnel auf der Fernbedienung geöffnet ist:

remote:~# netstat | grep 10.0.0.1 

Wir sollten eine Ausgabe ähnlich wie diese bekommen:

tcp 0 0 10.0.3.12:ssh 10.0.0.1:45988 ESTABLISHED 

Wäre schön, tatsächlich sehen einige Daten gehen von der Remote zum Host. Hier kommt netcat ins Spiel. Auf CentOS kann es mit yum install nc installiert werden.

zunächst ein Listening-Port auf dem lokalen Computer öffnen:

local:~# nc -l 127.0.0.1:456 

Dann eine Verbindung auf der Fernbedienung machen:

remote:~# nc 127.0.0.1 123 

Wenn Sie einen zweiten Anschluss an der lokalen Maschine öffnen, können Sie Siehe die Verbindung. Etwas wie folgt aus:

local:~# netstat | grep 456 
tcp 0 0 localhost.localdom:456 localhost.localdo:33826 ESTABLISHED 
tcp 0 0 localhost.localdo:33826 localhost.localdom:456 ESTABLISHED 

Noch besser ist es, voran gehen und etwas auf der Fernbedienung eingeben:

remote:~# nc 127.0.0.1 8888 
Hallo? 
anyone there? 

Sie sollten auf dem lokalen Terminal dies wird gespiegelt sehen:

local:~# nc -l 127.0.0.1:456 
Hallo? 
anyone there? 

Der Tunnel funktioniert! Aber was ist, wenn Sie eine Anwendung namens Anwendungsname haben, die Port 456 auf dem lokalen Computer abhören soll? Beende nc auf beiden Seiten und führe deine Bewerbung aus. Sie können prüfen, ob sie mit this auf dem richtigen Port lauscht:

local:~# netstat -tulpn | grep LISTEN | grep appname 
tcp 0 0 127.0.0.1:456 0.0.0.0:* LISTEN 2964/appname 

By the way, den gleichen Befehl auf der Fernbedienung ausgeführt wird, sollte sshd auf 127.0.0.1:123 Port lauscht zeigen.

0

Wir überprüfen Befehl ps

# ps -aux | grep ssh 

setzen Sie alle SHH-Dienst ausgeführt wird zeigen, und wir können die Tunneldienst