Como matar a sessão SSH iniciada com a opção -f (executada em segundo plano)

50

Estou muito perdido nisso. Na página do manual:

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

Depois de iniciar o SSH com a -fopção, eu tenho um túnel de trabalho. Mas depois de terminar de usá-lo, não sei mais como interagir com ele. Por exemplo, não consigo fechar o túnel SSH quando terminar com ele.

Os métodos usuais que conheço não funcionam. Por exemplo, jobsnão retorna nada. O ~comando não é reconhecido (e eu não sei exatamente como usá-lo).

No entanto, pgrepdiz-me que o túnel SSH ainda está em execução (depois de fechar o terminal, etc.). Como interajo com isso? Como eu fecho?

MountainX
fonte

Respostas:

65

Uma solução especialmente boa para scripts é usar master mode, com um soquete para comandos de controle:

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

Para fechá-lo novamente:

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

Isso evita o grepping para identificações de processo e quaisquer problemas de tempo que possam estar associados a outras abordagens.

Brian H
fonte
10
Apenas para expandir um pouco para os não iniciados, o <path-to-socket> é um caminho para um arquivo que a instância principal do ssh client criará para comunicação entre processos com outras instâncias do cliente ssh que desejam compartilhar a conexão da instância principal. O arquivo criado realmente representará um soquete de domínio unix. Ele pode ser chamado e localizado o que quer e onde quer que você quer, por exemplo /tmp/session1(embora seja recomendado para nomeá-lo usando % padrões - ver ControlPath descrição em man ssh_config)
golem
1
Também parece que a parte <server> do ssh -S <path-to-socket> -O exit <server>comando pode ser qualquer string, mas deve estar presente. Isso é meio desajeitado.
golem 29/05
1
Esta resposta e pergunta são um pouco antigas, mas eu queria aprovar isso como provavelmente a maneira mais elegante e 'correta' de lidar com esse problema que eu já vi. Obrigado senhor!
Zentechinc
41

Encontrei a solução aqui: http://www.g-loaded.eu/2006/11/24/auto-closing-ssh-tunnels/

A melhor maneira - túneis que fecham automaticamente

Como foi mencionado anteriormente, em vez de usar a combinação de opções -f -N, podemos apenas usar -f sozinho, mas também executar um comando na máquina remota. Mas, qual comando deve ser executado, já que precisamos apenas inicializar um túnel?

É quando o sono pode ser o comando mais útil de todos! Nessa situação específica, o sono tem duas vantagens:

  • não faz nada, então nenhum recurso é consumido
  • o usuário pode especificar por quanto tempo será executado

Como estes ajudam no fechamento automático do túnel ssh é explicado abaixo.

Iniciamos a sessão ssh em segundo plano, enquanto executamos o comando sleep por 10 segundos na máquina remota. O número de segundos não é crucial. Ao mesmo tempo, executamos o vncviewer exatamente como antes:

[me@local]$ ssh -f -L 25901:127.0.0.1:5901 [email protected] sleep 10; \
          vncviewer 127.0.0.1:25901:1

Nesse caso, o cliente ssh é instruído a colocar a sessão ssh em segundo plano (-f), criar o túnel (-L 25901: 127.0.0.1: 5901) e executar o comando sleep no servidor remoto por 10 segundos (suspensão 10)

A diferença entre esse método e o anterior (opção -N), basicamente, é que, neste caso, o principal objetivo do cliente ssh não é criar o túnel, mas executar o comando sleep por 10 segundos. A criação do túnel é algum tipo de efeito colateral, um objetivo secundário. Se o vncviewer não fosse usado, o cliente ssh sairia após o período de 10 segundos, pois não haveria mais tarefas a serem executadas, destruindo o túnel ao mesmo tempo.

Durante a execução do comando sleep, se outro processo, o vncviewer, nesse caso, começar a usar esse túnel e mantê-lo ocupado além do período de 10 segundos, então, mesmo se o cliente ssh concluir sua tarefa remota (execução da suspensão), ele não poderá sair porque outro processo ocupa o túnel. Em outras palavras, o cliente ssh não pode destruir o túnel porque precisaria matar o vncviewer também. Quando o vncviewer para de usar o encapsulamento, o cliente ssh também sai, pois já atingiu seu objetivo.

Dessa forma, nenhum processo ssh fica em execução em segundo plano.

MountainX
fonte
4
Uma breve observação / correção: Até onde eu sei, você deve especificar vncviewer 127.0.0.1::25091como está usando a sintaxe da porta e não a sintaxe da exibição.
Christian Wolf
Essa é uma ótima idéia e soluciona claramente um problema que tive no Windows. Versões recentes do Windows são fornecidas com um cliente ssh, e ele suporta a opção -S em teoria, mas não parecia funcionar para mim.
Keeely
9

Para eliminar o túnel, use ps -C sshou ps | grep sshou qualquer outra variante para determinar qual processo ssh está executando seu túnel. Então mate.

Como alternativa, você pode procurar o processo determinando qual deles tem essa porta aberta:

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

Se você deseja matar todos os clientes ssh em execução na sua máquina (como seu usuário), o pkill sshfará.

Gilles 'SO- parar de ser mau'
fonte
6

Como respondido por outras pessoas aqui, pkill sshmata.

Para criar um túnel que pode ser recuperado, inicio-o screensem a -fopção e desanexo a tela com Ctrl-A D. Para trazer de volta o túnel, ligue screen -r.

Haotian Yang
fonte
A força bruta, mas eficaz
mafrosis
1
Cuidado se você estiver se conectando remotamente. O pkill ssh até matará sua conexão atual.
Kennyut
@kennyut Mais uma razão para usar screen.
Haotian Yang
0

Quando inicio um túnel com:

ssh -fN -D 8080 SOME_IP_HERE -l LOGIN_NAME_HERE
  • -f Solicita que o ssh volte ao segundo plano imediatamente antes da execução do comando.
  • -NNão execute um comando remoto. Isso é útil apenas para encaminhamento de portas.
  • -D Especifica um encaminhamento de porta "dinâmico" local no nível do aplicativo.
  • -l Especifica o usuário para efetuar login como na máquina remota.

Eu posso fechá-lo com:

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

A melhor solução que encontrei para matar todos os túneis em uma linha de comando é

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

para as sessões ssh, basta remover a opção de encapsulamento

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

Philippe Gachoud
fonte