script bash ssh

Script Bash para configurar un túnel temporal SSH



bash if (6)

En CYGWIN, quiero un script de BASH para:

  1. crea un túnel SSH a un servidor remoto.
  2. Trabaja un poco localmente que usa el túnel.
  3. Luego cierra el túnel.

La "parte de cierre" me tiene perplejo.

Actualmente, tengo una solución débil. 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)

Finalmente, cuando termine. Cierro la primera ventana de shell para matar el túnel.

Me gustaría hacer esto en un solo script como: # Crear túnel # do trabajar # Kill tunnel

¿Cómo hago un seguimiento del proceso del túnel para saber cuál matar?


Otra opción potencial: si puede instalar el paquete esperado, debería poder realizar un script completo. Algunos buenos ejemplos aquí: http://en.wikipedia.org/wiki/Expect


Podrías lanzar el ssh con un & a fin, ponerlo en segundo plano y tomar su identificación cuando lo hagas. Entonces solo tienes que kill a esa identificación cuando termines.


Prefiero lanzar un nuevo shell para tareas separadas y a menudo uso la siguiente combinación de comandos:

$ sudo bash; exit

o algunas veces:

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

Estos comandos crean un shell anidado donde puedo hacer todo mi trabajo; Cuando termino, presiono CTRL-D y el caparazón padre limpia y sale también. Podrías lanzar bash; fácilmente bash; en su secuencia de comandos del túnel ssh justo antes de la parte de kill para que cuando cierre la sesión del shell anidado se cierre su túnel:

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


Puedes decirle a SSH que haga un fondo con la opción -f pero no obtendrás el PID con $ !. Además, en lugar de que el script duerma un tiempo arbitrario 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, puedes usar

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

y estar seguro de que está obteniendo el PID deseado


Puedes hacerlo limpiamente con un ''socket de control'' ssh. Para hablar con un proceso SSH ya en ejecución y obtener su pid, matarlo, etc. Utilice el ''socket de control'' (-M para el maestro 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.

Tenga en cuenta que my-ctrl-socket será un archivo real que se crea.

Obtuve esta información de una respuesta muy RTFM en la lista de correo de OpenSSH .


  • Puede decirle a ssh que entre en el fondo con & y no cree un cascarón en el otro lado (simplemente abra el túnel) con un indicador de línea de comando (veo que ya hizo esto con -N ).
  • Guarde el PID con PID=$!
  • Haz tus cosas
  • kill $PID

EDIT: Fixed $? a $! y agregó el &