2010-02-10 19 views
98

Auf CYGWIN zu gründen, mag ich einen BASH-Skript:Bash-Skript eines temporärer SSH-Tunnel

  1. einen SSH-Tunnel zu einem Remote-Server erstellen.
  2. Tun Sie etwas Arbeit lokal, die den Tunnel verwendet.
  3. Dann den Tunnel herunterfahren.

Der "Abschaltteil" hat mich verblüfft.

Derzeit habe ich eine lahme Lösung. In einer Shell führe ich Folgendes aus, um einen Tunnel zu erstellen.

# Create the tunnel - this works! It runs forever, until shell is quit. 
ssh -nNT -L 50000:localhost:3306 [email protected] 

Dann in einem anderen Shell-Fenster, mache ich meine Arbeit

# Do some MYSQL stuff over local port 50000 (which goes to remote port 3306) 

Schließlich, wenn ich fertig bin. Ich schließe das erste Shell-Fenster, um den Tunnel zu zerstören.

Ich möchte das alles wie in einem Skript tun: # erstellen Tunnel # arbeiten # Kill-Tunnel

Wie kann ich den Überblick über den Tunnel-Prozess, damit ich weiß, was man zu töten ?

+0

Ich schrieb ein Skript, das helfen würde, SSH-Tunneling zu tun, können Sie es auschecken: https://github.com/gdbtek/ssh-tunneling.git –

Antwort

235

Sie diese mit einem ssh ‚control socket‘ sauber machen kann. Um zu einem bereits laufenden SSH-Prozess zu sprechen und bekommen es pid ist, es töten usw. Verwenden Sie die ‚Steuerbuchse‘ (-M für Master und -S für Sockel) wie folgt:

$ ssh -M -S my-ctrl-socket -fnNT -L 50000:localhost:3306 [email protected] 
$ ssh -S my-ctrl-socket -O check [email protected] 
Master running (pid=3517) 
$ ssh -S my-ctrl-socket -O exit [email protected] 
Exit request sent. 

Beachten Sie, dass my-ctrl -socket wird eine tatsächliche Datei sein, die erstellt wird.

Ich habe diese Informationen von a very RTFM reply on the OpenSSH mailing list.

+5

Dies ist die beste Antwort, die ich bisher zu diesem Thema gesehen habe. Vielen Dank, es sollte akzeptiert werden. Ich verwende dies, um mich mit meiner Vagrant-VM zu verbinden und ein FlywayDB-Update-Skript auszuführen. – Christian

+7

Einfach wunderbar. Danke für das Teilen. +1. – slayedbylucifer

+2

Anscheinend funktionieren Steuerbuchsen nicht überall. Zum Beispiel bekomme ich 'Operation nicht erlaubt 'auf drone.io kontinuierliche Integration Umgebung:' muxserver_listen: Link mux Listener ssh-ctrl-socket.wsASksksgSBlK7kqD => ssh-ctrl-socket: Betrieb nicht erlaubt' –

2

Sie könnten die ssh mit einem & ein Ende starten, um es in den Hintergrund zu stellen und seine ID zu greifen, wenn Sie tun. Dann müssen Sie nur eine kill dieser ID tun, wenn Sie fertig sind.

+0

Seien Sie sich bewusst, wenn Sie das kaufmännische Und ("&") verwenden. Es ist ein hässlicher Ansatz, da Sie die tatsächliche Verbindung für sich selbst bestimmen müssen. Es kann dazu führen, dass weiterer Code ausgeführt wird, der nicht darauf wartet, dass die tatsächliche Verbindung vollständig hergestellt wird. Außerdem wird die Verbindung nicht automatisch abgebrochen, wenn das Skript bricht. –

17
  • Sie ssh in Hintergrund mit & und nicht erstellen eine Shell auf der anderen Seite zu gehen, sagen können (öffnen Sie einfach den Tunnel) mit einem Flag-Befehlszeile (Ich sehe Sie schon tat dies mit -N).
  • Speichern Sie die PID mit PID=$!
  • Sie Ihre Sachen
  • kill $PID

EDIT: Feste $? zu $! und fügte hinzu, die &

+7

$ ?? Nein, $ !! . . – mob

+0

Wenn mein Skript irgendwo stirbt, bevor es zum KILL kommt, muss ich vorsichtig damit umgehen. –

+0

@mobrule: dein Recht. Fest. – ZeissS

4

Ich ziehe eine neue Shell für unterschiedliche Aufgaben zu starten und ich verwende oft den folgenden Befehl Kombination:

$ sudo bash; exit 

oder manchmal:

$ : > sensitive-temporary-data.txt; bash; rm -f sensitive-temporary-data.txt; exit 

Diese Befehle erstellen eine verschachtelte Shell wo ich all meine Arbeit machen kann; Wenn ich fertig bin, drücke ich STRG-D und die Eltern-Shell räumt auf und geht ebenfalls. Sie könnten leicht bash; in Ihren SSH-Tunnel Skript werfen kurz vor dem kill Teil so, dass, wenn Sie die verschachtelten Shell geschlossen werden Ihre Tunnel ausloggen:

#!/bin/bash 
ssh -nNT ... & 
PID=$! 
bash 
kill $PID 
+0

Sehr interessant. Dies kann das "Trap" -Problem besser behandeln. Ich werde es versuchen müssen. –

2

Eine andere mögliche Option - wenn Sie das Paket erwarten installieren , Sie sollten in der Lage sein, die ganze Sache zu skripten.Einige gute Beispiele hier: http://en.wikipedia.org/wiki/Expect

13

Sie können SSH mit der Option -f in den Hintergrund bringen, aber Sie erhalten die PID nicht mit $ !. Anstatt das Skript vor der Verwendung des Tunnels beliebig lange schlafen zu lassen, können Sie -o ExitOnForwardFailure = yes mit -f verwenden und SSH wartet darauf, dass alle Remote-Port-Forwards erfolgreich eingerichtet werden, bevor es sich im Hintergrund befindet. Sie können die Ausgabe von ps grep, um die PID zu erhalten. Zum Beispiel können Sie

... 
ssh -Cfo ExitOnForwardFailure=yes -NL 9999:localhost:5900 $REMOTE_HOST 
PID=$(pgrep -f 'NL 9999:') 
[ "$PID" ] || exit 1 
... 

und sein ziemlich sicher, verwenden Sie zum gewünschten PID

Verwandte Themen