Utilizo un túnel SSH del trabajo para sortear varios firewalls idóticos (está bien con mi jefe :)). El problema es que, después de un tiempo, la conexión ssh generalmente se cuelga y el túnel se rompe.
Si al menos pudiera monitorear el túnel automáticamente, podría reiniciar el túnel cuando se cuelga, pero ni siquiera he encontrado una forma de hacerlo.
¡Puntos de bonificación para quien pueda decirme cómo evitar que se cuelgue mi conexión ssh, por supuesto!
watch
comando como:watch -n1 60 echo "wiiiii"
. El túnel no morirá a menos que la red esté rota o no la use.Respuestas:
Parece que necesitas autossh . Esto monitoreará un túnel ssh y lo reiniciará según sea necesario. Lo hemos usado durante un par de años y parece funcionar bien.
Más detalles sobre el parámetro -M aquí
fuente
autossh
en la respuesta?autossh -f -nNT -i ~/keypair.pem -R 2000:localhost:22 [email protected]
Puede notar que configuré esto usando -nNT que no crea un terminal remoto para que pueda poner autossh en segundo plano, y la opción -i para que SSH use un archivo .pem. Si va a mantener una conexión abierta todo el tiempo, definitivamente recomiendo pasar por la configuración adicional.-M
parámetro: bugs.debian.org/cgi-bin/bugreport.cgi?bug=351162Todos los firewalls 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 mucho tiempo sin escuchar del 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 se puedan enviar los paquetes keepalive, una conexión inactiva de larga duración 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 usar para evitar que la conexión permanezca inactiva durante demasiado tiempo (como beneficio adicional, detectará cuándo el par murió antes incluso si la conexión está inactiva).
fuente
En su propia máquina Mac o Linux, configure su ssh y mantenga vivo el servidor ssh cada 3 minutos. Abra una terminal y vaya a su .ssh invisible en su hogar:
luego cree un archivo de configuración de 1 línea con:
también deberías agregar:
el valor predeterminado es 3, por lo que ServerAliveInterval 180 dejará de enviarse después de 9 minutos (3 del intervalo de 3 minutos especificado por ServerAliveInterval).
fuente
ServerAliveInterval 180
nos da 6 minutos? intuición me hace intentar esto:180/60 == 3
. Entonces, ¿ServerAliveInterval
funciona en múltiplos de 30 segundos?He usado el siguiente script Bash para seguir generando nuevos túneles ssh cuando el anterior muere. Usar un script es útil cuando no quiere o no puede instalar paquetes adicionales o usar el compilador.
Tenga en cuenta que esto requiere un archivo de claves para establecer la conexión automáticamente, pero ese también es el caso con autossh.
fuente
Systemd es ideal para esto.
Cree un archivo de servicio que
/etc/systemd/system/sshtunnel.service
contenga:(Modifique el comando ssh para adaptarlo)
sshtunnel
así que asegúrese de que el usuario exista primerosystemctl enable sshtunnel
para configurarlo para que se inicie en el momento del arranquesystemctl start sshtunnel
para comenzar de inmediatoActualización de enero de 2018 : algunas distribuciones (por ejemplo, Fedora 27) pueden usar la política de SELinux para evitar el uso de SSH desde systemd init, en cuyo caso será necesario crear una política personalizada para proporcionar las exenciones necesarias.
fuente
systemd
sistema. Si se usaRestart=on-failure
, matar manualmente al cliente SSH no dará como resultado un reinicio por systemd como el cliente SSH con salida con éxito.ExecStart
por ejemplo, construir lassh
lista de argumentos, realice comprobaciones básicas, etc. y luego llámelo desde el script de esta maneraexec /bin/ssh -N ...
. Aquí está mi comando:exec /bin/ssh -N -oExitOnForwardFailure=Yes -oTCPKeepAlive=no -oServerAliveInterval=5 -oServerAliveCountMax=6 -i "${LOCAL_PRIVATE_KEY}" -L "${TUNNEL_INLET}:${TUNNEL_OUTLET}" "${REMOTE_USER}@${REMOTE_MACHINE}"
dóndeTUNNEL_INLET="127.0.0.1:3307"
yTUNNEL_OUTLET="127.0.0.1:3306"
Me parece seguro que todos están malinterpretando ServerAliveCountMax. Según tengo entendido los documentos, es la cantidad de mensajes activos del servidor que pueden quedar sin respuesta sin que se finalice la conexión. Entonces, en casos como los que estamos discutiendo aquí, establecerlo en un valor alto solo garantizará que no se detecte y finalice una conexión bloqueada.
Simplemente configurar ServerAliveInterval debería ser suficiente para resolver el problema con un firewall que se olvida de la conexión, y dejar ServerAliveCountMax bajo permitirá que el extremo de origen note la falla y termine si la conexión falla de todos modos.
Lo que desea es 1) que la conexión permanezca abierta permanentemente en circunstancias normales, 2) que se detecte la falla de conexión y que el lado de origen salga en caso de falla, y 3) que se vuelva a emitir el comando ssh cada vez que salidas (la forma en que lo hace depende mucho de la plataforma, el script "verdadero" sugerido por Jawa es unidireccional, en OS XI realmente configuró un elemento lanzado).
fuente
Utilice siempre la
ServerAliveInterval
opción SSH en caso de que los problemas del túnel sean generados por sesiones NAT expiradas.Siempre use un método de reaparición en caso de que la conectividad se caiga por completo, tiene al menos tres opciones aquí:
while true do ssh ...; sleep 5; done
) no elimina el comando de suspensión,ssh
puede fallar rápidamente y reaparecerá 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 para usted:script de inicio en Ubuntu, donde
/etc/inittab
no está disponible:o siempre use ambos métodos.
fuente
Resolví este problema con esto:
Editar
Y añadir
Según la página de manual de ssh_config:
fuente
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 como si no se hubiera conectado en absoluto.fuente
He tenido la necesidad de mantener un túnel SSH a largo plazo. Mi solución se ejecutaba desde un servidor Linux, y es solo un pequeño programa en C que reaparece ssh usando autenticación basada en claves.
No estoy seguro acerca de la ejecución, pero he tenido túneles muertos debido a los tiempos de espera.
Me encantaría proporcionar el código para el respawner, pero parece que no puedo encontrarlo en este momento.
fuente
mientras que hay herramientas como autossh que ayudan a reiniciar la sesión ssh ... lo que encuentro realmente útil es ejecutar el comando 'screen'. Le permite REANUDAR sus sesiones ssh incluso después de desconectarse. Especialmente útil si su conexión no es tan confiable como debería ser.
... no olvide marcar esta es la respuesta 'correcta' si le ayuda k! ;-)
fuente
Un poco hack, pero me gusta usar la pantalla para mantener esto. Actualmente tengo un avance remoto que ha estado funcionando durante semanas.
Ejemplo, comenzando localmente:
Cuando se aplica el reenvío remoto, y tiene un shell en la computadora remota:
Ahora tiene un avance remoto ininterrumpido. El truco es ejecutar la pantalla en ambos extremos
fuente
Recientemente tuve este problema, porque estas soluciones requieren que vuelva a ingresar la contraseña cada vez que use una contraseña de inicio de sesión. Usé sshpass en un bucle junto con un mensaje de texto para evitar tener la contraseña en el archivo por lotes.
Pensé que compartiría mi solución en este tema en caso de que alguien más tenga el mismo problema:
fuente
He tenido problemas similares con mi ISP anterior. Para mí fue lo mismo con cualquier conexión tcp, visitar sitios web o enviar correos.
La solución fue configurar una conexión VPN a través de UDP (estaba usando OpenVPN). Esta conexión fue más tolerante con lo que causó las desconexiones. Entonces puede ejecutar cualquier servicio a través de esta conexión.
Todavía puede haber problemas con la conexión, pero dado que el túnel será más tolerante, cualquier sesión ssh sentirá una breve interrupción en lugar de desconectarse.
Para hacer esto, necesitará un servicio VPN en línea que puede configurar en su propio servidor.
fuente
Como
autossh
no satisface nuestras necesidades (existe con error si no puede conectarse al servidor en el primer intento), hemos escrito una aplicación de bash puro: https://github.com/aktos-io/link- con servidorCrea un túnel inverso para el puerto sshd del NODE (22) en el servidor de forma predeterminada. Si necesita realizar otras acciones (como reenviar puertos adicionales, enviar correos electrónicos en conexión, etc.) puede colocar sus scripts
on-connect
yon-disconnect
carpetas.fuente