Le tunnel SSH survit à la veille du Mac, mais plus rien ne passe
Publié le 14 août 2026Brouillon
Après la veille du Mac, le tunnel ne marche plus, et pourtant tout a l'air normal : le processus ssh est toujours là, le port local écoute toujours. Ce qui est mort, c'est la connexion TCP sous-jacente, fermée par le réseau pendant le sommeil, et SSH ne le découvre qu'à la première écriture. Ce décalage entre l'apparence et l'état réel est toute la panne, et il se répare par deux lignes de configuration.
Pourquoi le processus est-il vivant et le tunnel mort ?
Parce que personne n'a prévenu SSH. Une connexion TCP au repos n'échange rien : tant qu'aucun octet ne circule, aucune des deux extrémités ne peut savoir que l'autre a disparu. Pendant que le Mac dort, le monde continue sans lui : le serveur finit par fermer la session restée muette, une box NAT oublie la correspondance qui la portait, un pare-feu jette l'entrée de sa table. Rien de tout cela ne produit le moindre signal vers une machine endormie.
Au réveil, le processus ssh reprend exactement où il s'était arrêté, avec un descripteur de connexion que plus rien ne relie à quoi que ce soit. Il ne s'en apercevra qu'en essayant d'écrire dedans, c'est-à-dire au moment précis où vous vous en servez. D'où l'impression d'un tunnel « instable » : il n'est pas instable, il est mort depuis le réveil et personne ne le lui a dit.
Le test qui dit la vérité
Tester le port local ne prouve rien, et c'est le piège central de cette panne : nc -z localhost 5433 répond « succeeded » dès lors que le processus écoute, même quand le chemin derrière est mort. La preuve est dans l'anatomie de « connect failed: Connection refused », où ce test réussit pendant que la connexion échoue.
Le test honnête fait un aller-retour complet. Ouvrez une vraie connexion à travers le tunnel, avec un délai court, et regardez ce que dit le processus ssh au même moment :
psql "host=localhost port=5433 connect_timeout=3" -c 'select 1'
Trois issues possibles. La requête répond : le tunnel est vraiment vivant. Elle échoue immédiatement pendant que le tunnel affiche channel open failed : la session SSH est vivante mais la cible ne répond plus. Elle reste suspendue puis expire sans que le tunnel ne dise rien : la session SSH elle-même est morte, et c'est le cas de la veille.
ServerAliveInterval : ce qu'il répare, ce qu'il ne répare pas
Par défaut, SSH ne teste jamais sa propre connexion. Deux lignes changent cela :
Host *
ServerAliveInterval 30
ServerAliveCountMax 3
Toutes les 30 secondes d'inactivité, le client envoie une sonde ; après 3 sondes sans réponse, il abandonne et se termine. C'est la moitié du travail : une session morte est désormais détectée en une minute et demie au plus, au lieu de rester vivante en apparence pour toujours. Un processus qui meurt est un état honnête : votre prochaine commande échoue franchement au lieu de rester suspendue.
Ce que ce réglage ne fait pas : rouvrir le tunnel. SSH constate le décès, il n'organise pas la succession. Il ne retient pas non plus la connexion pendant la veille : la sonde ne circule pas pendant que la machine dort, et c'est très bien ainsi. Empêcher le Mac de dormir avec caffeinate n'est pas une solution à cette panne, c'est sa négation : on ne gère pas le réveil en supprimant le sommeil, on paie juste la batterie.
La reprise, c'est la moitié qui reste. Kestro rouvre les tunnels au réveil de la machine, précisément parce qu'un processus vivant ne prouve rien, et le guide du tunnel qui tombe donne la version manuelle complète, boucle de relance comprise.
Ce qui reste
Le délai exact entre le réveil et la détection dépend du réglage et du moment où la sonde part ; nous ne publions pas encore de mesure chiffrée, elle viendra avec sa méthode. Reste aussi le cas du réseau qui change au réveil, du Wi-Fi de la maison à celui du bureau : la connexion est alors morte pour une autre raison, mais le remède est le même, détecter vite et rouvrir. Et si votre tunnel meurt sans veille, en pleine session, le symptôme est proche mais la piste est ailleurs : commencez par « bind: Address already in use » si la relance échoue, ou par le message exact que le processus affiche.