Comment ça marche
Une machine derrière un NAT ne peut pas accepter de connexions entrantes, mais elle peut en établir de sortantes. Elle se connecte donc à un serveur à adresse publique et lui demande d'écouter sur un port. Les connexions vers ce port reviennent par la connexion SSH déjà ouverte.
Pour les deux autres types de redirection, voyez les tunnels SSH locaux, distants et dynamiques.
Se connecter en SSH à la machine cachée
La machine cachée doit avoir son propre serveur SSH en marche. Sur la machine cachée :
ssh -N -o ExitOnForwardFailure=yes -R 2222:localhost:22 user@server
-N n'exécute aucune commande distante. -R 2222:localhost:22 signifie que le port 2222 du serveur mène au port 22 de cette machine. Ajoutez -f pour passer en arrière-plan.
Sur le serveur, vous pouvez voir le port et l'utiliser :
$ ss -ltn | grep 2222
LISTEN 0 128 127.0.0.1:2222 0.0.0.0:*
LISTEN 0 128 [::1]:2222 [::]:*
$ ssh -p 2222 hiddenuser@localhost
Depuis votre portable, passez par le serveur en une seule étape :
ssh -J user@server -p 2222 hiddenuser@localhost
Pour ne pas mélanger les clés d'hôte, puisque localhost peut désigner de nombreuses machines, mettez ceci dans ~/.ssh/config :
Host home
HostName localhost
Port 2222
User hiddenuser
ProxyJump user@server
HostKeyAlias home
Montrer une application web locale
ssh -N -R 8080:localhost:3000 user@server
Désormais, curl http://localhost:8080/ sur le serveur atteint le port 3000 de votre machine. Dans notre essai, depuis une autre machine, curl http://server:8080/ était refusé tant que nous n'avions pas modifié GatewayPorts.
Avec le port 0, le serveur choisit un port libre et ssh l'affiche :
$ ssh -N -R 0:localhost:3000 user@server
Allocated port 33341 for remote forward to localhost:3000
GatewayPorts : qui peut atteindre le port
Ce réglage se trouve dans le sshd_config du serveur et vaut no par défaut. Ce que nous avons mesuré :
| GatewayPorts | -R 8080:... | -R 0.0.0.0:8080:... |
|---|---|---|
no | Boucle locale uniquement | Boucle locale uniquement, l'adresse est ignorée |
clientspecified | Boucle locale uniquement | Toutes les adresses, joignable depuis d'autres machines |
yes | Toutes les adresses | Toutes les adresses |
Avec yes, même -R localhost:8080:... écoutait sur toutes les adresses dans notre essai. Si vous avez besoin d'un accès depuis l'extérieur, clientspecified laisse le choix au client, et le pare-feu doit tout de même autoriser le port.
Garder le tunnel privé
- Laissez
GatewayPorts noet utilisez-Jcomme ci-dessus. Seule une personne pouvant se connecter au serveur peut alors atteindre le port. - N'oubliez pas les autres utilisateurs du serveur. La boucle locale est partagée par tous ceux qui y sont connectés. Ils peuvent atteindre le port, et le service derrière doit tout de même exiger sa propre authentification.
- Utilisez une clé et un compte dédiés au tunnel, puisque la machine derrière le NAT conserve une clé qui permet de se connecter à votre serveur. Le guide autossh présente une configuration restreinte testée.
Quand le port est déjà pris
Avec ExitOnForwardFailure=yes, ssh s'arrête et quitte avec le code 255 :
Error: remote port forwarding failed for listen port 2222
Sans cette option, vous n'obtenez qu'un Warning et ssh reste connecté sans tunnel, ce qui passe facilement inaperçu. Une cause fréquente est qu'une ancienne connexion occupe encore le port sur le serveur. AllowTcpForwarding no ou une règle PermitListen sur le serveur provoque le même genre d'échec.
Le laisser tourner
Un simple ssh -R s'arrête quand la connexion tombe, et rien ne le relance. Pour un tunnel permanent, suivez autossh et systemd.
Questions
Quelle différence entre ssh -L et ssh -R ?
-L ouvre un port sur votre machine qui mène à quelque chose que le serveur peut joindre. -R fait l'inverse : il ouvre un port sur le serveur qui ramène à votre machine.
Pourquoi les autres machines n'atteignent-elles pas le port du tunnel inverse ?
Avec la valeur par défaut GatewayPorts no, le serveur n'écoute que sur sa boucle locale. Mettez GatewayPorts clientspecified ou yes dans sshd_config et ouvrez le port dans le pare-feu.
Comment garder un tunnel SSH inverse actif ?
Un simple ssh -R s'arrête quand la connexion tombe. Lancez-le avec autossh et systemd pour qu'il redémarre tout seul.