2009-09-08 13:04:22 +0000 2009-09-08 13:04:22 +0000
244
244

¿Cómo mantener abierto un túnel SSH de forma fiable?

Utilizo un túnel SSH desde el trabajo para rodear varios firewalls idoticos (le parece bien a mi jefe :)). El problema es que al cabo de un rato la conexión ssh suele colgarse y el túnel se rompe.

Si al menos pudiera monitorizar el túnel automáticamente, podría reiniciar el túnel cuando se cuelgue, pero no he encontrado la forma de hacerlo.

¡Puntos extra para quien me diga cómo evitar que se me cuelgue la conexión ssh, por supuesto!

Respuestas (16)

296
296
296
2009-09-08 13:43:51 +0000

Parece que necesitas autossh . Esto monitoreará un túnel ssh y lo reiniciará cuando sea necesario. Lo hemos usado durante un par de años y parece funcionar bien.

autossh -M 20000 -f -N your_public_server -R 1234:localhost:22 -C

Más detalles sobre el parámetro -M aquí

40
40
40
2009-09-28 13:47:26 +0000

Todos los cortafuegos con estado se olvidan de una conexión después de no ver un paquete para esa conexión durante algún tiempo (para evitar que las tablas de estado se llenen de conexiones donde ambos extremos murieron sin cerrar la conexión). La mayoría de las implementaciones de TCP enviarán un paquete keepalive después de un largo tiempo sin escuchar al otro lado (2 horas es un valor común). Sin embargo, si hay un firewall con estado que se olvida de la conexión antes de que los paquetes keepalive puedan ser enviados, una conexión de larga duración pero inactiva morirá.

Si ese es el caso, la solución es evitar que la conexión quede inactiva. OpenSSH tiene una opción llamada ServerAliveInterval que se puede utilizar para evitar que la conexión esté inactiva durante demasiado tiempo (como ventaja, detectará cuando el peer haya muerto antes aunque la conexión esté inactiva).

24
24
24
2010-05-29 13:45:08 +0000

En su propia máquina mac o linux configurar su ssh mantener el servidor ssh vivo cada 3 minutos. Abra un terminal y vaya a su invisible .ssh en su casa:

cd ~/.ssh/

luego crea un archivo de configuración de 1 línea con:

echo "ServerAliveInterval 180" >> config

también debe añadir:

ServerAliveCountMax xxxx (high number)

el valor por defecto es 3 así que ServerAliveInterval 180 dejará de enviar después de 9 minutos (3 del intervalo de 3 minutos especificado por ServerAliveInterval).

23
23
23
2009-09-22 14:58:15 +0000

He utilizado el siguiente script de Bash para seguir generando nuevos túneles ssh cuando el anterior muere. El uso de un script es útil cuando no quieres o no puedes instalar paquetes adicionales o usar el compilador.

while true
do
  ssh <ssh_options> [user@]hostname
  sleep 15
done

Tenga en cuenta que esto requiere un archivo de claves para establecer la conexión automáticamente, pero eso es el caso de autossh, también.

21
21
21
2016-07-28 06:10:14 +0000

Systemd es ideal para esto.

Cree un archivo de servicio /etc/systemd/system/sshtunnel.service que contenga:

[Unit]
Description=SSH Tunnel
After=network.target

[Service]
Restart=always
RestartSec=20
User=sshtunnel
ExecStart=/bin/ssh -NT -o ServerAliveInterval=60 -L 5900:localhost:5900 user@otherserver

[Install]
WantedBy=multi-user.target

(Modifique el comando ssh para adaptarlo)

  • esto se ejecutará como usuario sshtunnel así que asegúrese de que el usuario existe primero
  • emita systemctl enable sshtunnel para configurarlo para que se inicie en el momento del arranque
  • emita systemctl start sshtunnel para que se inicie inmediatamente

Update Jan 2018 : algunas distros (e. g. Fedora 27) pueden utilizar la política SELinux para impedir el uso de SSH desde systemd init, en cuyo caso habrá que crear una política personalizada para proporcionar las exenciones necesarias.

11
11
11
2013-11-28 01:04:34 +0000

Me parece que estáis interpretando mal ServerAliveCountMax. Según entiendo en la documentación, es el número de mensajes de servidor vivo que pueden quedar sin respuesta sin que la conexión se termine. Así que en casos como el que estamos discutiendo aquí, ponerlo a un valor alto sólo asegurará que una conexión colgada no sea detectada y terminada.

El simple hecho de establecer ServerAliveInterval debería ser suficiente para resolver el problema de que un cortafuegos se olvide de la conexión, y dejar ServerAliveCountMax bajo permitirá que el extremo de origen se dé cuenta del fallo y termine si la conexión falla de todos modos.

Lo que quieres es, 1) que la conexión permanezca abierta permanentemente bajo circunstancias normales, 2) que el fallo de la conexión sea detectado y que el lado originario salga al fallar, y 3) que el comando ssh sea reemitido cada vez que salga (la forma de hacerlo depende mucho de la plataforma, el script “while true” sugerido por Jawa es una forma, en OS X en realidad configuro un elemento launchd).

9
9
9
2014-03-08 21:30:40 +0000

Utilice siempre la opción ServerAliveInterval SSH en caso de que los problemas del túnel se generen por sesiones NAT caducadas.

Utilice siempre un método de respawning en caso de que la conectividad se caiga por completo, aquí tiene al menos tres opciones:

  • programa autossh
  • script bash (while true do ssh ...; sleep 5; done) no elimine el comando sleep, ssh puede fallar rápidamente y respawneará demasiados procesos
  • /etc/inittab, para tener acceso a una caja enviada e instalada en otro país, detrás de NAT, sin reenvío de puertos a la caja, puede configurarla para crear un túnel ssh de vuelta a usted:

  • script de arranque en Ubuntu, donde /etc/inittab no está disponible:

o utilizar siempre ambos métodos.

6
6
6
2013-05-30 13:32:05 +0000

He solucionado este problema con esto:

Editar

~/.ssh/config

Y añadir

ServerAliveInterval 15
ServerAliveCountMax 4

Según página man para ssh_config:

ServerAliveCountMax
         Sets the number of server alive messages (see below) which may be
         sent without ssh(1) receiving any messages back from the server.
         If this threshold is reached while server alive messages are
         being sent, ssh will disconnect from the server, terminating the
         session. It is important to note that the use of server alive
         messages is very different from TCPKeepAlive (below). The server
         alive messages are sent through the encrypted channel and there‐
         fore will not be spoofable. The TCP keepalive option enabled by
         TCPKeepAlive is spoofable. The server alive mechanism is valu‐
         able when the client or server depend on knowing when a connec‐
         tion has become inactive.

         The default value is 3. If, for example, ServerAliveInterval
         (see below) is set to 15 and ServerAliveCountMax is left at the
         default, if the server becomes unresponsive, ssh will disconnect
         after approximately 45 seconds. This option applies to protocol
         version 2 only.

 ServerAliveInterval
         Sets a timeout interval in seconds after which if no data has
         been received from the server, ssh(1) will send a message through
         the encrypted channel to request a response from the server. The
         default is 0, indicating that these messages will not be sent to
         the server. This option applies to protocol version 2 only.
4
4
4
2015-06-06 23:41:10 +0000

ExitOnForwardFailure yes es un buen complemento a las otras sugerencias. Si se conecta pero no puede establecer el reenvío de puertos es tan inútil para usted como si no se hubiera conectado en absoluto.

1
1
1
2012-03-13 12:11:18 +0000

Un poco de un hack, pero me gusta usar la pantalla para mantener esto. Actualmente tengo un forward remoto que lleva semanas funcionando.

Ejemplo, comenzando localmente:

screen
ssh -R ......

Cuando el forward remoto se aplica, y tienes un shell en el ordenador remoto:

screen
Ctrl + a + d

Ahora tienes un forward remoto ininterrumpido. El truco es ejecutar la pantalla en ambos extremos

1
1
1
2015-07-30 14:02:55 +0000

Recientemente tuve este problema yo mismo, porque estas soluciones requieren que usted vuelva a introducir la contraseña cada vez que si se utiliza un inicio de sesión de contraseña que he utilizado sshpass en un bucle junto con un mensaje de texto para evitar que la contraseña en el archivo por lotes.

Pensé en compartir mi solución en este thead en caso de que alguien más tiene el mismo problema:

#!/bin/bash
read -s -p "Password: " pass
while true
do
    sshpass -p "$pass" ssh user@address -p port
    sleep 1
done
1
1
1
2009-09-08 14:09:33 +0000

mientras que hay herramientas como autossh que ayuda a reiniciar la sesión ssh… lo que encuentro realmente útil es ejecutar el comando ‘screen’. Te permite REANUDAR tus sesiones ssh incluso después de desconectarte. Especialmente útil si tu conexión no es tan fiable como debería.

…no olvides marcar que esta es la respuesta ‘correcta’ si te ayuda k! ;-)

1
1
1
2009-09-08 13:17:28 +0000

He tenido la necesidad de mantener un túnel SSH a largo plazo. Mi solución se ejecutaba desde un servidor Linux, y es sólo un pequeño programa en C que respawns ssh utilizando la autenticación basada en claves.

No estoy seguro de que se cuelgue, pero he tenido túneles que mueren debido a los tiempos de espera.

Me encantaría proporcionar el código para el respawner, pero no puedo encontrarlo ahora mismo.

0
0
0
2017-07-15 00:04:11 +0000

Como autossh no satisface nuestras necesidades (existe con error si no puede conectarse al servidor en el primer intento), hemos escrito una aplicación bash pura: https://github.com/aktos-io/link-with-server

Crea un túnel inverso para el puerto sshd del NODO (22) en el servidor por defecto. Si necesitas realizar cualquier otra acción (como reenviar puertos adicionales, enviar correos en conexión, etc…) puedes colocar tus scripts en las carpetas on-connect y on-disconnect.

0
0
0
2009-09-28 10:27:21 +0000

He tenido problemas similares con mi anterior ISP. Para mí era lo mismo con cualquier conexión tcp, visitando sitios web o enviando correo.

La solución fue configurar una conexión VPN sobre UDP (usaba OpenVPN). Esta conexión era más tolerante a lo que causaba las desconexiones. Entonces puedes ejecutar cualquier servicio a través de esta conexión.

Todavía puede haber problemas con la conexión pero ya que el túnel será más tolerante cualquier sesión ssh sentirá una breve retención en lugar de ser desconectada.

Para hacer esto necesitarás un servicio VPN online que puedes configurar en tu propio servidor.

0
0
0
2020-02-20 15:09:46 +0000

Puedes usar simplemente el comando tmux en tu servidor remoto. Le permite abrir una “sesión” en la máquina remota donde ejecutará su código remoto.

Luego puede salir (o perder la conexión en su caso) de la máquina remota sin preocuparse dado que su código se está ejecutando de forma segura en su sesión tmux.

Finalmente, cuando te vuelvas a conectar en el servidor remoto, sólo tienes que tmux attach para volver a la sesión que tenías abierta anteriormente y ya está.

Preguntas relacionadas

6
10
3
19
3