aviso Legal
Se a sua conexão SSH não sobreviver a breves interrupções na rede, haverá outra coisa que não permitirá que o ssh
TCP faça o que é normal.
Veja abaixo para detalhes. De qualquer forma:
A solução sem dependência mais rápida e suja
Crie um script de shell como este:
#!/bin/sh -
# Tune these numbers depending on how aggressively
# you want your SSH session to get reconnected.
timeout_options='-o ServerAliveInterval=4 -o ServerAliveCountMax=2'
# 255 is the status OpenSSH uses to signal SSH errors, which
# means we want to connect. All other exit statuses suggest
# an intentional exit.
status=255
# Keep opening the SSH connection and immediately dropping into
# `screen` until an intentional exit happens.
while [ "$status" = 255 ]
do
ssh $timeout_options -t "$@" screen -dR
status=$?
# You can add a `sleep` command here or a counter or whatever
# you might need as far as rate/retry limiting.
done
exit "$status"
Isso apenas executará um loop simples e estúpido que continua tentando se conectar ssh
e se conectar screen
. Passe o host ou qualquer outra coisa que você normalmente passaria para sua ssh
chamada como argumentos da linha de comando.
A reconexão baseia-se apenas no fato de o SSH relatar um erro na conexão, o que significa que ele não possui inteligência para detectar erros não-SSH como "você literalmente não tem o WiFI ativado" ou o que quer que seja, mas isso provavelmente não importa para você.
Suponho que você tenha ssh-agent
ou uma chave SSH sem senha que permita que as reconexões funcionem sem a necessidade de entrada adicional de você.
Haverá uma pequena condição de corrida em que, se você acertar ^C
durante a fração de segundo imperceptível a humanos certa durante uma reconexão, poderá acabar matando o script em vez de passar o ^C
caminho para o terminal do cliente, portanto, se você suspeitar de uma conexão travada não amasse ^C
com zelo demais.
Solução de software adicional mais simples
Você pode tentar o programa autossh , que deve estar disponível no seu repositório de pacotes Ubuntu.
Se você precisar compilar a partir do código-fonte ou auditá-lo, é um único programa em C que compila sem nenhuma biblioteca adicional como dependências, parece ter mais inteligência sobre como verificar a vitalidade da conexão do que o meu hack acima, e também é fornecido com um conveniente rscreen
comando de script que auto -anexa a screen
.
Detalhes
Como ssh
normalmente se recupera
Só para verificar, porque não gosto de dizer as coisas sem me verificar, fiz um pequeno teste antes de responder:
Eu entrei no meu WiFi com um dispositivo Linux, fiz uma conexão SSH com outro dispositivo na minha LAN, verifiquei que tinha uma ssh
conexão funcionando com a outra extremidade (podia executar comandos, etc.) e, em seguida, o cliente desconectou o WiFi (causando a interface para ser desconfigurado: não há mais endereços IP), digitou muitos caracteres na sessão ssh (sem resposta, é claro) e reconectou-se ao meu WiFi - a reconexão realmente falhou pelo menos uma vez devido a um sinal ruim e outros fatores e, finalmente, reconectado: esperei cerca de cinco segundos para que a ssh
sessão se recuperasse, nada aconteceu e pressionei mais uma tecla, e a ssh
sessão imediatamente voltou a funcionar, com todas as teclas que eu havia digitado durante a desconexão aparecendo na linha de comando.
Veja, ssh
apenas grava / lê no soquete da rede TCP até que o sistema operacional avise que algo deu errado, e o TCP é realmente muito tolerante a quedas prolongadas de conexão.
Deixada para seus próprios dispositivos com configurações padrão do kernel, a pilha TCP no Linux tolerará com prazer a conexão ficar completamente silenciosa por muitos minutos antes de declarar a conexão inativa e relatar um erro ssh
- no momento em que finalmente desistir, estaremos conversando no estádio. de ~ 30 minutos, ou pelo menos certamente o tempo suficiente para superar os soluços de conexão que duram um segundo ou um minuto.
Por baixo das capas, a pilha TCP do Linux tenta novamente gradualmente as mensagens com atrasos cada vez maiores, o que significa que, quando sua conexão voltar, você poderá observar um atraso adicional antes que sua ssh
sessão pareça ficar "viva" novamente.
Por que isso às vezes quebra
Geralmente, algo está ativamente causando o fechamento da conexão após um período de inatividade significativamente mais curto do que o valor que a pilha TCP tolerará e, em seguida, falha ao relatar esse estado de conexão ao seu ssh
cliente.
Os candidatos prováveis incluem:
Firewalls ou roteadores NAT'ing, que precisam usar a memória para lembrar cada conexão TCP ativa - como uma otimização e alguma atenuação contra ataques do DOS, eles às vezes esquecem sua conexão e depois ignoram silenciosamente os pacotes resultantes, porque os pacotes no no meio de uma conexão quando você não se lembra da conexão existente parecer inválida.
Firewalls / roteadores com melhor comportamento injetam um pacote TCP RST, que geralmente se manifesta como uma connection reset by peer
mensagem de erro, mas o pacote de redefinição é um alerta, portanto, se a conexão com o cliente ainda estiver com problemas naquele momento e eliminar o redefinir o pacote também, seu cliente pensará que a conexão ainda está ativa.
O servidor em si pode ter uma política de firewall para eliminar silenciosamente pacotes inesperados, o que interromperia as tentativas de retomada de conexão do cliente sempre que o servidor considerar que a conexão foi fechada, mas o cliente não: seu cliente continua tentando continuar a conexão, mas o servidor é apenas ignorando-o porque não há conexão ativa à qual esses pacotes pertençam ao estado de firewall do servidor.
Como você está executando o Linux, verifique cuidadosamente o servidor iptables
/ ip6tables
(ou nft
se você estiver usando o novo material) exatamente o que está permitindo ou descartando. É muito comum permitir pacotes novos / estabelecidos / relacionados na porta TCP SSH, mas não "inválidos" - se você estiver descartando silenciosamente tudo o que não é permitido, essa configuração comum poderá causar esse tipo de congelamento após breves problemas de conexão .
O próprio servidor SSH pode ser configurado para fechar a conexão após um período de inatividade, usando uma das opções do OpenSSH para pacotes de manutenção de atividade do cliente TCP ou SSH. Por si só, isso não causará travamentos indefinidos, mas pode colocá-lo em um dos estados descritos acima.
É possível que você simplesmente não esteja dando tempo suficiente para "desfazer" sozinho depois de entrar no estado em que sua ssh
sessão é encerrada .
<Enter>
e digite~.
para dizer ao seu lado para interromper a conexão, e você pode simplesmente repetir o último comando ssh para reconectar (por exemplo, com seta para cima ou!!
).