Mejores Prácticas para Prevenir Problemas de Tiempo de Espera en SSH

Evita desconexiones SSH inactivas con keepalives del cliente, configuraciones sensatas del servidor y tmux o screen para trabajos de larga duración.

Mejores Prácticas para Prevenir Problemas de Tiempo de Espera en SSH

Los tiempos de espera en SSH suelen aparecer cuando tu terminal se congela después de unos minutos de inactividad, y luego muestra un error de tubería rota o conexión reiniciada. La causa suele ser un firewall, puerta de enlace NAT, VPN o balanceador de carga que elimina sesiones TCP inactivas antes de que tu cliente SSH lo note.

La solución más útil son los keepalives SSH desde tu cliente. Las configuraciones del lado del servidor también pueden ayudar, pero tienen un propósito diferente y pueden desconectar clientes inactivos si las configuras de manera demasiado agresiva.

Comprendiendo la Causa Raíz de los Tiempos de Espera en SSH

Un tiempo de espera en SSH ocurre cuando el enlace de comunicación entre el cliente y el servidor se corta porque ninguno de los lados ha detectado actividad durante un período específico. Esto no suele ser el software SSH en sí, sino dispositivos de red intermedios (firewalls, enrutadores y tablas NAT) que podan agresivamente conexiones inactivas para conservar recursos.

Cuando un firewall no ha visto tráfico en una conexión TCP específica durante unos minutos, asume que la sesión está muerta y elimina el estado de la conexión. La próxima vez que el cliente SSH intente enviar datos, el servidor nunca los recibe, lo que lleva a una congelación de la sesión y eventual error de tiempo de espera.

La solución es configurar SSH para enviar señales keep-alive (paquetes pequeños sin datos) regularmente, asegurando que los dispositivos intermedios reconozcan la conexión como activa.

1. Soluciones del Lado del Cliente: El ServerAliveInterval

La solución más común y fácil para prevenir tiempos de espera es configurar el cliente SSH para que envíe periódicamente un mensaje keep-alive al servidor. Esto se controla mediante la directiva ServerAliveInterval.

Cómo Funciona ServerAliveInterval

ServerAliveInterval especifica el tiempo en segundos después del cual el cliente enviará un paquete nulo al servidor si no se ha recibido datos del servidor. Este valor asegura que el lado del cliente mantenga el estado de la conexión.

Configuración a través de ~/.ssh/config

Este método se recomienda ya que te permite establecer la configuración de forma global o por host, persistiendo a través de reinicios y diferentes sesiones de terminal.

Crea o modifica tu archivo de configuración del cliente, típicamente ubicado en ~/.ssh/config:

nano ~/.ssh/config

Para aplicar la configuración de forma global (a todos los hosts):

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3

Explicación de los Valores:

  • ServerAliveInterval 60: El cliente enviará un paquete keep-alive cada 60 segundos si la conexión está inactiva.
  • ServerAliveCountMax 3: Si el cliente envía 3 mensajes keep-alive consecutivos sin recibir una respuesta del servidor, el cliente terminará la conexión. (Duración total del tiempo de espera: 60 segundos * 3 intentos = 180 segundos).

Configuración a través de la Línea de Comandos

Si necesitas una solución temporal o prefieres aplicar la configuración solo para una sesión, usa la opción -o durante la conexión:

ssh -o "ServerAliveInterval 60" usuario@host_remoto

Consejo: Un valor de 30 a 60 segundos suele ser ideal, ya que es lo suficientemente frecuente para eludir la mayoría de las reglas del firewall (a menudo configuradas alrededor de 5 minutos) pero no tan frecuente como para generar una sobrecarga de red excesiva.

2. Soluciones del Lado del Servidor: Forzar Keep-Alives

Si bien la solución del lado del cliente (ServerAliveInterval) suele ser suficiente, los administradores que gestionan servidores accedidos por muchos usuarios pueden desear forzar configuraciones keep-alive de forma centralizada o establecer límites estrictos en conexiones inactivas. Esto se hace en el archivo de configuración del demonio SSH, /etc/ssh/sshd_config.

Usando ClientAliveInterval y ClientAliveCountMax

Estas directivas son las contrapartes del lado del servidor de las configuraciones del cliente. Indican al servidor que verifique si el cliente sigue conectado.

  1. Abre el archivo de configuración del demonio SSH:

    sudo nano /etc/ssh/sshd_config
    
  2. Agrega o modifica las siguientes líneas:

    # El servidor envía un mensaje client-alive después de 300 segundos sin tráfico del cliente.
    ClientAliveInterval 300
    
    # Desconectar después de 3 mensajes client-alive sin respuesta.
    ClientAliveCountMax 3
    

Nota sobre ClientAliveCountMax:

Los mensajes ClientAliveInterval son sondeos a nivel SSH, no una simple configuración de "desconectar después de este tiempo de inactividad". Con ClientAliveInterval 300 y ClientAliveCountMax 3, el servidor desconecta solo después de aproximadamente 15 minutos de sondeos sin respuesta. En OpenSSH, ClientAliveCountMax 0 deshabilita estos mensajes keep-alive del servidor, por lo que no es un buen ejemplo para forzar tiempos de espera.

  1. Reinicia el servicio SSH para que los cambios surtan efecto:

    sudo systemctl reload sshd
    # o
    sudo service ssh reload
    

3. Estrategias Avanzadas de Resiliencia

Si bien los keep-alives SSH manejan períodos cortos de inactividad, una interrupción completa de la red (por ejemplo, cambiar de redes Wi-Fi o perder señal momentáneamente) aún cortará la conexión TCP. Para una verdadera resiliencia, usa herramientas de gestión de sesiones.

Utiliza Multiplexores de Terminal (tmux o screen)

Los multiplexores de terminal son la defensa definitiva contra cortes de conexión. Ejecutan una sesión en el servidor remoto que persiste incluso si tu conexión de cliente se corta. Puedes desvincularte de la sesión, reconectarte más tarde (desde el mismo o un cliente diferente) y reanudar exactamente donde lo dejaste.

Flujo de Trabajo Básico de tmux:

  1. Conéctate al servidor:
    ssh usuario@host_remoto
    
  2. Inicia una nueva sesión de tmux en el servidor:
    tmux new -s mi_sesion
    
  3. Trabaja dentro de la sesión de tmux.
  4. Si la conexión se corta, o necesitas irte, desvincula la sesión (Ctrl+B, luego D).
  5. Reconéctate al servidor vía SSH.
  6. Vuelve a vincular tu sesión existente:
    tmux attach -t mi_sesion
    

Distinguiendo Keep-Alives SSH de Keep-Alives TCP

Es posible usar el mecanismo TCP Keep-Alive del sistema operativo subyacente, a menudo configurado mediante la directiva TCPKeepAlive yes en sshd_config. Sin embargo, los keep-alives a nivel SSH (ServerAliveInterval) son generalmente preferidos porque:

  1. Portabilidad: Las directivas SSH funcionan de manera consistente independientemente del ajuste del kernel del sistema operativo subyacente.
  2. Capa de Aplicación: Los keep-alives SSH operan dentro de la capa de aplicación, asegurando que el demonio SSH siga respondiendo.
  3. Conciencia del Firewall: Los keep-alives TCP a veces pueden ser bloqueados silenciosamente por firewalls o dispositivos NAT que solo verifican la actividad de la carga útil, mientras que los keep-alives SSH están diseñados específicamente para atravesar estas capas con éxito.

Si eliges usar TCPKeepAlive yes, recuerda que el intervalo de tiempo real está controlado por el sistema operativo (por ejemplo, net.ipv4.tcp_keepalive_time de Linux), no por la configuración SSH.

Resumen de Mejores Prácticas

Problema Directiva de Configuración Ubicación Valor Recomendado Propósito
Tiempos de Espera del Cliente ServerAliveInterval ~/.ssh/config (Cliente) 30 - 60 segundos Envía paquetes nulos del cliente al servidor para evitar la caída del firewall.
Umbral de Desconexión del Cliente ServerAliveCountMax ~/.ssh/config (Cliente) 3 - 5 Número de respuestas perdidas antes de que el cliente se desconecte.
Forzar Inactividad del Servidor ClientAliveInterval /etc/ssh/sshd_config (Servidor) 300 segundos (5 min) Envía verificaciones del servidor al cliente para monitorear la actividad.
Resiliencia de Conexión N/A Sesión del Servidor tmux o screen Permite la persistencia de la sesión a pesar de fallos de red.

Comienza con ServerAliveInterval en tu configuración de cliente. Para migraciones de larga duración, actualizaciones de paquetes o investigaciones de registros, ejecuta el trabajo dentro de tmux o screen para que una ruta de red caída no mate el trabajo.