SSH : tunnels et rebonds
Un tunnel SSH fait passer un trafic réseau dans une connexion chiffrée. Les exemples utilisent un serveur monserveur (alias défini dans Configuration du client).
Redirection locale (-L) : atteindre un service distant
Section intitulée « Redirection locale (-L) : atteindre un service distant »Donne accès, depuis le poste local, à un port vu depuis le serveur (par exemple une base de données qui n’écoute qu’en local) :
ssh -N -L 5432:127.0.0.1:5432 monserveur| Élément | Signification |
|---|---|
-L 5432:127.0.0.1:5432 |
Port local 5432 → adresse 127.0.0.1:5432 vue du serveur |
-N |
Ne lance pas de commande (tunnel seul) |
-f |
Passe en arrière-plan après l’authentification |
Pendant que la commande tourne :
psql -h 127.0.0.1 -p 5432 -U app boutique # se connecte à PostgreSQL du serveurmysql -h 127.0.0.1 -P 3306 -u app -p # même principe pour MySQL (-L 3306:127.0.0.1:3306)Pour accéder à une machine tierce depuis le serveur : -L 8080:10.0.0.30:80 (le port 80 de 10.0.0.30, vu du serveur).
Le tunnel écoute par défaut sur 127.0.0.1 du poste local : seuls les programmes de ce poste l’utilisent. Éviter -L 0.0.0.0:5432:… qui l’ouvre au réseau local.
Redirection distante (-R) : exposer un service local
Section intitulée « Redirection distante (-R) : exposer un service local »Rend un port du poste local accessible depuis le serveur :
ssh -N -R 9100:127.0.0.1:8000 monserveurSur le serveur, curl http://127.0.0.1:9100/ atteint le service qui écoute sur le port 8000 du poste (par exemple pour présenter un site en développement). Par défaut, le port distant n’écoute que sur 127.0.0.1 du serveur.
Pour l’exposer à d’autres machines, activer GatewayPorts clientspecified dans sshd_config (déconseillé sans pare-feu) et utiliser -R 0.0.0.0:9100:127.0.0.1:8000.
Proxy SOCKS dynamique (-D)
Section intitulée « Proxy SOCKS dynamique (-D) »ssh -N -D 1080 monserveurcurl --socks5-hostname 127.0.0.1:1080 https://exemple.com/Les navigateurs ou outils configurés avec le proxy SOCKS 127.0.0.1:1080 sortent par le serveur. --socks5-hostname fait aussi résoudre les noms par le serveur.
Rebond : -J et ProxyJump
Section intitulée « Rebond : -J et ProxyJump »Atteindre une machine qui n’est joignable que par un serveur intermédiaire (« bastion ») :
ssh -J monserveur deploy@10.0.0.20ssh -J bastion1,bastion2 deploy@10.0.0.20 # plusieurs rebondsscp -J monserveur fichier deploy@10.0.0.20:/tmp/Dans ~/.ssh/config :
Host interne HostName 10.0.0.20 User deploy ProxyJump monserveurLes données restent chiffrées de bout en bout entre le poste et la machine finale : le bastion ne voit pas le contenu. La clé privée reste sur le poste (contrairement à ssh -A, à éviter).
Options utiles
Section intitulée « Options utiles »| Option | Rôle |
|---|---|
-N |
Pas de commande distante |
-f |
Arrière-plan (après authentification) |
-o ExitOnForwardFailure=yes |
Quitte si le tunnel ne peut pas être établi (indispensable dans un script) |
-o ServerAliveInterval=30 |
Maintient et détecte la coupure du tunnel |
-g |
Autorise d’autres machines à utiliser un tunnel -L local (prudence) |
ssh -f -N -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -L 5432:127.0.0.1:5432 monserveurArrêter un tunnel en arrière-plan :
pgrep -af "ssh -f -N" # repérer le processuspkill -f "ssh -f -N -o ExitOnForwardFailure=yes"Tunnel permanent avec systemd
Section intitulée « Tunnel permanent avec systemd »Un service systemd relance le tunnel automatiquement s’il tombe (voir systemd : services). Fichier /etc/systemd/system/tunnel-bdd.service sur le poste (ou la machine qui doit toujours avoir le tunnel) :
[Unit]Description=Tunnel SSH vers la base de donnéesAfter=network-online.targetWants=network-online.target
[Service]User=deployExecStart=/usr/bin/ssh -NT -o ExitOnForwardFailure=yes -o ServerAliveInterval=30 -o ServerAliveCountMax=3 -o StrictHostKeyChecking=yes -L 5432:127.0.0.1:5432 monserveurRestart=alwaysRestartSec=10
[Install]WantedBy=multi-user.targetsudo systemctl daemon-reloadsudo systemctl enable --now tunnel-bddsystemctl status tunnel-bddLe compte deploy doit disposer de la clé (sans phrase secrète, ou via un agent) et du serveur dans known_hosts. Pour cette clé de tunnel, limiter ses droits côté serveur (restrict,port-forwarding,permitopen="127.0.0.1:5432" dans authorized_keys).
Restreindre ce qu’un tunnel peut atteindre
Section intitulée « Restreindre ce qu’un tunnel peut atteindre »Dans authorized_keys du serveur, une clé destinée à un seul tunnel :
restrict,port-forwarding,permitopen="127.0.0.1:5432" ssh-ed25519 AAAAC3Nza… tunnel-bddrestrict retire tous les droits, port-forwarding rend les redirections possibles, et permitopen les limite à la destination indiquée.
Dépannage
Section intitulée « Dépannage »| Symptôme | Piste |
|---|---|
bind [127.0.0.1]:5432: Address already in use |
Le port local est déjà utilisé : un autre tunnel, ou PostgreSQL local. Changer le port local (-L 15432:127.0.0.1:5432) |
channel 2: open failed: connect failed: Connection refused |
Rien n’écoute à la destination vue du serveur (mauvais port ou adresse) |
administratively prohibited: open failed |
AllowTcpForwarding no sur le serveur, ou permitopen qui ne l’autorise pas |
| Le tunnel se coupe après un moment | Ajouter ServerAliveInterval ; utiliser le service systemd ci-dessus |
Warning: remote port forwarding failed for listen port |
Port distant déjà pris, ou -R interdit |
| Le tunnel marche mais l’application ne se connecte pas | Utiliser 127.0.0.1 (et non localhost, qui peut résoudre en IPv6) |
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Manuel :
man ssh(options-L,-R,-D,-J) - Suite : Transfert de fichiers