Acompanhamento: Parece que a série rápida de desconexões que coincide com alguns meses de execução de cada servidor provavelmente é coincidência e serviu apenas para revelar o problema real. A razão pela qual ele não conseguiu se reconectar é quase certamente devido aos valores AliveInterval (resposta de kasperd). O uso da opção ExitOnForwardFailure deve permitir que o tempo limite ocorra corretamente antes de se reconectar, o que deve resolver o problema na maioria dos casos. A sugestão do MadHatter (o script de interrupção) é provavelmente a melhor maneira de garantir que o túnel possa se reconectar, mesmo se tudo falhar.
Eu tenho um servidor (A) atrás de um firewall que inicia um túnel reverso em várias portas para um pequeno DigitalOcean VPS (B), para que eu possa conectar-me a A via endereço IP de B. O túnel trabalha de forma consistente há cerca de três meses, mas falhou repentinamente quatro vezes nas últimas 24 horas. A mesma coisa aconteceu há algum tempo em outro provedor de VPS - meses de operação perfeita e, de repente, várias falhas rápidas.
Eu tenho um script na máquina A que executa automaticamente o comando tunnel ( ssh -R *:X:localhost:X address_of_B
para cada porta X), mas quando é executado, ele diz Warning: remote port forwarding failed for listen port X
.
Entrar no sshd /var/log/secure
no servidor mostra estes erros:
bind: Address already in use
error: bind: Address already in use
error: channel_setup_fwd_listener: cannot listen to port: X
A solução requer a reinicialização do VPS. Até então, todas as tentativas de se reconectar transmitem a mensagem "falha no encaminhamento de porta remota" e não funcionam. Agora é o ponto em que o túnel dura apenas cerca de 4 horas antes de parar.
Nada mudou no VPS e é uma máquina de usuário único e uso único que serve apenas como ponto final do túnel reverso. Está executando o OpenSSH_5.3p1 no CentOS 6.5. Parece que o sshd não fecha as portas quando a conexão é perdida. Não sei explicar por que, ou por que isso aconteceria repentinamente agora, depois de meses de operação quase perfeita.
Para esclarecer, primeiro preciso descobrir por que o sshd se recusa a ouvir as portas após a falha do túnel, o que parece ser causado pelo sshd deixar as portas abertas e nunca fechá-las. Esse parece ser o principal problema. Só não tenho certeza do que faria com que ele se comportasse dessa maneira depois de meses se comportando como eu esperava (por exemplo, fechando as portas imediatamente e permitindo que o script se reconecte).
fonte
Respostas:
Concordo com o MadHatter, que é provável que sejam encaminhamentos de portas de conexões ssh desativadas. Mesmo que o seu problema atual acabe sendo algo diferente, você pode esperar encontrar essas conexões ssh desativadas mais cedo ou mais tarde.
Existem três maneiras pelas quais essas conexões desativadas podem ocorrer:
Descobrir qual dos três acima está acontecendo não é muito importante, porque existe um método que abordará os três. Esse é o uso de mensagens keepalive.
Você deve procurar a
ClientAliveInterval
palavra - chavesshd_config
e oServerAliveInterval
intervalo parassh_config
ou~/.ssh/config
.A execução do
ssh
comando em um loop pode funcionar bem. É uma boa idéia inserir uma suspensão no loop, para que você não acabe inundando o servidor quando a conexão, por algum motivo, falhar.Se o cliente se reconectar antes que a conexão seja encerrada no servidor, você poderá acabar em uma situação em que a nova conexão ssh esteja ativa, mas sem encaminhamento de porta. Para evitar isso, você precisa usar a
ExitOnForwardFailure
palavra-chave no lado do cliente.fonte
-o ExitOnForwardFailure yes
é exatamente o que eu precisava. Então isso é uma coisa a menos que preciso descobrir. Para pensar, eu ia escrever um script Python para analisar essas mensagens de aviso. Isso é muito mais simples. : DExitOnForwardFailure
ao escrever minha resposta. Eu o adicionei à resposta agora.-o ExitOnForwardFailure=yes
(observe o sinal de igual). Portanto, se alguém se deparar com isso, não copie e cole do meu comentário anterior, ele não funcionará. : PVocê pode encontrar o processo que está vinculando a porta nesse servidor com
Parece muito provável que seja o meio defunto
sshd
, mas por que fazer suposições quando você pode ter dados? Também é uma boa maneira de um script encontrar um PID para enviar o sinal 9 antes de tentar abrir o túnel novamente.fonte
Para mim, quando um
ssh
túnel é desconectado, leva algum tempo para que a conexão seja redefinida, para que ossh
processo continue bloqueado, deixando-me sem túneis ativos e não sei por quê. Uma solução alternativa é colocarssh
em segundo plano-f
e gerar novas conexões sem esperar que as conexões antigas sejam redefinidas. O-o ExitOnForwardFailure=yes
pode ser usado para LIMT o número de novos processos. A-o ServerAliveInterval=60
melhora a confiabilidade de sua conexão atual.Você pode repetir o
ssh
comando com frequência, digamos, em umcron
ou em um loop no seu script, por exemplo, a seguir, executamos ossh
comando a cada 3 minutos:fonte
-o ExitOnForwardFailure=yes
era o que eu estava procurando, muito obrigado!Na minha experiência, o ssh tem o hábito um pouco cansativo de não sair corretamente, se 'algo' ainda estiver sendo executado no sistema remoto. Por exemplo, iniciado em segundo plano. Você pode reproduzir isso:
Seu ssh será desconectado, mas na verdade não fechará a sessão - até que o processo remoto termine (o que não acontecerá, porque é um loop 'while true'). Pode estar acontecendo algo semelhante - sua sessão tem um processo 'travado' que está sendo gerado pelo ssh. A porta permanece em uso e, portanto, não pode ser reutilizada pelo seu processo local.
fonte
ssh -o ConnectTimeout=10 -o BatchMode=yes -gnN -R *:X:localhost:X root@$TUNSRV 1>>tunnel.log 2>&1 &
para que não haja nada sendo executado pelo SSH, exceto o próprio túnel, especificamente devido à opção -N. Tudo o que está sendo mantido aberto está sendo feito no servidor remoto B usando o próprio sshd.