Question Comment garder un tunnel SSH ouvert?


J'utilise un tunnel SSH à partir du travail pour contourner divers pare-feu idotiques (ça va avec mon patron :)). Le problème est que, après un certain temps, la connexion ssh se bloque et que le tunnel est cassé.

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

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


200
2017-09-08 13:04


origine


C'est ton tunnel mort parce que l'inactivité? J'ai eu ce problème lors de la tunnellisation des ports de mon téléphone, alors j'ai fini par créer des commandes factices sur la connexion pour la rendre "vivante" en utilisant le watch commande comme: watch -n1 60 echo "wiiiii". Le tunnel ne mourra pas à moins que le réseau ne soit brisé ou que vous ne l'utilisiez pas. - erm3nda
En relation: unix.stackexchange.com/q/200239 - sampablokuper


Réponses:


On dirait que vous avez besoin autossh. Cela surveillera un tunnel ssh et le redémarrera si nécessaire. Nous l'avons utilisé pendant quelques années et cela 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


239
2017-09-08 13:43



+1 pour autossh, il fait ce qu'il dit sur la boîte. Je crois qu'une partie de ses fonctionnalités consiste également à envoyer des paquets de style «persistants» pour éviter tout délai d'attente. - akent
Pourriez-vous utiliser l'exemple de tunnel en utilisant autossh dans la réponse? - Ehtesh Choudhury
autossh -f -nNT -i ~/keypair.pem -R 2000:localhost:22 username@myoutsidebox.com   Vous remarquerez peut-être que je l'ai configuré avec -nNT qui ne crée pas de terminal distant pour que je puisse mettre en arrière-plan autossh et l'option -i pour que SSH utilise un fichier .pem. Si vous voulez garder une connexion ouverte tout le temps, je vous recommande vivement de passer par la configuration supplémentaire. - juckele
Pour ce qu’il vaut, il semble qu’il soit préférable d’omettre la -M paramètre: bugs.debian.org/cgi-bin/bugreport.cgi?bug=351162 - rinogo
Si cela ne fonctionne pas et que vous utilisez des clés, cochez cette réponse - serverfault.com/a/545093/288788 - muttonUp


Tous les pare-feu avec état oublient une connexion après ne pas avoir vu un paquet pour cette connexion pendant un certain temps (pour éviter que les tables d'état ne deviennent pleines de connexions où les deux extrémités sont mortes sans fermer la connexion). La plupart des implémentations TCP enverront un paquet keepalive après un long moment sans entendre de l'autre côté (2 heures est une valeur commune). Si, toutefois, il existe un pare-feu avec état qui oublie la connexion avant que les paquets keepalive puissent être envoyés, une connexion longue 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é pour empêcher la connexion d’être inactive pendant trop longtemps (en prime, elle détectera le moment où le pair est mort plus tôt, même si la connexion est inactive).


34
2017-09-28 13:47



L'intervalle spécifié est en secondes, vous pouvez donc apporter des modifications. Si votre pare-feu avec état a un délai d'inactivité de 5 minutes, 60 ou 120 secondes suffisent pour maintenir la connexion ouverte. C'est l'une des façons de garder mes sessions ssh ouvertes via mon routeur domestique. - Darren Hall
Merci, cela a aidé. Mais remarquez (d'après une réponse moins bien classée ici, superuser.com/a/146641/115515) Si vous spécifiez ServerAliveInterval et non ServerAliveCountMax, vous pouvez trouver ssh à se déconnecter intentionnellement plus tôt que vous ne le souhaitiez. - metamatt
@metamatt, cette réponse de moindre rang que vous avez mentionnée est moins bien classée pour une bonne raison: C'EST FAUX. - Lambart


Sur votre propre machine Mac ou Linux, configurez votre ssh pour maintenir le serveur ssh actif toutes les 3 minutes. Ouvrez un terminal et rendez-vous sur votre .ssh invisible chez vous:

cd ~/.ssh/ 

puis créez un fichier de configuration de 1 ligne avec:

echo "ServerAliveInterval 180" >> config

vous devriez également ajouter:

ServerAliveCountMax xxxx (high number)

la valeur par défaut est 3, ce qui signifie que ServerAliveInterval 180 arrête l'envoi après 9 minutes (3 des 3 minutes d'intervalle spécifiées par ServerAliveInterval).


22
2018-05-29 13:45



Notez que votre commande n'est pas recommandée si vous avez déjà un fichier de configuration. Utiliser >> pour la redirection serait beaucoup mieux! - Peltier
pourquoi ServerAliveInterval 180 donnez-nous 6 minutes? l'intuition me fait essayer ceci: 180/60 == 3. Alors, est-ce que ServerAliveInterval travailler en multiples de 30 secondes? - nemesisfixx
@mcnemesis: ServerAliveInterval 180 signifie 3 minutes. ServerAliveCountMax par défaut 3 signifie 3 de ces intervalles, soit 9 minutes. - metamatt
Je vote cette réponse parce que merci de mentionner ServerAliveCountMax, et que se passe-t-il si vous spécifiez ServerAliveInterval sans ServerAliveCountMax. Mais comme les commentaires précédents, je remarque que le calcul sur "cessera d’envoyer après" est faux, et je pense que cette réponse serait plus utile si elle donnait simplement les informations sur ces options, sans nous dire comment les appliquer avec les commandes cd et echo . - metamatt
Réduire le nombre de votes, car cela n'a aucun sens de définir ServerAliveCountMax sur un "nombre élevé". ServerAliveCountMax spécifie combien de fois il essaiera d'envoyer le message "keepalive" avant d'abandonner. La valeur par défaut est 3, donc, avec ServerAliveInterval 180, il cessera d'envoyer UNIQUEMENT si le serveur N'A PAS RÉPONDU après 9 minutes, auquel cas votre connexion est probablement bien morte. - Lambart


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

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

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


20
2017-09-22 14:58



Vous devriez ajouter des raisons pour lesquelles vous utiliseriez ce script sur autossh, ou est-ce juste que c'est plus facile de cette façon? - kyrias
Cela n'aiderait pas si ssh lui-même se fige, n'est-ce pas? - nafg
Cela aide si vous ne pouvez pas installer des choses sur le serveur. autossh ne vient pas préinstallé et la bureaucratie c'est parfois très obtus. - quarkex
Oui, préférable de ne pas avoir à installer des choses. Je le fais depuis un an comme seul moyen de garder une machine distante accessible (et même de configurer crontab pour le lancer au redémarrage). Il n'a jamais échoué et, plus important encore, je sais pourquoi il ne manquera jamais. - sudo


Il est certain que vous interprétez mal ServerAliveCountMax. Si je comprends bien, c'est le nombre de messages sur le serveur qui peuvent rester sans réponse sans que la connexion ne soit interrompue. Donc, dans les cas où nous discutons ici, la valeur élevée garantira simplement qu'une connexion bloquée ne sera pas détectée et terminée!

Paramétrer simplement ServerAliveInterval devrait suffire à résoudre le problème avec un pare-feu oubliant la connexion, et laisser ServerAliveCountMax faible permettra à l'extrémité d'origine de constater l'échec et de se terminer si la connexion échoue de toute façon.

Qu'est-ce que vous voulez, 1) pour que la connexion reste ouverte en permanence dans des circonstances normales, 2) pour l'échec de connexion soit détecté et le côté de départ pour quitter en cas d'échec, et 3) pour la commande ssh à réémettre à chaque fois Exits (la façon dont vous faites cela dépend beaucoup de la plate-forme, le script "while true" proposé par Jawa est une façon, sous OS XI de configurer un élément launchd).


9
2017-11-28 01:04





Toujours utiliser ServerAliveInterval Option SSH au cas où les problèmes de tunnel seraient générés par des sessions NAT expirées.

Utilisez toujours une méthode de réapparition au cas où la connectivité diminuerait complètement, vous avez au moins trois options ici:

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

    tun1:2345:respawn:/usr/bin/ssh -i /path/to/rsaKey -f -N -o "ServerAliveInterval 180" -R 55002:localhost:22 user@publicip 'sleep 365d'
    
  • script upstart sur Ubuntu, où /etc/inittab n'est pas disponible:

    start on net-device-up IFACE=eth0
    stop on runlevel [01S6]
    respawn
    respawn limit 180 900
    exec ssh -i /path/to/rsaKey -N -o "ServerAliveInterval 180" -R 55002:localhost:22 user@publicip
    post-stop script
        sleep 5
    end script
    

ou utilisez toujours les deux méthodes.


9
2018-03-08 21:30



+1 pour l'option en ligne au cas où vous ne le souhaitiez pas pour toutes vos connexions SSH - user1146334
Vous écrivez "en cas de panne totale de la connectivité". Maintenant, je ne comprends pas, quels problèmes autossh se résout, et qu'est-ce que ça ne fait pas? Je pensais, bien sûr, qu’il s’agirait de briser une connexion, par exemple de débrancher le câble pendant quelques heures, mais peut-être pas? - Mads Skjern


Systemd convient parfaitement à 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

(Modifiez la commande ssh en fonction)

  • cela fonctionnera comme utilisateur sshtunnel alors assurez-vous que l'utilisateur existe en premier
  • problème systemctl enable sshtunnel pour le démarrer au démarrage
  • problème systemctl start sshtunnel pour commencer immédiatement

Mise à jour janvier 2018: certaines distributions (par exemple, Fedora 27) peuvent utiliser la stratégie SELinux pour empêcher l'utilisation de SSH à partir de systemd init, auquel cas une stratégie personnalisée doit être créée pour fournir les exemptions nécessaires.


8
2017-07-28 06:10



Cela ressemble beaucoup à mon esprit: gist.github.com/guettli/ Les commentaires sont les bienvenus! - guettli
Excellent pour un systemd système. Si on utilise Restart=on-failure puis, le fait de tuer manuellement le client SSH n'entraînera pas de redémarrage par le système en tant que client SSH avec une sortie réussie. - David Tonhofer
Si vous voulez démarrer ssh à partir d’un script (bash) donné en argument à ExecStart par exemple pour construire le ssh liste des arguments, faire des vérifications de base, etc. exec /bin/ssh -N .... Voici ma commande: 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}" où TUNNEL_INLET="127.0.0.1:3307" et TUNNEL_OUTLET="127.0.0.1:3306" - David Tonhofer


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

modifier

~/.ssh/config

Et ajouter

ServerAliveInterval 15
ServerAliveCountMax 4

Selon 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.

6
2018-05-30 13:32



Toutes les 15 secondes semblent assez souvent faire un ping sur le serveur. - Lambart
@Lambart mais si la connexion est vraiment instable et laisse tomber les connexions souvent, elle détecte au moins une connexion morte et donne la possibilité de réessayer plus tôt. - binki