Cómo matar la sesión SSH que se inició con la opción -f (ejecutar en segundo plano)


50

Estoy bastante perdido en esto. Desde la página del manual:

 -f      Requests ssh to go to background just before command execution.

Después de comenzar SSH con la -fopción, tengo un túnel en funcionamiento. Pero después de terminar de usarlo, no sé cómo seguir interactuando con él. Por ejemplo, no puedo cerrar el túnel SSH cuando termino con él.

Los métodos habituales que conozco no funcionan. Por ejemplo, jobsno devuelve nada. El ~comando no se reconoce (y no sé exactamente cómo usarlo, de todos modos).

Sin embargo, pgrepme dice que el túnel SSH todavía está funcionando (después de haber cerrado la terminal, etc.). ¿Cómo interactúo con él? ¿Cómo lo cierro?

Respuestas:


65

Una solución especialmente buena para las secuencias de comandos es usar master mode, con un socket para comandos de control:

ssh -f -N -M -S <path-to-socket> -L <port>:<host>:<port> <server>

Para cerrarlo de nuevo:

ssh -S <path-to-socket> -O exit <server>

Esto evita tanto la búsqueda de identificadores de proceso como cualquier problema de tiempo que pueda estar asociado con otros enfoques.


10
Solo para expandirse un poco para los no iniciados, <path-to-socket> es una ruta a un archivo que la instancia maestra del cliente ssh creará para la comunicación entre procesos con otras instancias del cliente ssh que quieran compartir la conexión de la instancia maestra. El archivo creado en realidad representará un socket de dominio Unix. Puede nombrarse y ubicarse como y donde lo desee, p. Ej. /tmp/session1(Aunque se recomienda nombrarlo usando % patterns - consulte la descripción de ControlPath en man ssh_config)
golem

1
También parece que la parte <server> del ssh -S <path-to-socket> -O exit <server>comando puede ser cualquier cadena, pero debe estar presente. Eso es un poco torpe.
Golem

1
Esta respuesta y esta pregunta son algo antiguas, pero quería respaldar esto como probablemente la forma más elegante y 'correcta' de manejar este problema que he visto. ¡Gracias Señor!
zentechinc

41

Encontré la solución aquí: http://www.g-loaded.eu/2006/11/24/auto-closing-ssh-tunnels/

La mejor manera: túneles que se cierran automáticamente

Como se ha mencionado anteriormente, en lugar de usar la combinación de conmutadores -f -N, podemos usar -f solo, pero también ejecutar un comando en la máquina remota. Pero, ¿qué comando debe ejecutarse, ya que solo necesitamos inicializar un túnel?

¡Aquí es cuando dormir puede ser el comando más útil de todos! En esta situación particular, dormir tiene dos ventajas:

  • no hace nada, por lo que no se consumen recursos
  • el usuario puede especificar por cuánto tiempo se ejecutará

A continuación, se explica cómo estos ayudan a cerrar automáticamente el túnel ssh.

Comenzamos la sesión ssh en segundo plano, mientras ejecutamos el comando de suspensión durante 10 segundos en la máquina remota. El número de segundos no es crucial. Al mismo tiempo, ejecutamos vncviewer exactamente como antes:

[me@local]$ ssh -f -L 25901:127.0.0.1:5901 me@remote.example.org sleep 10; \
          vncviewer 127.0.0.1:25901:1

En este caso, se le indica al cliente ssh que bifurque la sesión ssh en segundo plano (-f), cree el túnel (-L 25901: 127.0.0.1: 5901) y ejecute el comando de suspensión en el servidor remoto durante 10 segundos (suspensión 10)

La diferencia entre este método y el anterior (-N switch), básicamente, es que en este caso el objetivo principal del cliente ssh no es crear el túnel, sino más bien ejecutar el comando de suspensión durante 10 segundos. La creación del túnel es una especie de efecto secundario, un objetivo secundario. Si no se usó vncviewer, el cliente ssh saldría después del período de 10 segundos, ya que no tendría más trabajos que hacer, destruyendo el túnel al mismo tiempo.

Durante la ejecución del comando de suspensión, si otro proceso, vncviewer en este caso, comienza a usar ese túnel y lo mantiene ocupado más allá del período de 10 segundos, entonces, incluso si el cliente ssh finaliza su trabajo remoto (ejecución de suspensión), no puede salir porque otro proceso ocupa el túnel. En otras palabras, el cliente ssh no puede destruir el túnel porque también tendría que matar a vncviewer. Cuando vncviewer deja de usar el túnel, el cliente ssh también se cierra, ya que ya ha logrado su objetivo.

De esta manera, no quedan procesos ssh ejecutándose en segundo plano.


44
Una breve observación / corrección: Hasta donde yo sé, debe especificar, vncviewer 127.0.0.1::25091ya que está utilizando la sintaxis del puerto y no la sintaxis de la pantalla.
Christian Wolf

Esta es una gran idea, y deja de lado un problema que tuve en Windows. Las versiones recientes de Windows se entregan con un cliente ssh, y es compatible con la opción -S en teoría, pero no parece funcionar para mí.
Keeely

9

Para matar el túnel, use ps -C ssho ps | grep sshcualquier otra variante para determinar qué proceso ssh está ejecutando su túnel. Entonces mátalo.

Alternativamente, puede buscar el proceso determinando cuál tiene este puerto abierto:

netstat -lnpt | awk '$4 ~ /:1234$/ {sub(/\/.*/, "", $7); print $7}'

Si desea matar a todos los clientes ssh que se ejecutan en su máquina (como su usuario), pkill sshlo hará.


6

Como respondieron otros aquí, lo pkill sshmata.

Para crear un túnel que pueda recuperarse, lo inicio screensin la -fopción y luego desconecto la pantalla con Ctrl-A D. Para traer de vuelta el túnel, llame screen -r.


Fuerza bruta, pero efectiva
mafrosis

1
Tenga cuidado si se está conectando de forma remota. pkill ssh incluso matará tu conexión actual.
kennyut

@kennyut Otra razón más para usar screen.
Haotian Yang

0

Cuando comienzo un túnel con:

ssh -fN -D 8080 SOME_IP_HERE -l LOGIN_NAME_HERE
  • -f Solicita a ssh que vaya al fondo justo antes de la ejecución del comando.
  • -NNo ejecute un comando remoto. Esto es útil solo para reenviar puertos.
  • -D Especifica un reenvío de puerto a nivel de aplicación "dinámico" local.
  • -l Especifica el usuario para iniciar sesión como en la máquina remota.

Puedo cerrarlo con:

ps -lef | grep ssh | grep "8080" | awk "{print \$2}" | xargs kill

-1

La mejor solución que encontré para matar todos los túneles en una línea de comando es

ps -lef|grep ssh|grep "\-L"|awk '{print $4}'|xargs kill

para las sesiones ssh, simplemente elimine la opción de túnel

ps -lef|grep ssh|awk '{print $4}'|xargs kill

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.