Descargo de responsabilidad

Descargo de responsabilidad

A menudo tengo que conectarme a un servidor a través de ssh en un entorno wifi no confiable. En el servidor, ejecuto screen, de modo que si me desconecto, puedo volver a conectarme y reanudar la sesión de screen, y continuar donde lo dejé, pero la pérdida de conexión sigue siendo una gran pérdida de tiempo: si la conexión se interrumpe mientras estoy Estoy en el servidor, la ventana del terminal tiende a congelarse. Tengo que cerrar esa pestaña, abrir una nueva, conectarme nuevamente al servidor y reanudar la sesión de pantalla. Intenté esto ejecutando la pantalla en el servidor y la pantalla localmente. De cualquier manera, tiende a congelarse cuando se interrumpe la conexión.

¿Hay alguna manera de tener algo similar a la pantalla, o tal vez a la pantalla misma, que intente reconectarse automáticamente y mantener la sesión en ejecución, para no tener que volver a conectarme manualmente? A menudo, cuando pierdo la conexión creo que es sólo por un período muy breve, tal vez menos de un segundo.

Estoy usando Ubuntu 14.04 LTS, edición MATE. gracias

Respuesta1

Podrías considerar usar mosh:https://mosh.org/

Puede configurar un servidor de "salto" con una conexión a Internet confiable que utilice moshpara conectarse y luego tener sshsesiones en cada servidor que administre. La razón por la que sugiero usar un servidor de salto es que es posible que no desee instalarlo moshen los servidores que está administrando.

Otra ventaja moshes que se basa en UDP en lugar de TCP, y su sesión puede sobrevivir a un cambio de dirección IP, por ejemplo, pasar de WiFi a una conexión a Internet móvil.

Solo para que quede claro, moshno es un reemplazo de screen, sino más bien ssh. Sigue siendo una buena idea usarlo screencon él, ya que moshen sí mismo no proporciona una forma de volver a conectarse a su sesión si el cliente muere por algún motivo.

Respuesta2

Utilice las opciones de ssh ServerAlivepara detectar cuando la conexión ha fallado.

ServerAliveCountMax
Establece el número de mensajes activos del servidor (ver más abajo) que pueden enviarse sin que ssh(1) reciba ningún mensaje del servidor. Si se alcanza este umbral mientras se envían mensajes del servidor activo, ssh se desconectará del servidor y finalizará la sesión. Es importante tener en cuenta que el uso de mensajes activos del servidor es muy diferente de TCPKeepAlive (a continuación). Los mensajes activos del servidor se envían a través del canal cifrado y, por lo tanto, no serán suplantables. La opción TCP keepalive habilitada por TCPKeepAlive es falsificada. El mecanismo del servidor activo es valioso cuando el cliente o el servidor dependen de saber cuándo una conexión se ha vuelto inactiva.

El valor predeterminado es 3. Si, por ejemplo, ServerAliveInterval (ver más abajo) se establece en 15 y ServerAliveCountMax se deja en el valor predeterminado, si el servidor deja de responder, ssh se desconectará después de aproximadamente 45 segundos.

ServerAliveInterval
Establece un intervalo de tiempo de espera en segundos después del cual, si no se han recibido datos del servidor, ssh(1) enviará un mensaje a través del canal cifrado para solicitar una respuesta del servidor. El valor predeterminado es 0, lo que indica que estos mensajes no se enviarán al servidor.

Entonces, si lo configura ServerAliveIntervalen 5, sshse desconectará automáticamente si la red falla durante 15 segundos.

Respuesta3

he estado usandotmuxDesde hace unos años y, según mi experiencia, se vuelve a conectar automáticamente. Al menos cuando la conexión falla sólo durante un tiempo relativamente breve. Tenga en cuenta que en realidad usobyobucon tmux como backend. No sé si esta robustez es una característica de los dos tmuxo byobuincluso de la combinación de ellos, pero te sugiero que pruebes ambos.

Me conecto desde mi instalación local de Arch a varios servidores remotos de Ubuntu a través de una VPN. Lo probé hace un momento desconectando el cable de red mientras estaba conectado al control remoto. La sesión se colgó, pero tan pronto como volví a enchufar el cable, se reanudó sin problemas.

Sin embargo, cuando probé reiniciando mi enrutador, la conexión no volvió. Supongo que tiene algo que ver con el tiempo que estuvo inactiva la red, pero parece volver a conectarse si solo está inactiva unos segundos.

En caso de que sea relevante, hago todo esto usandoterminatorcomo mi emulador de terminal.

Los tres están disponibles en los repositorios de Ubuntu:

sudo apt-get install tmux terminator byobu

Sin embargo, no estoy del todo seguro de que alguno de los dos tmuxsea byobumejor manejando las desconexiones ssh. Solo sé que, según mi experiencia, a menudo se recuperan de pérdidas breves de conexión. Sin embargo, eso puede deberse a otros aspectos de mi configuración.

Respuesta4

Descargo de responsabilidad

Si su conexión SSH no sobrevive a breves cortes de red, entonces hayalgo másEsto no permite sshque TCP haga su trabajo normal.

Consulte a continuación para obtener más detalles. De todos modos:

La solución sin dependencias más rápida y sucia

Cree un 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"

Esto simplemente ejecutará un bucle estúpidamente simple que sigue intentando conectarse sshy adjuntarse a screen. Pase el host o cualquier otra cosa que normalmente pasaría a su sshinvocación como argumentos de línea de comando.

La reconexión se basa simplemente en si SSH informa un error con la conexión, lo que significa que no tiene inteligencia para detectar errores que no sean SSH como "literalmente no tienes WiFI activado" o lo que sea, pero eso probablemente no importe. tú.

Supongo que tiene ssh-agentuna clave SSH sin contraseña que permitirá que las reconexiones funcionen sin ninguna entrada adicional de su parte.

Habrá una pequeña condición de carrera en la que, si presionas ^Cdurante la fracción de segundo correcta, imperceptible para los humanos, durante una reconexión, podrías terminar matando el script en lugar de pasarlo ^Ca la terminal del cliente, por lo que si sospechas que una conexión se bloquea. no tritures ^Ccon demasiado entusiasmo.

La solución de software adicional más sencilla

Puedes probar el programa.autossh, que debería estar disponible en su repositorio de paquetes de Ubuntu.

Si necesita compilar desde la fuente o auditarlo, es un único programa C que se compila sin bibliotecas adicionales como dependencias, parece tener más inteligencia para verificar la vivacidad de la conexión que mi truco anterior.yTambién viene con un práctico rscreencomando de script que se adjunta automáticamente a screen.

Detalles

¿Cómo sshse recupera normalmente?

Sólo para comprobarlo, porque no me gusta decir cosas sin comprobarlo, hice una pequeña prueba antes de responder:

Entré en mi WiFi con un dispositivo Linux, hice una conexión SSH a otro dispositivo en mi LAN, verifiqué que tenía una sshconexión funcional con el otro extremo (podía ejecutar comandos, etc.), luego en el clientedesconectado el wifi(lo que provocó que la interfaz se desconfigurara: no más direcciones IP), escribí muchos caracteres más en la sesión ssh (sin respuesta, por supuesto) y luego me volví a conectar a mi WiFi; la reconexión en realidad falló al menos una vez debido a un problema señal y otros factores, finalmente me reconecté: esperé unos cinco segundos para que la sshsesión se recuperara, no pasó nada, así que presioné una tecla más y la sshsesión inmediatamente volvió a la vida, con todas las teclas que había escrito durante la desconexión apareciendo en la línea de comando.

Mira, sshsimplemente escribe/lee en el socket de red TCP hasta que el sistema operativo le dice que algo salió mal, y TCP en realidad esmuytolerante a caídas prolongadas de conexión.

Si se la deja a su suerte con la configuración predeterminada del kernel, la pila TCP en Linux tolerará felizmente que la conexión quede completamente silenciosa durante muchos minutos antes de declararla muerta e informar un error; sshpara cuando finalmente se dé por vencida, ya estamos hablando del estadio. de ~30 minutos, o al menos lo suficientemente largo como para superar los problemas de conexión que duran un segundo o un minuto.

Debajo de las cubiertas, la pila TCP de Linux reintenta gradualmente los mensajes con retrasos cada vez más largos, lo que significa que cuando su conexión se restablezca, es posible que esté observando un retraso adicional antes de que su sshsesión parezca volver a estar "viva".

¿Por qué esto a veces se rompe?

A menudo, algo está provocando activamente que la conexión se cierre después de algún tiempo.significativamente más cortoperíodo de inactividad mayor que la cantidad que tolera la pila TCP y luego no informar ese estado de conexión a su sshcliente.

Los posibles candidatos incluyen:

  1. Firewalls o enrutadores NAT, que tienen que usar memoria para recordar cada conexión TCP activa; como optimización y cierta mitigación contra los ataques de DOS, a veces simplementeolvidarsu conexión, y luegoignorar silenciosamentepaquetes consiguientes para ello, porque los paquetes en medio de una conexión cuando no recuerda la conexión existente parecen no válidos.

  2. Los cortafuegos/enrutadores que se comportan mejor inyectarán un paquete TCP RST, que normalmente se manifiesta como un connection reset by peermensaje de error, pero el paquete de reinicio es de tipo "disparar y olvidar", por lo que si la conexión con su cliente todavía tiene problemas en ese momento y se interrumpe reinicie el paquete también, su cliente pensará que la conexión aún está activa.

  3. El servidorsí mismopodría tener una política de firewall para descartar silenciosamente paquetes inesperados, lo que interrumpiría los intentos de reanudación de la conexión del cliente cada vez que el servidor piensa que la conexión se cerró pero el cliente no: su cliente sigue intentando continuar la conexión, pero el servidor simplemente la ignora porque no hay ninguna conexión activa a la que pertenezcan estos paquetes en el estado del firewall del servidor.

    Dado que está ejecutando Linux, verifique cuidadosamente el iptables/ de su servidor ip6tables(o nftsi está usando cosas nuevas) para saber exactamente qué está permitiendo en lugar de eliminarlo. Es muy común permitirnuevo/establecido/relacionadopaquetes en el puerto TCP SSH, peronolos "no válidos": si elimina silenciosamente todo lo que no está permitido, esta configuración común podría causar este tipo de congelaciones después de breves problemas de conexión.

  4. Su propio servidor SSH puede estar configurado para cerrar la conexión después de un período de inactividad, utilizando una de las opciones de OpenSSH para paquetes de mantenimiento de conexión de cliente TCP o SSH. Por sí solo, esto no causará bloqueos indefinidos, pero puede ponerlo en uno de los estados descritos anteriormente.

  5. Es posible que simplemente no le estés dando suficiente tiempo para "descolgarse" por sí solo después de llegar al estado en el que la sshsesión se cuelga.

información relacionada