Écran, ou similaire, pour reprendre automatiquement une connexion ssh feuilletée

18

Je dois souvent me connecter à un serveur via ssh dans un environnement wifi peu fiable. Sur le serveur, j'exécute l'écran, donc si je suis déconnecté, je peux me reconnecter et reprendre la session d'écran, et reprendre là où je m'étais arrêté, mais la perte de connexion est toujours un temps considérable: si la connexion tombe pendant que je suis sur le serveur, la fenêtre du terminal a tendance à se figer. Je dois tuer cet onglet, en ouvrir un nouveau, ssh à nouveau sur le serveur et reprendre la session d'écran. J'ai essayé ceci avec l'exécution de l'écran sur le serveur et de l'écran localement. Dans les deux cas, il a tendance à geler lorsque la connexion est interrompue.

Existe-t-il un moyen pour que je puisse avoir quelque chose de similaire à l'écran, ou peut-être l'écran lui-même, qui essaiera automatiquement de se reconnecter et de maintenir la session en cours, donc je n'ai pas à continuer de me reconnecter manuellement? Souvent, lorsque je perds la connexion, je pense que ce n'est que pour une très courte période - moins d'une seconde peut-être.

J'utilise Ubuntu 14.04 LTS, édition MATE. Merci

Max Williams
la source
4
Re "la fenêtre shell a tendance à se figer": C'est parce que votre ssh local ne sait pas que la connexion est morte. Appuyez <Enter>et tapez ~.pour dire à votre côté de supprimer la connexion, et vous pouvez simplement répéter la dernière commande ssh pour vous reconnecter (par exemple avec la flèche vers le haut ou !!).
alexis
@alexis qui sonne comme un moyen plus rapide de se reconnecter, merci! J'adorerais que cela se produise automatiquement ...
Max Williams

Réponses:

23

Vous pouvez regarder en utilisant mosh: https://mosh.org/

Vous pouvez configurer un serveur 'jump' avec une connexion Internet fiable à laquelle vous vous moshconnectez, puis avoir des sshsessions sur chaque serveur que vous gérez. La raison pour laquelle je suggère d'utiliser un serveur de saut est que vous ne souhaiterez peut-être pas installer moshsur les serveurs que vous gérez.

Un autre avantage moshest qu'il est basé sur UDP plutôt que TCP, et votre session peut survivre à un changement d'adresse IP, par exemple en passant du WiFi à une connexion Internet mobile.

Pour être clair, ce moshn'est pas un remplacement screen, mais plutôt ssh. C'est toujours une bonne idée de l'utiliser screenavec, car moshlui-même ne fournit pas un moyen de se reconnecter à votre session si le client décède pour une raison quelconque.

shackleford rouillé
la source
Merci, c'est juste un serveur (la plupart du temps) et nous le possédons donc je devrais pouvoir installer Mosh. Je vérifierai.
Max Williams
En fait, il s'avère que parce que notre serveur est assez ancien (ou exécutant un ancien Ubuntu, je devrais dire), il est trop difficile à installer. :(
Max Williams
@MaxWilliams quel âge a-t-il? Même LTS 12.4 n'est plus pris en charge. Et pourquoi ne pas simplement essayer de le compiler vous
phuclv
En lisant les documents mosh, vous avez besoin du serveur mosh sur chaque hôte que vous avez l'intention de gérer à distance. Pourtant, vraiment intéressant.
Wildcard
1
La connexion à un terminal tmux sur mosh est la solution la plus stable pour moi.
Nemo
3

J'utilise depuis tmuxquelques années maintenant et d'après mon expérience, il se reconnecte automatiquement. Au moins lorsque la connexion échoue uniquement pendant un temps relativement bref. Notez que j'utilise en fait byobuavec tmux comme backend. Je ne sais pas si cette robustesse est une caractéristique de tmuxou byobuou même de la combinaison des deux, mais je vous suggère d'essayer les deux.

Je me connecte depuis mon installation Arch locale à divers serveurs Ubuntu distants via un VPN. Je l'ai testé tout à l'heure en débranchant mon câble réseau alors que j'étais connecté à la télécommande. La session a été suspendue, mais dès que mon câble a été rebranché, il a repris sans problème.

Cependant, lorsque j'ai testé en redémarrant mon routeur, la connexion n'est pas revenue. Je suppose que cela a quelque chose à voir avec la durée de la panne du réseau, mais il semble se reconnecter si ce n'est que quelques secondes.

Si c'est pertinent, je fais tout cela en utilisant terminatormon émulateur de terminal.

Les trois sont disponibles dans les référentiels Ubuntu:

sudo apt-get install tmux terminator byobu

Cependant, je ne suis pas du tout sûr que ce soit tmuxou byobusont mieux à gérer les déconnexions ssh. Je sais seulement que d'après mon expérience, ils reviennent souvent de courtes pertes de connexion. Cela peut être dû à d'autres aspects de ma configuration.

terdon
la source
1
Lorsque vous avez redémarré votre routeur, vous avez peut-être reçu une adresse IP publique différente, ce qui aura interrompu la tcpconnexion. D'après mon expérience, il sshpeut être très résistant aux pannes de réseau intermittentes, je ne pense pas que cela ait quelque chose à voir avec le fait que vous utilisez tmuxà l'intérieur de la sshfenêtre.
rusty shackleford
3
J'allais dire la même chose: même avec SSH ordinaire, vous pouvez gérer une déconnexion courte, tant que la connexion TCP ne s'éteint pas. Ce qu'il pourrait, si votre interface est arrêtée, ou si un routeur trop zélé le tue (les routeurs NAT peuvent oublier l'état NAT au redémarrage et rompre les connexions existantes), ou ClientAlive/ ServerAlivedéclenche, ou ... Je n'ai aucune idée de ce qui se byobupasse, cependant .
ilkkachu
Oui, mais l'OP semble subir un gel en cas d'échec de connexion, alors que je ne le fais pas. Mais oui, vous avez raison, je le vois aussi avec ssh simple et sans tmux. Néanmoins, peut-être que l'écran ne peut pas y faire face?
terdon
2
@MaxWilliams tmuxest fondamentalement une alternative plus moderne à screen, oui. Quand j'ai commencé à travailler comme je le fais maintenant et que j'avais besoin de ce genre de chose, ma lecture superficielle a suggéré que c'était tmuxle meilleur choix de nos jours. Je ne suis pas sûr non plus à 100% qu'il ait une meilleure gestion des connexions perdues, tout ce que je sais, c'est qu'il se remet de brèves pannes d'après mon expérience. Que ce soit à tmuxcause d'autre chose, je ne sais pas. Mais cela semble valoir le coup :). Byobu est fondamentalement une interface pour screen / tmux, pas un émulateur de terminal GUI. Il est cependant extrêmement utile: byobu.org
terdon
2
tmux ne fait rien pour les interruptions de connexion. Il fonctionne avec le terminal fourni par ssh. Tout se tient et tombe avec la connexion ssh.
Jonas Schäfer
2

Utilisez les ServerAliveoptions de ssh pour détecter lorsque la connexion a échoué.

ServerAliveCountMax
Définit le nombre de messages actifs du serveur (voir ci-dessous) qui peuvent être envoyés sans que ssh (1) ne reçoive de message du serveur. Si ce seuil est atteint pendant l'envoi des messages du serveur actif, ssh se déconnecte du serveur, mettant fin à la session. Il est important de noter que l'utilisation des messages vivants du serveur est très différente de TCPKeepAlive (ci-dessous). Les messages du serveur vivant sont envoyés via le canal crypté et ne seront donc pas usurpés. L'option TCP keepalive activée par TCPKeepAlive est usurpée. Le mécanisme de serveur vivant est utile lorsque le client ou le serveur dépendent de savoir quand une connexion est devenue inactive.

La valeur par défaut est 3. Si, par exemple, ServerAliveInterval (voir ci-dessous) est défini sur 15 et ServerAliveCountMax est laissé par défaut, si le serveur ne répond plus, ssh se déconnectera après environ 45 secondes.

ServerAliveInterval
Définit un délai d'expiration en secondes après lequel si aucune donnée n'a été reçue du serveur, ssh (1) enverra un message via le canal crypté pour demander une réponse du serveur. La valeur par défaut est 0, indiquant que ces messages ne seront pas envoyés au serveur.

Donc, si vous définissez ServerAliveIntervalsur 5, sshse déconnectera automatiquement si le réseau s'éteint pendant 15 secondes.

Barmar
la source
Pour interrompre une session SSH par la force, j'appuie ~.(ou d'abord sur Entrée, puis ~.) composé de: le caractère d'échappement ~et la commande pour interrompre la session.
imz - Ivan Zakharyaschev
@ imz - IvanZakharyaschev Cela suppose que vous pouvez dire que la connexion est interrompue. L'utilisation de keepalive de SSH détectera automatiquement l'échec.
Barmar
Cela semble vraiment utile, merci, je vais certainement essayer la prochaine fois que je serai dans la "zone feuilletée".
Max Williams
@Barmar Oui, c'est vrai. J'ai également pensé au problème de déterminer si la connexion est vraiment bloquée, ou si j'appuie sur quelque chose peut accidentellement envoyer ces touches du côté distant ... Et je ne connais pas de bonne solution.
imz - Ivan Zakharyaschev
2

Dans des conditions similaires, j'ai tendance à utiliser eshellTRAMP (sur ssh) dans Emacs. TRAMP s'occupe de se reconnecter si nécessaire sans me causer beaucoup de problèmes en donnant les commandes souhaitées pour le shell distant.

Cependant, eshell n'est pas bon en tant que terminal, c'est-à-dire pour exécuter des commandes qui font quelque chose de spécial avec le terminal, ou qui s'exécutent pendant une période de temps continue (incrémentielle) pour imprimer quelque chose.

Fondamentalement, il est assez simple de commencer à l'utiliser dans Emacs avec TRAMP:

M-x eshell
cd /user@host:
imz - Ivan Zakharyaschev
la source
1

Avertissement

Si votre connexion SSH ne survit pas à de brèves pannes de réseau, alors il se passe autre chose qui ne permet pas à sshTCP de faire son travail normal.

Voir ci-dessous pour plus de détails. En tous cas:

La solution sans dépendances la plus rapide et la plus sale

Créez un script shell comme celui-ci:

#!/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"

Cela exécutera simplement une boucle stupide-simple qui continue d'essayer de se connecter sshet de s'y attacher screen. Passez l'hôte ou tout ce que vous passez normalement à votre sshappel en tant qu'arguments de ligne de commande.

La reconnexion est simplement basée sur le fait que SSH signale une erreur avec la connexion, ce qui signifie qu'il n'a aucune intelligence pour détecter les erreurs non SSH comme "vous n'avez littéralement pas WiFI activé" ou autre, mais cela n'a probablement pas d'importance pour vous.

Je suppose que vous avez ssh-agentou une clé SSH sans phrase de passe qui permettra aux reconnexions de fonctionner sans aucune entrée supplémentaire de votre part.

Il va y avoir une petite condition de course où si vous frappez ^Cpendant juste la bonne fraction de seconde imperceptible par l'homme pendant une reconnexion, vous pourriez finir par tuer le script au lieu de passer ^Cpar le terminal client, donc si vous suspectez une connexion de se bloquer ne pas écraser ^Ctrop zélé.

Solution logicielle supplémentaire la plus simple

Vous pouvez essayer le programme autossh , qui devrait être disponible dans votre référentiel de paquets Ubuntu.

Si vous avez besoin de construire à partir de la source ou de l'auditer, c'est un seul programme C qui se compile sans bibliothèques supplémentaires en tant que dépendances, semble avoir plus d'informations sur la vérification de la vivacité de la connexion que mon hack ci-dessus, et il est également livré avec une rscreencommande de script pratique qui auto -attache à screen.

Détails

Comment sshrécupère normalement

Juste pour vérifier, parce que je n'aime pas dire des choses sans me vérifier, j'ai fait un petit test avant de répondre:

Je me suis connecté à mon WiFi avec un appareil Linux, j'ai établi une connexion SSH avec un autre appareil sur mon LAN, vérifié que j'avais une sshconnexion fonctionnelle à l'autre extrémité (je pouvais exécuter des commandes, etc.), puis le client a déconnecté le WiFi (provoquant l'interface à déconfigurer: plus d'adresses IP), tapé un tas de caractères dans la session ssh (pas de réponse, bien sûr), puis reconnecté à mon WiFi - la reconnexion a en fait échoué au moins une fois en raison d'un mauvais signal et d'autres facteurs , puis finalement reconnecté: j'ai attendu environ cinq secondes pour que la sshsession se rétablisse, rien ne s'est passé alors j'ai appuyé sur une touche de plus, et la sshsession a repris vie immédiatement, avec toutes les clés que j'avais tapées lors de la déconnexion apparaissant sur la ligne de commande.

Vous voyez, il sshsuffit d'écrire / lire dans le socket réseau TCP jusqu'à ce que le système d'exploitation lui dise que quelque chose s'est mal passé, et TCP est en fait très tolérant aux chutes de connexion prolongées.

Laissée à ses propres appareils avec les paramètres de noyau par défaut, la pile TCP sous Linux tolérera volontiers la connexion complètement silencieuse pendant plusieurs minutes avant de déclarer la connexion morte et de signaler une erreur ssh- au moment où elle abandonne finalement, nous parlons dans le stade approximatif de ~ 30 minutes, ou du moins certainement assez longtemps pour survivre à des hoquets de connexion qui durent une seconde ou une minute.

Sous les couvertures, la pile Linux TCP réessaye progressivement les messages avec des délais de plus en plus longs, cependant, ce qui signifie qu'au moment où votre connexion revient, vous pourriez envisager un décalage supplémentaire avant que votre sshsession ne semble à nouveau "vivante".

Pourquoi cela casse parfois

Souvent, quelque chose provoque activement la fermeture de la connexion après une période d'inactivité considérablement plus courte que la quantité tolérée par la pile TCP, puis ne signale pas cet état de connexion à votre sshclient.

Les candidats probables comprennent:

  1. Pare-feu ou routeurs NAT, qui doivent utiliser de la mémoire pour se souvenir de chaque connexion TCP en direct - en tant qu'optimisation et atténuation contre les attaques DOS, ils oublient parfois simplement votre connexion, puis ignorent silencieusement les paquets conséquents pour cela, car les paquets dans le au milieu d'une connexion lorsque vous ne vous souvenez pas que la connexion existante n'est pas valide.

  2. Les pare-feu / routeurs qui se comportent mieux injectent un paquet TCP RST, qui se manifeste généralement sous la forme d'un connection reset by peermessage d'erreur, mais le paquet de réinitialisation est un feu et oublie, donc si la connexion à votre client rencontre toujours des problèmes à ce moment-là et abandonne le réinitialiser le paquet aussi, votre client pensera que la connexion est toujours active.

  3. Le serveur lui - même peut avoir une politique de pare-feu pour supprimer silencieusement les paquets inattendus, ce qui interromprait les tentatives de reprise de connexion du client chaque fois que le serveur pense que la connexion est fermée mais pas le client: votre client continue d'essayer de continuer la connexion, mais le serveur est juste l'ignorer car il n'y a pas de connexion active à laquelle ces paquets appartiennent dans l'état du pare-feu du serveur.

    Puisque vous utilisez Linux, vérifiez soigneusement iptables/ / ip6tablesou nftsi vous utilisez les nouveaux éléments de votre serveur pour savoir exactement ce que vous autorisez par rapport à la suppression. Il est très courant d'autoriser les paquets nouveaux / établis / associés sur le port TCP SSH, mais pas les paquets "non valides" - si vous supprimez silencieusement tout ce qui n'est pas autorisé, cette configuration courante pourrait provoquer ce genre de gel après de brefs problèmes de connexion .

  4. Votre serveur SSH lui-même peut être configuré pour fermer la connexion après une période d'inactivité, en utilisant l'une des options OpenSSH pour les paquets persistants du client TCP ou SSH. En soi, cela ne provoquera pas de blocages indéfinis, mais cela peut vous mettre dans l'un des états décrits ci-dessus.

  5. Il est possible que vous ne lui laissiez pas suffisamment de temps pour «se désengager» de lui-même après être entré dans l'état où votre sshsession raccroche.

mtraceur
la source