2010-02-10 15 views
98

En CYGWIN, quiero un script bash a:script bash para configurar un túnel SSH temporal

  1. crear un túnel SSH a un servidor remoto.
  2. Trabaja un poco localmente que utiliza el túnel.
  3. Luego cierre el túnel.

La "parte de apagado" me tiene perplejo.

Actualmente, tengo una solución poco convincente. En un shell ejecuto lo siguiente para crear un túnel.

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

Luego, en otra ventana de shell, hago mi trabajo

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

Por último, cuando haya terminado. Cierro la primera ventana de shell para matar el túnel.

me gustaría hacer todo esto en un script como: # Crear túnel # funcionan túnel # Kill

¿Cómo puedo realizar un seguimiento del proceso de túnel, así que sé cuál de ellos para matar ?

+0

Escribí un script que ayudaría a hacer ssh tunneling, puede consultarlo en: https://github.com/gdbtek/ssh-tunneling.git –

Respuesta

235

Puede hacerlo limpiamente con un ssh 'toma de control'. Para hablar con un proceso de SSH ya a ejecutar y obtener su PID, matarlo etc. Use la 'toma de control' (-M para el amo y -S para el zócalo) de la siguiente manera:

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

Nota que mi-ctrl -socket será un archivo real que se crea.

Obtuve esta información en a very RTFM reply on the OpenSSH mailing list.

+5

Esta es la mejor respuesta que he visto sobre el tema hasta ahora. Muchas gracias, debería ser el aceptado. Utilizo esto para conectarme a mi VM de Vagrant y ejecutar un script de actualización de FlywayDB. – Christian

+7

Simplemente maravilloso. Gracias por compartir esto. +1. – slayedbylucifer

+2

Aparentemente, los enchufes de control no funcionan en todas partes. Por ejemplo, obtengo 'Operación no permitida' en el entorno de integración continua de drone.io:' muxserver_listen: enlace escucha de mux ssh-ctrl-socket.wsASkszgSBlK7kqD => ssh-ctrl-socket: Operación no permitida' –

2

Puede abrir el ssh con un & al final, para ponerlo en segundo plano y tomar su identificación al hacerlo. Entonces solo tienes que hacer un kill de esa identificación cuando hayas terminado.

+0

Tenga cuidado si usa el símbolo comercial ("&"). Es un enfoque desagradable, ya que tendrá que determinar la conexión real establecida para usted. Puede hacer que se ejecute un código adicional que no está esperando que la conexión real se establezca por completo. Además, la conexión no se eliminará automáticamente si se rompe la secuencia de comandos. –

17
  • Se puede decir ssh entrar en fondo con & y no crear una concha en el otro lado (basta con abrir el túnel) con un indicador de línea de comandos (Veo que ya hizo esto con -N).
  • Guardar el PID con PID=$!
  • Haz tus cosas
  • kill $PID

EDIT: $ fijo? a $! y añade el &

+7

$ ?? No, $ !! . . – mob

+0

Si mi secuencia de comandos muere en algún lugar antes de que llegue al KILL, tengo que tener cuidado de manejar eso. –

+0

@mobrule: su derecha. fijo. – ZeissS

4

prefiero lanzar un nuevo shell para tareas separadas y que a menudo utilizan la combinación siguiente comando:

$ sudo bash; exit 

oa veces:

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

Estos comandos crean una cáscara anidada donde puedo hacer todo mi trabajo; Cuando termino, presiono CTRL-D y el caparazón padre limpia y sale también. Desde aquí se puede tirar bash; dentro del script de túnel SSH justo antes de la parte kill de manera que al cerrar la sesión de la cáscara anidado el túnel se cerró:

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

Muy interesante. Esto puede manejar mejor el problema de "trampa". Tendré que intentarlo. –

13

Puede indicar a SSH el fondo con la opción -f pero no obtendrá el PID con $ !. Además, en lugar de que el script duerma una cantidad de tiempo arbitraria antes de utilizar el túnel, puede usar -o ExitOnForwardFailure = yes con -f y SSH esperará a que todos los puertos remotos se establezcan correctamente antes de colocarse en segundo plano. Puede grep la salida de ps para obtener el PID. Por ejemplo, puede utilizar

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

y estar bastante seguro de que está recibiendo el PID deseada

Cuestiones relacionadas