Melhores Práticas para Prevenir Problemas de Timeout no SSH
Evite quedas de SSH por inatividade com keepalives do cliente, configurações sensatas do servidor e tmux ou screen para trabalhos de longa duração.
Melhores Práticas para Prevenir Problemas de Timeout no SSH
Os timeouts de SSH geralmente aparecem quando seu terminal congela após alguns minutos de inatividade e, em seguida, exibe um erro de pipe quebrado ou conexão resetada. A causa geralmente é um firewall, gateway NAT, VPN ou balanceador de carga que descarta sessões TCP ociosas antes que seu cliente SSH perceba.
A correção mais útil são os keepalives SSH do seu cliente. As configurações do lado do servidor também podem ajudar, mas servem a um propósito diferente e podem desconectar clientes inativos se você as definir de forma muito agressiva.
Entendendo a Causa Raiz dos Timeouts SSH
Um timeout SSH ocorre quando o link de comunicação entre o cliente e o servidor é rompido porque nenhum dos lados detectou atividade por um período específico. Isso geralmente não é causado pelo software SSH em si, mas sim por dispositivos de rede intermediários (firewalls, roteadores e tabelas NAT) que podam agressivamente conexões ociosas para conservar recursos.
Quando um firewall não vê tráfego em uma conexão TCP específica por alguns minutos, ele assume que a sessão está morta e descarta o estado da conexão. Na próxima vez que o cliente SSH tentar enviar dados, o servidor nunca os receberá, levando a um congelamento da sessão e eventual erro de timeout.
A solução é configurar o SSH para enviar sinais keep-alive (pequenos pacotes sem dados) regularmente, garantindo que os dispositivos intermediários reconheçam a conexão como ativa.
1. Soluções do Lado do Cliente: O ServerAliveInterval
A solução mais comum e fácil para prevenir timeouts é configurar o cliente SSH para enviar periodicamente uma mensagem keep-alive ao servidor. Isso é controlado pela diretiva ServerAliveInterval.
Como o ServerAliveInterval Funciona
ServerAliveInterval especifica o tempo em segundos após o qual o cliente enviará um pacote nulo ao servidor se nenhum dado tiver sido recebido do servidor. Esse valor garante que o lado do cliente mantenha o estado da conexão.
Configuração via ~/.ssh/config
Este método é recomendado, pois permite definir a configuração globalmente ou por host, persistindo entre reinicializações e diferentes sessões de terminal.
Crie ou modifique seu arquivo de configuração do cliente, geralmente localizado em ~/.ssh/config:
nano ~/.ssh/config
Para aplicar a configuração globalmente (a todos os hosts):
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Explicação dos Valores:
ServerAliveInterval 60: O cliente enviará um pacote keep-alive a cada 60 segundos se a conexão estiver ociosa.ServerAliveCountMax 3: Se o cliente enviar 3 mensagens keep-alive consecutivas sem receber uma resposta do servidor, o cliente encerrará a conexão. (Duração total do timeout: 60 segundos * 3 tentativas = 180 segundos).
Configuração via Linha de Comando
Se você precisar de uma correção temporária ou preferir aplicar a configuração apenas para uma única sessão, use a opção -o durante a conexão:
ssh -o "ServerAliveInterval 60" usuario@host_remoto
Dica: Um valor de 30 a 60 segundos geralmente é ideal, pois é frequente o suficiente para contornar a maioria das regras de firewall (geralmente definidas em torno de 5 minutos), mas não tão frequente a ponto de gerar sobrecarga excessiva de rede.
2. Soluções do Lado do Servidor: Aplicando Keep-Alives
Embora a solução do lado do cliente (ServerAliveInterval) seja geralmente suficiente, administradores que gerenciam servidores acessados por muitos usuários podem desejar aplicar configurações de keep-alive centralmente ou definir limites rígidos para conexões ociosas. Isso é feito no arquivo de configuração do daemon SSH, /etc/ssh/sshd_config.
Usando ClientAliveInterval e ClientAliveCountMax
Essas diretivas são as contrapartes do lado do servidor para as configurações do cliente. Elas instruem o servidor a verificar se o cliente ainda está conectado.
Abra o arquivo de configuração do daemon SSH:
sudo nano /etc/ssh/sshd_configAdicione ou modifique as seguintes linhas:
# O servidor envia uma mensagem de cliente ativo após 300 segundos sem tráfego do cliente. ClientAliveInterval 300 # Desconecta após 3 mensagens de cliente ativo sem resposta. ClientAliveCountMax 3
Nota sobre ClientAliveCountMax:
As mensagens ClientAliveInterval são sondagens em nível SSH, não uma configuração simples de "desconectar após este tempo de inatividade". Com ClientAliveInterval 300 e ClientAliveCountMax 3, o servidor desconecta somente após aproximadamente 15 minutos de sondagens sem resposta. No OpenSSH, ClientAliveCountMax 0 desativa essas mensagens keep-alive do servidor, portanto, não é um bom exemplo de aplicação de timeout.
Reinicie o serviço SSH para que as alterações entrem em vigor:
sudo systemctl reload sshd # ou sudo service ssh reload
3. Estratégias Avançadas de Resiliência
Embora os keep-alives SSH lidem com curtos períodos de inatividade, uma interrupção completa da rede (por exemplo, mudar de rede Wi-Fi ou perder o sinal momentaneamente) ainda derrubará a conexão TCP. Para verdadeira resiliência, use ferramentas de gerenciamento de sessão.
Utilize Multiplexadores de Terminal (tmux ou screen)
Os multiplexadores de terminal são a defesa definitiva contra quedas de conexão. Eles executam uma sessão no servidor remoto que persiste mesmo que sua conexão de cliente seja interrompida. Você pode se desanexar da sessão, reconectar mais tarde (do mesmo cliente ou de um diferente) e reanexar para retomar exatamente de onde parou.
Fluxo de Trabalho Básico do tmux:
- Conecte-se ao servidor:
ssh usuario@host_remoto - Inicie uma nova sessão do
tmuxno servidor:tmux new -s minha_sessao - Trabalhe dentro da sessão do
tmux. - Se a conexão cair, ou se você precisar sair, desanexe a sessão (Ctrl+B, depois D).
- Reconecte-se ao servidor via SSH.
- Reanexe à sua sessão existente:
tmux attach -t minha_sessao
Distinguindo Keep-Alives SSH de Keep-Alives TCP
É possível usar o mecanismo Keep-Alive TCP do sistema operacional subjacente, geralmente configurado através da diretiva TCPKeepAlive yes no sshd_config. No entanto, os keep-alives em nível SSH (ServerAliveInterval) são geralmente preferidos porque:
- Portabilidade: As diretivas SSH funcionam de forma consistente, independentemente da sintonia do kernel do SO subjacente.
- Camada de Aplicação: Os keep-alives SSH operam dentro da camada de aplicação, garantindo que o daemon SSH permaneça responsivo.
- Consciência de Firewall: Os keep-alives TCP podem às vezes ser silenciosamente bloqueados por firewalls ou dispositivos NAT que apenas verificam a atividade de payload, enquanto os keep-alives SSH são projetados especificamente para atravessar essas camadas com sucesso.
Se você optar por usar TCPKeepAlive yes, lembre-se de que o intervalo de tempo real é controlado pelo sistema operacional (por exemplo, net.ipv4.tcp_keepalive_time do Linux), não pela configuração SSH.
Resumo das Melhores Práticas
| Problema | Diretiva de Configuração | Localização | Valor Recomendado | Propósito |
|---|---|---|---|---|
| Timeouts do Cliente | ServerAliveInterval |
~/.ssh/config (Cliente) |
30 - 60 segundos | Envia pacotes nulos do cliente para o servidor para evitar queda por firewall. |
| Limite de Desconexão do Cliente | ServerAliveCountMax |
~/.ssh/config (Cliente) |
3 - 5 | Número de respostas perdidas antes do cliente desconectar. |
| Aplicação de Inatividade do Servidor | ClientAliveInterval |
/etc/ssh/sshd_config (Servidor) |
300 segundos (5 min) | Envia verificações do servidor para o cliente para monitorar atividade. |
| Resiliência de Conexão | N/A | Sessão do Servidor | tmux ou screen |
Permite persistência da sessão apesar de falha de rede. |
Comece com ServerAliveInterval na configuração do seu cliente. Para migrações longas, atualizações de pacotes ou investigações de logs, execute o trabalho dentro do tmux ou screen para que um caminho de rede perdido não mate o trabalho.