Como evitar "Falha na gravação: tubo quebrado" na conexão SSH?

283

O que posso fazer para configurar o SSH no cliente e nos servidores para evitar Write Failed: broken pipeerros? Geralmente ocorre se você dorme o computador cliente e retoma mais tarde.

sorin
fonte
8
Nada realmente. A sessão foi interrompida e a segurança da sessão foi comprometida. Se você não colocar o componente em suspensão, poderá definir um tempo de manutenção para o cliente disparar um batimento cardíaco de manutenção para o servidor, mas se o sistema estiver inativo, não há nada que possa ser feito.
darkdragn
3
Neste caso, estou procurando por algo que me permita reiniciar uma conexão ssh quebrada (provavelmente baseada no código de saída) e restaurar usando screen?
Sorin
4
Vocês estão errados: eu tenho DUAS máquinas clientes desktop conectando ao MESMO servidor. Um deles é o ubuntu 12.10, Quantal, cujo cliente SSH funciona bem e mantém a conexão por horas. O outro é o Ubuntu 14.10, Utopic, apenas de lado o outro e em uma nova instalação; Após alguns minutos, ele se bloqueia com esta mensagem. O restante das funções de rede na máquina não é interrompido. Portanto, não, não é um problema de rede, nem um servidor, mas um problema específico do software SSH CLIENT, que pode ser resolvido, ao contrário do que "darkdragan" ousa dizer, que "nada pode ser feito".
David L
2
E, de fato, como eu disse: as pessoas falam demais quando dizem "nada pode ser feito", assim como @ddrdragn ousou. Li a resposta de Aram Kocharyan e a apliquei: há 20 minutos ... percebi que no meu antigo Quantal Ubuntu 12.10, havia aplicado essa instrução naquele arquivo [acabei de verificar], dois anos atrás, e isso foi a razão da estabilidade lá. Fiz aqui e, nestes últimos 20 minutos, a conexão está estável desde então. Então, por favor, pessoal: abstenha-se ao ousar pensar que "nada pode ser feito" e abstenha-se ainda mais ao tentar deixar essa mensagem para outras pessoas.
David L
11
@ DavidDl, você deve ler melhor as perguntas antes de reclamar. Seu problema não é o mesmo do OP, que menciona claramente colocar o computador em suspensão. Que, a propósito, apenas uma das respostas de endereço ("mosh"), e foi postada 2 anos após a pergunta. No entanto, as outras respostas fazem a próxima melhor coisa, que é propor soluções para casos que podem ser resolvidos mais facilmente, como o seu. Chill out, não seja tão estressado, ranting não faz qualquer bom por aqui ...
MSB

Respostas:

266

Eu tentei isso no /etc/ssh/ssh_configLinux e Mac:

Host *
ServerAliveInterval 120

É com que frequência, em segundos, ele deve enviar uma mensagem de manutenção permanente para o servidor. Se isso não funcionar, treine um macaco para pressionar enter a cada dois minutos enquanto você trabalha.

Você pode definir ServerAliveIntervalna /etc/ssh/ssh_configmáquina cliente ou ClientAliveIntervalna /etc/ssh/sshd_configmáquina servidor. Tente reduzir o intervalo se você ainda estiver recebendo o erro.

A configuração para um único usuário pode ser definida em arquivo ~/.ssh/configno servidor e no cliente. Verifique se o arquivo tem permissões corretas chmod 644 ~/.ssh/config.

Aram Kocharyan
fonte
4
Eu não estou em um Mac, mas o Ubuntu 12.04 e o arquivo para este sistema operacional também parecem ser ~ / .ssh / config.
H2ONaCl 14/12
5
OS X 10.8.4 apresenta um erroBad configuration option: ClientAliveInterval
ohho 15/07/2013
3
Eu recebo o mesmo Bad configuration optionerro no OSX 10.8.4.
22613 Nick Heiner
10
Geralmente, você coloca esses dois comandos em diferentes partes do sistema. Apenas ServerAliveInterval no lado do cliente OSX ... e só ClientAliveInterval no arquivo sshd configuração ...
ftrotter
2
Meu macaco me disse: "Por que você não se digita" top [ENTER] "
agosto
85

As sessões SSH podem ser interrompidas devido a numerosas e possivelmente inevitáveis ​​razões.

Um utilitário útil que pode ser usado para mitigar problemas causados ​​por isso é chamado screen. Screen é um utilitário poderoso que permite controlar vários terminais que permanecerão ativos independentemente da sessão ssh. Por exemplo, se você executar screenuma sessão ssh, verá um novo terminal aberto e poderá usá-lo para executar tarefas. Vamos dizer que sua sessão ssh morre no processo. A execução screen -dentão screen -rreabrirá a última sessão e você poderá continuar a partir daí. Certifique-se de ler parte da documentação antes de usá-la.

eltommo
fonte
5
Esta é provavelmente a melhor resposta, não sei por que não foi votada mais. As outras "correções" são úteis no caso especial em que você realmente se preocupa em manter uma conexão SSH, mas na maioria dos casos de uso, imagino que a preocupação real é que os processos pretendidos continuem em execução, independentemente de qualquer problema de conexão cliente / servidor. .
Paul McMurdie
16
Eu também adicionaria o Tmux como uma alternativa para a tela. Acho mais versátil e estável que a tela.
Fridaymeetssunday
2
deixando isso aqui para referência futura - você pode executar convenientemente screen -d -rpara recuperar sua última sessão.
Doplumi
2
Ou simplesmente screen -dr. Ou screen -xdependendo do que você planeja fazer. O ponto é que é preciso saber o que todos esses comutadores fazem, para poder usar os adequados e não apenas seguir cegamente as sugestões das pessoas da Internet. Há um belo resumo compacto disponível aqui: ss64.com/bash/screen.html
flith
Esta não é uma resposta para o problema
user3728501 16/04
46

Configuração do cliente

Tente criar o arquivo:

~/.ssh/config

Adicione o conteúdo:

Host *
  ServerAliveInterval 30
  ServerAliveCountMax 5

Agora faça o ssh no seu servidor e verifique se o seu problema foi corrigido. A opção ClientAliveInterval é útil apenas ao configurar o servidor ssh (também conhecido como sshd), pois não altera nada no lado do cliente ssh, portanto, não use-o no arquivo de configuração acima.

Isso enviará um sinal de olá, você está aí para o servidor se nenhum pacote tiver sido recebido nos 30 segundos anteriores (conforme especificado acima). No entanto, se o número de sinais consecutivos do tipo "olá-você-você-aí" atingirem ServerAliveCountMax, o ssh será desconectado do servidor. Esse valor é padronizado como 3 (portanto, 3 * 30 = 90 segundos sem atividade do servidor), aumente-o se for adequado às suas necessidades. Há muito mais opções de configuração no arquivo .ssh / config e você pode ler:

Usando um arquivo de configuração SSH

Para mais informações sobre outras opções. Você pode não querer aplicar isso a todos os servidores aos quais você se conectar ao qual este exemplo será. Ou restrinja-o a apenas um servidor específico substituindo a linha Host *por Host <IP>(substitua por um endereço IP, consulte a página de manual ssh_config).

Configuração do servidor

Da mesma forma, você pode dizer ao servidor para ser gentil com seus clientes. O arquivo de configuração é /etc/ssh/sshd_config.

ClientAliveInterval 20
ClientAliveCountMax 5

Você pode desativá-lo através da criação ClientAliveIntervalde 0ou ajustar ClientAliveIntervale ClientAliveCountMaxdefinir uma inatividade máximo cliente ssh sem responder às sondas. Uma vantagem dessas configurações sobre o TCPKeepAlive é que os sinais são enviados pelos canais criptografados, portanto, é menos provável que sejam falsificados.

Matt
fonte
Isso não funciona. Estou enfrentando o mesmo erro novamente.
user997704
3
Experimente diretamente da linha de comando e ir mais baixo: ssh -o ServerAliveInterval = 5 user @ host
Matt
Tentei isso também ... não funciona. Eu realmente não sei o que está acontecendo com o meu sistema
user997704
2
É ClientAliveCountMax, NÃO ClientAliveMaxCount
David G
@DavidG Por favor, edite a resposta com suas correções.
CivMeierFan
23

Estou atualizando remotamente um servidor Ubuntu do lucid para preciso e perdi a conexão ssh no meio da atualização com a mensagem "Falha na gravação. Brocken pipe". ClientAliveInterval e ServerAliveInterval não fizeram nada. A solução é ativar as opções TCPKeepAlive no cliente ssh:

TCPKeepAlive yes

no

/etc/ssh/ssh_config
Alexey Sviridov
fonte
20

Para o cliente, edite seu arquivo ~/.ssh/config(ou /etc/ssh/ssh_config) da seguinte maneira:

Host *
  TCPKeepAlive yes
  ServerAliveInterval 120

TCPKeepAlive - Especifica se o sistema deve enviar mensagens de manutenção de TCP para o outro lado. Se forem enviados, a morte da conexão ou falha de uma das máquinas será notada corretamente. No entanto, isso significa que as conexões morrerão se a rota cair temporariamente e algumas pessoas consideram isso irritante (o padrão é 'yes').

ServerAliveInterval - Define um intervalo de tempo limite em segundos, após o qual, se nenhum dado foi recebido do servidor, o ssh (1) enviará uma mensagem através do canal criptografado para solicitar uma resposta do servidor. O padrão é 0, indicando que essas mensagens não serão enviadas ao servidor.


Para o servidor, edite seu /etc/ssh/sshd_configcomo:

ClientAliveInterval 600
ClientAliveCountMax 0

Se você deseja que o cliente ssh saia (tempo limite) automaticamente após 10 minutos (600 segundos).

ClientAliveCountMax - Indica o número total de mensagens de verificação enviadas pelo servidor ssh sem obter resposta do cliente ssh. O padrão é 3.

ClientAliveInterval - indica o tempo limite em segundos. Após um número x de segundos, o servidor ssh enviará uma mensagem ao cliente solicitando resposta. O surdo é 0 (o servidor não enviará a mensagem ao cliente para verificar.).


Veja também: O que as opções ServerAliveIntervale ClientAliveIntervalno sshd_config fazem, precisamente?

kenorb
fonte
Definir um ServerAliveCountMax maior que o padrão no cliente também deve ajudar a manter a conexão ativa para conexões lentas.
Jonnyjandles
17

Eu absolutamente amo Mosh. Frequentemente, ssh em um servidor, fecho meu laptop e vou a um café, abro e continuo como se nada tivesse mudado.

Mosh (shell móvel)

Aplicativo de terminal remoto que permite roaming , suporta conectividade intermitente e fornece eco local inteligente e edição de linha das teclas do usuário.

Mosh é um substituto para o SSH. É mais robusto e ágil, especialmente através de links Wi-Fi, celular e de longa distância.

Mosh é um software gratuito, disponível para GNU / Linux, FreeBSD, Solaris, Mac OS X e Android.

Jake
fonte
6

Para mim, eu estava ficando Write failed: Broken pipeempolgado quando estava digitando ativamente no vim ou no prompt do shell. Também não consegui navegar na internet localmente por um tempo. (Eu estava me conectando remotamente ao Ubuntu usando o Terminal.)

Outros na minha rede transmitem muitos vídeos do Netflix e de outros lugares. Não posso provar isso, mas suspeito que seja um problema com o provedor ou o roteador. Por exemplo, Verizon e Netflix estão apontando os dedos para os problemas de rede de seus clientes.

Se você possui uma conexão discada e está transmitindo vídeo ou música com uma conexão SSH ou telnet simultânea, é inevitável que, em algum momento, você receba uma mensagem incorreta. Atualizar o meu pacote de banda larga de ISPs parecia tornar minha conexão interrompida menos frequente.

Parag
fonte
3

Eu tenho um script no servidor remoto que nunca parece falhar, independentemente do cliente ou servidor de configuração SSH.

#!/bin/bash
while true; do date; sleep 10; done;

Salve-o em algum arquivo dummy.sh e execute-o rapidamente antes de minimizar a janela ou se afastar dela. Ele continuará imprimindo o carimbo de data / hora atual no servidor e manterá sua conexão ativa, desde que a conexão não seja interrompida por qualquer outro motivo. Quando você voltar ao terminal, basta pressionar CTRL + C e continuar trabalhando.

JulioHM
fonte
9
ou simplesmente sair topcorrendo
Eben Geer
1

Você pode adicionar esses argumentos sempre que chamar ssh: -o ServerAliveInterval=15 -o ServerAliveCountMax=3

Você não precisa editar os arquivos / etc / ssh / * config se fizer isso.

Você pode criar um alias de bash ou função ou script para facilitar isso.

Por exemplo, essas funções do bash, você pode adicionar ao .bashrc, do_ssh é usado manualmente para ativar o keepalives. do_ssh_pty é usado nos scripts para definir o pty e evitar prompts.

do_ssh() {
    ssh -o ServerAliveInterval=15 -o ServerAliveCountMax=3 $*
}

do_ssh_pty() {
    ssh -tt -o "BatchMode=yes" -o "StrictHostKeyChecking=no" -o ServerAliveInterval=15 -o ServerAliveCountMax=3 $*
}

Agora do_ssh user@hostpode ser usado ou do_ssh user@host <args> <command>e o keepalives estará ativo.

gaoithe
fonte