Blog

Tunnel SSH ouvert, mais « connect failed: Connection refused »

Cette erreur ne vient pas de votre machine. Le message channel 2: open failed: connect failed: Connection refused est émis par le serveur SSH distant, qui a bien accepté votre tunnel mais n'a pas réussi à joindre l'hôte et le port demandés depuis là-bas. Le tunnel fonctionne ; c'est la seconde moitié du chemin qui est fermée, et c'est le service distant ou son pare-feu qu'il faut regarder, pas votre configuration SSH.

Qui envoie ce message ?

Un tunnel ssh -L est un chemin en deux moitiés. La première va de votre port local au serveur SSH : elle s'ouvre au lancement de la commande, et c'est elle que tout le monde regarde. La seconde va du serveur SSH à la cible que vous avez nommée, et elle ne s'ouvre qu'au moment où quelque chose se connecte : c'est le serveur qui tente alors ce raccordement, depuis son propre réseau, avec sa propre vision des adresses.

connect failed: Connection refused est le compte rendu de cette tentative. Le mot channel le trahit : un canal est ouvert dans une connexion SSH déjà établie. Si vous lisez ce message, l'authentification est passée depuis longtemps. Ce n'est ni une clé refusée ni un mot de passe : chercher de ce côté est la fausse piste la plus coûteuse de cette panne.

Pourquoi le tunnel a-t-il l'air ouvert ?

Parce qu'il l'est. Voici la panne reproduite en entier, avec un tunnel vers un port sur lequel rien n'écoute :

ssh -N -L 15433:127.0.0.1:59999 serveur
nc -z localhost 15433
Connection to localhost port 15433 [tcp/*] succeeded!
channel 2: open failed: connect failed: Connection refused

Les deux lignes disent chacune la vérité. nc a bien atteint le port local : la première moitié du chemin existe. Et au même instant, le serveur a échoué à joindre la cible : la seconde moitié n'existe pas. Un voyant, un test de port, un telnet local vous répondront tous que « le tunnel marche ». Ils ne testent que la moitié qui marche.

Votre postelocalhost:15433ouvertServeur SSHsshdconnect refuséCible127.0.0.1:59999
Les deux moitiés d'un tunnel : le message vient de la seconde.

Les quatre causes, de la plus fréquente à la plus sournoise

CauseCe qui s'est passéLe test qui la confirme
Le service ne tourne pasLa base ou l'application visée est arrêtée, ou a redémarré ailleursssh serveur 'nc -vz 127.0.0.1 5432' échoue aussi
Mauvais port ou mauvaise adresseUne faute de frappe dans la partie droite du -LRelire la commande : la cible est ce qui suit le premier deux-points
Le service n'écoute que sur localhostVous visez l'adresse réseau d'une machine dont le service est attaché à 127.0.0.1ssh serveur 'ss -tlnp' montre l'adresse d'écoute réelle
localhost n'est pas celui que vous croyezDans un -L, la cible est résolue par le serveur, pas par votre posteRemplacer le nom par une adresse IP explicite

Kestro fait cette distinction à votre place : il sépare « le tunnel est ouvert » de « la cible répond », et affiche laquelle des deux moitiés a échoué. La vérification manuelle ci-dessous reste la bonne méthode si vous n'avez pas envie d'un outil de plus, et le guide du tunnel qui tombe couvre les autres façons qu'a un tunnel de mentir.

Comment vérifier depuis le serveur, et non depuis chez vous ?

Le réflexe qui tranche tout : rejouer la connexion depuis l'endroit qui la tente réellement. Une seule commande suffit, et elle emprunte la session SSH qui existe déjà :

ssh serveur 'nc -vz 127.0.0.1 5432'

Si cette commande échoue, le problème est entièrement du côté du serveur : service arrêté, port faux, pare-feu local. Votre tunnel n'y est pour rien, et le relancer ne changera rien. Si elle réussit alors que le tunnel échoue toujours, comparez ce que vous avez écrit dans le -L avec ce que vous venez de tester : dans la quasi-totalité des cas restants, les deux ne visent pas la même chose.

Ce qui reste

Ce message a un frère presque identique, open failed: administratively prohibited, qui ne vient pas d'un port fermé mais d'un serveur configuré pour interdire les tunnels : la réponse est alors dans sshd_config, pas dans le service cible. Et si votre tunnel échoue seulement après une mise en veille, le symptôme se ressemble mais la cause est ailleurs : c'est le cas du tunnel mort après la veille. Enfin, la reproduction ci-dessus a été faite sur macOS avec OpenSSH ; le libellé exact du message peut varier d'une version à l'autre, le mécanisme, non.