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

Comment maintenir un tunnel SSH ouvert de manière fiable ?

J'utilise un tunnel SSH du travail pour contourner divers pare-feux idiots (c'est bon pour mon patron :)). Le problème, c'est qu'au bout d'un moment, la connexion ssh est généralement interrompue, et le tunnel est rompu.

Si je pouvais au moins surveiller le tunnel automatiquement, je pourrais le redémarrer lorsqu'il est suspendu, mais je n'ai même pas trouvé le moyen de le faire.

Points bonus pour celui qui peut me dire comment empêcher ma connexion ssh de se bloquer, bien sûr !

Réponses (16)

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

On dirait que vous avez besoin de autossh . Cette fonction permet de surveiller un tunnel ssh et de le redémarrer si nécessaire. Nous l'utilisons depuis quelques années et il semble bien fonctionner.

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

Plus de détails sur le paramètre -M ici

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

Tous les pare-feu d'état oublient une connexion après n'avoir pas vu un paquet pour cette connexion pendant un certain temps (pour éviter que les tables d'état ne se remplissent de connexions dont les deux extrémités sont mortes sans fermer la connexion). La plupart des implémentations TCP envoient un paquet keepalive après un long moment sans avoir de nouvelles de l'autre côté (2 heures est une valeur courante). Cependant, si un pare-feu à état actif oublie la connexion avant que les paquets keepalive puissent être envoyés, une connexion de longue durée mais inactive mourra.

Si tel est le cas, la solution consiste à empêcher la connexion de devenir inactive. OpenSSH a une option appelée ServerAliveInterval qui peut être utilisée pour empêcher la connexion d'être inactive trop longtemps (en bonus, elle détectera le moment où le pair est mort plus tôt même si la connexion est inactive).

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

Sur votre propre machine mac ou linux, configurez votre ssh et maintenez le serveur ssh actif toutes les 3 minutes. Ouvrez un terminal et installez votre .ssh invisible chez vous :

cd ~/.ssh/

puis créez un fichier de configuration d'une ligne avec :

echo "ServerAliveInterval 180" >> config

vous devez également ajouter :

ServerAliveCountMax xxxx (high number)

la valeur par défaut est 3 donc ServerAliveInterval 180 arrêtera d'envoyer après 9 minutes (3 de l'intervalle de 3 minutes spécifié par ServerAliveInterval).

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

J'ai utilisé le script Bash suivant pour continuer à créer de nouveaux tunnels ssh lorsque le précédent meurt. L'utilisation d'un script est pratique lorsque vous ne voulez ou ne pouvez pas installer de paquets supplémentaires ou utiliser le compilateur.

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

Notez que cela nécessite un fichier clé pour établir la connexion automatiquement mais c'est aussi le cas avec autossh.

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

Systemd est parfaitement adapté pour cela.

Créer un fichier de service /etc/systemd/system/sshtunnel.service contenant :

[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

(Modifier la commande ssh en conséquence)

  • ce fichier sera exécuté sous l'utilisateur sshtunnel donc assurez-vous que l'utilisateur existe d'abord
  • émettre systemctl enable sshtunnel pour le faire démarrer au démarrage
  • émettre systemctl start sshtunnel pour le faire démarrer immédiatement

Mise à jour Jan 2018 : quelques distros (e. g. Fedora 27) peuvent utiliser la politique SELinux pour empêcher l'utilisation de SSH de systemd init, auquel cas une politique personnalisée devra être créée pour fournir les exemptions nécessaires.

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

Il me semble que vous interprétez tous mal ServerAliveCountMax. Si j'ai bien compris la documentation, c'est le nombre de messages “Server alive” qui peuvent rester sans réponse sans que la connexion ne soit interrompue. Donc, dans des cas comme celui dont nous parlons ici, le régler à une valeur élevée ne fera que garantir qu'une connexion suspendue ne sera pas détectée et terminée !

Le simple fait de régler ServerAliveInterval devrait suffire à résoudre le problème d'un pare-feu qui oublie la connexion, et laisser ServerAliveCountMax à une valeur basse permettra à l'extrémité d'origine de remarquer l'échec et de mettre fin à la connexion si celle-ci échoue de toute façon.

Ce que vous voulez, c'est 1) que la connexion reste ouverte en permanence dans des circonstances normales, 2) que l'échec de la connexion soit détecté et que le côté d'origine sorte en cas d'échec, et 3) que la commande ssh soit réémise à chaque fois qu'elle sort (la façon dont vous faites cela dépend beaucoup de la plate-forme, le script “while true” suggéré par Jawa est un moyen, sous OS X, je configure en fait un élément de lancement).

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

Utilisez toujours l'option ServerAliveInterval SSH au cas où les problèmes du tunnel sont générés par des sessions NAT expirées.

Utilisez toujours une méthode de respawning au cas où la connectivité serait entièrement défaillante, vous avez au moins trois options ici :

  • programme autossh
  • bash script (while true do ssh ...; sleep 5; done) ne supprimez pas la commande sleep, ssh peut échouer rapidement et vous respawnerez trop de processus
  • /etc/inittab, pour avoir accès à une boîte expédiée et installée dans un autre pays, derrière le NAT, sans redirection de port vers la boîte, vous pouvez la configurer pour créer un tunnel ssh qui vous reviendra :

  • script de démarrage sur Ubuntu, où /etc/inittab n'est pas disponible :

ou toujours utiliser les deux méthodes.

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

J'ai résolu ce problème avec cela :

Modifier

~/.ssh/config

Et ajouter

ServerAliveInterval 15
ServerAliveCountMax 4

Selon la page de manuel pour 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 est un bon complément aux autres suggestions. Si elle se connecte mais ne peut pas établir la redirection de port, elle vous est aussi inutile que si elle n'était pas connectée du tout.

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

C'est un peu un piratage, mais j'aime bien utiliser l'écran pour garder ça. J'ai actuellement un transfert à distance qui fonctionne depuis des semaines.

Exemple, en commençant localement :

screen
ssh -R ......

Lorsque le transfert à distance est appliqué et que vous avez un shell sur l'ordinateur distant :

screen
Ctrl + a + d

Vous avez maintenant un renvoi distant ininterrompu. L'astuce consiste à exécuter l'écran aux deux extrémités

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

J'ai moi-même eu ce problème récemment, car ces solutions exigent que vous saisissiez à nouveau le mot de passe à chaque fois que vous utilisez un mot de passe de connexion ; j'ai utilisé sshpass en boucle avec une invite textuelle pour éviter d'avoir le mot de passe dans le fichier du lot.

J'ai pensé que je pourrais partager ma solution sur ce site au cas où quelqu'un d'autre aurait le même problème :

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

Bien qu'il existe des outils comme autossh qui aident à redémarrer la session ssh… ce que je trouve vraiment utile, c'est d'exécuter la commande “screen”. Elle vous permet de RESUMEZ vos sessions ssh même après vous être déconnecté. C'est particulièrement utile si votre connexion n'est pas aussi fiable qu'elle devrait l'être.

…n'oubliez pas de cocher la “bonne” réponse si cela vous aide k ! ;-)

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

J'ai eu besoin de maintenir un tunnel SSH à long terme. Ma solution fonctionnait à partir d'un serveur Linux, et ce n'est qu'un petit programme en C qui respawns ssh en utilisant une authentification basée sur une clé.

Je ne suis pas sûr de l'accrochage, mais j'ai eu des tunnels qui sont morts à cause de dépassements de temps.

J'aimerais bien fournir le code pour le respawner, mais je n'arrive pas à le trouver pour l'instant.

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

Comme autossh ne répond pas à nos besoins (il existe avec une erreur s'il ne peut pas se connecter au serveur dès la première tentative), nous avons écrit une application purement bash : https://github.com/aktos-io/link-with-server

Elle crée un tunnel inverse pour le port sshd (22) du NODE sur le serveur par défaut. Si vous avez besoin d'effectuer d'autres actions (comme transférer des ports supplémentaires, envoyer des mails à la connexion, etc…) vous pouvez placer vos scripts on-connect et on-disconnect dans des dossiers.

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

J'ai eu des problèmes similaires avec mon ancien fournisseur d'accès Internet. Pour moi, c'était la même chose avec n'importe quelle connexion tcp, en visitant des sites web ou en envoyant du courrier.

La solution a été de configurer une connexion VPN sur UDP(j'utilisais OpenVPN). Cette connexion était plus tolérante à l'égard de ce qui provoquait les déconnexions. Vous pouvez donc faire fonctionner n'importe quel service grâce à cette connexion.

Il peut toujours y avoir des problèmes avec la connexion mais comme le tunnel sera plus tolérant, toute session ssh ressentira un court retard plutôt que d'être déconnectée.

Pour ce faire, vous aurez besoin d'un service VPN en ligne que vous pourrez installer sur votre propre serveur.

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

Vous pourriez très simplement utiliser la commande tmux sur votre serveur distant. Elle vous permet d'ouvrir une “session” sur la machine distante où votre code distant sera exécuté.

Vous pouvez alors quitter (ou perdre la connexion dans votre cas) la machine distante sans vous inquiéter puisque votre code s'exécute en toute sécurité dans votre session tmux.

Enfin, lorsque vous vous reconnectez sur le serveur distant, il vous suffit de tmux attach pour revenir à la session que vous aviez ouverte précédemment et c'est tout.