Como posso me reconectar a uma sessão ssh após um cano quebrado?

28

Então, eu estava rodando apt-get upgradeem um servidor quando o roteador decidiu que já fazia muito tempo desde a última vez que fiquei com raiva: ele perdeu toda a conexão. O moral da história é usar screenmuito quando você está em um roteador de vagabundo.

De qualquer forma, entrei novamente e descobri no htop que o processo ainda estava suspenso, esperando o upgrade do Y / n (ainda não o havia acertado, por sorte). Existe alguma maneira de me reconectar a uma sessão que foi interrompida? Acabei matando, já que não estava no meio do gerenciamento de pacotes, mas seria ótimo saber para referência futura.

ζ--
fonte
1
Estou surpreso que o apt-getprocesso ainda estivesse em execução. Deveria ter morrido junto com toda a cadeia do processo até o SSH. Notei que do-dist-upgradecomeça automaticamente em uma sessão screen/ byobu: talvez em algumas circunstâncias, apt-getfaça o mesmo?
Nfvvine 02/10

Respostas:

16

A resposta para sua pergunta correta é: você não pode . Eu acho que o principal problema é que os procedimentos de autenticação estarão fora de sincronia. Simplesmente não funciona assim.

Como você notou, a solução é usar a tela sempre que possível (a propósito, o tmux é uma alternativa à tela).

janeiro
fonte
1
Mas e se você tiver ssh sem senha? Você pode fazer isso então?
Sridhar Sarnobat
1
byobu is a nice, easier to use front end to screen (or tmux) - definitely worth a look (:
drevicko
Sridhar-Samobol, a autenticação ainda precisa ocorrer. Anexar a uma sessão em execução não tem como executar o aperto de mão inicial novamente, portanto, seus invariantes seriam interrompidos se introduzirmos uma nova sessão em uma já existente. Resposta: não.
kevr 17/04
9

Para executar processos duradouros, eu uso screen ou byobu se você deseja uma interface mais amigável.

Para tela, você pode usar:

screen [program] [args]

Isso executará [program] e seus [args] dentro de uma sessão de tela . Após o término do programa, a sessão é fechada automaticamente. Se você deseja manter a sessão após a execução do programa, basta executar a tela sem argumentos e um novo prompt aparecerá dentro da sessão. CTRL + A + D desanexa o terminal da sessão atual.

Para se reconectar a uma sessão anterior:

screen -r

Se houver apenas uma sessão aberta, ela será reconectada imediatamente. Se várias sessões estiverem em andamento, ele perguntará a qual você deseja anexar. Se você souber o nome da sessão, basta adicioná-lo como argumento a esta linha de comando.

Byobu é uma boa melhoria. É baseado na tela , mas fornece uma barra na parte inferior que mostra todas as sessões atuais como guias e fornece atalhos mais fáceis para serem movidos por elas. Você pode:

  • F2 inicia uma nova sessão
  • F3 move para a próxima guia da sessão à esquerda
  • F4 move para a próxima sessão da guia à direita
  • F8 atribui um nome amigável à guia da sessão atual
  • F9 abre um menu de opções
  • CTRL + A + D desanexa todas as sessões do terminal.

PALAVRA DO CONSELHO : evite deixar uma sessão aberta com a raiz do usuário . Se alguém obtiver acesso ao seu terminal (local ou remotamente), poderá facilmente se reconectar a uma sessão em andamento e usar seu sistema como root. Se necessário, é melhor iniciar uma sessão usando as linhas de comando comuns do usuário e do sudo , conforme necessário.

JulioHM
fonte
1
Posso citar o OP: "A moral da história é usar muito a tela ". Aparentemente, essa não era a questão aqui.
janeiro
Obrigado pela redação, mas janeiro estava correto.
Use sudo screen <comando> para configurar uma tela como raiz, que precisa de acesso ao sudo para reconectar-se a ela. Muito melhor do que iniciar uma tela normalmente e depois mudar para raiz dentro dela.
Djsmiley2k - CoW
8

Embora não seja possível reconectar a uma sessão SSH quebrada, é possível reparar novamente o processo em execução no SSH - funcionalmente equivalente ao que você deseja.

Instruções

No seu caso, você assumiria o apt-getprocesso a ser controlado a partir de uma nova sessão SSH, screensessão ou similar. O meu favorito para isso é o reptyrcomando:

$ sudo apt-get install reptyr
$ ps ax | grep apt-get
10626 pts/8   R+     0:32 apt-get upgrade

Então, com o pid que você encontrou para o seu processo:

$ sudo reptyr -T 10626

Ou, se isso não funcionar, tente:

$ reptyr 10626

Após esse estágio, toda a entrada do teclado vai para o programa que você assumiu. Infelizmente, você não verá a saída antiga da sessão SSH, como a apt-getsaída solicitando sua confirmação.

Explicações

Existem várias outras ferramentas que basicamente funcionam da mesma forma reptyr(ou seja, via ptraceanexo de depuração). Consulte as seguintes perguntas e respostas onde elas são discutidas:

Nas instruções acima, ele reptyr 10626usa o ptraceanexo de depuração enquanto o sudo reptyr -T 10626comando usa o roubo de TTY e é preferível ( detalhes ).

Finalmente, a razão pela qual você não pode assumir uma sessão SSH dessa maneira é porque um sshdprocesso não é controlado por um terminal host, mas fornece a parte escrava de um terminal - um ptsdispositivo - enquanto a parte principal que o controla reside no máquina cliente, aqui com uma sessão SSH dividida no meio. Quando você força a assumir esse sshdprocesso reptyr -s <pid>, a entrada do teclado vai para esse processo, não para o processo filho ativo. Portanto, um "Ctrl + Z" simplesmente elimina isso sshd.

tanius
fonte
1

Eu estava fazendo do-dist-upgradevia ssh de um laptop que entrou em suspensão, portanto Broken pipe. Ao voltar para a máquina, vi os processos relacionados à atualização ainda em execução, entre os quais uma whiptailsolicitação de entrada (qual gerenciador de exibição escolher) e, relevante, uma propriedade de raiz SCREEN. Eu era capaz de fazer sudo su -e screen -rme anexar à sessão e, eis que eu tenho o diálogo whiptail à minha frente, capaz de receber sugestões. Consegui retomar a atualização sem problemas.

Nota: esta foi uma atualização do Ubuntu 14.04 para 16.04.

haelix
fonte