Le tunneling SSH sur Linux crée des canaux chiffrés pour faire transiter le trafic réseau entre machines, vous permettant d’accéder à des services derrière des pare-feux, de chiffrer des protocoles non sécurisés, et de construire des chemins sécurisés à travers des réseaux non fiables. Que vous ayez besoin d’atteindre une base de données sur un réseau privé, d’exposer votre serveur de développement local à un collègue, ou de router le trafic de votre navigateur via un point de sortie de confiance, la redirection de ports SSH répond à tous ces besoins avec les outils déjà installés sur chaque système Linux. Ce guide couvre les trois types de redirection avec des configurations éprouvées en production.
Prérequis
- Deux machines Linux avec accès SSH (ou un client Linux et n’importe quel serveur SSH)
- Client OpenSSH installé localement (
ssh -Vpour vérifier) - Serveur OpenSSH actif sur la machine distante (
sshd) - Compréhension de base des ports TCP et du modèle client-serveur
- Authentification par clé SSH configurée (recommandé — voir l’article associé)
Comprendre les Types de Tunnels SSH
SSH supporte trois modes de redirection distincts. Chacun correspond à un cas d’usage différent :
| Type | Option | Direction | Cas d’usage |
|---|---|---|---|
| Redirection locale | -L | Machine locale → destination distante | Accéder à une base de données, interface web ou service distant |
| Redirection distante | -R | Serveur distant → machine locale | Exposer un serveur de dev local, permettre l’accès distant à des services locaux |
| Redirection dynamique | -D | Proxy SOCKS local → n’importe quelle destination via le distant | Navigation sécurisée, routage de tout le trafic via SSH |
Les trois chiffrent le trafic de bout en bout entre votre client SSH et le serveur SSH. Le trafic entre le serveur SSH et la destination finale n’est pas chiffré par SSH (il circule sur le réseau local du serveur).
Redirection de Port Locale (-L)
La redirection locale est le type le plus courant. Elle ouvre un port sur votre machine locale et envoie le trafic à travers le tunnel SSH vers une destination spécifique accessible depuis le serveur distant.
Syntaxe
ssh -L [bind_address:]local_port:destination:dest_port user@ssh_server
Exemple : Accéder à une Base de Données Distante
Vous avez une base de données PostgreSQL sur db.internal port 5432 qui n’est accessible que depuis le serveur applicatif app.example.com. Votre laptop ne peut pas atteindre db.internal directement.
# Rediriger le port local 5432 vers db.internal:5432 via app.example.com
ssh -L 5432:db.internal:5432 admin@app.example.com
Connectez-vous ensuite à la base de données en local :
psql -h localhost -p 5432 -U myuser mydb
Chemin du trafic : laptop:5432 → tunnel SSH → app.example.com → db.internal:5432
Exemple : Accéder à une Interface Web Distante
Un tableau de bord de monitoring tourne sur http://monitor.internal:3000 derrière un pare-feu :
# Rediriger le port local 8080 vers le tableau de bord distant
ssh -L 8080:monitor.internal:3000 admin@jumpbox.example.com
# Ouvrir dans le navigateur
# http://localhost:8080
Tunnel en Arrière-Plan (Sans Shell)
Ajoutez -f -N pour lancer le tunnel en arrière-plan sans ouvrir un shell distant :
# -f = passe en arrière-plan après l'authentification
# -N = pas de commande distante (tunnel uniquement)
ssh -f -N -L 8080:monitor.internal:3000 admin@jumpbox.example.com
Pour fermer un tunnel en arrière-plan, trouvez et terminez le processus :
ps aux | grep 'ssh -f -N -L'
kill <PID>
Écouter sur Toutes les Interfaces
Par défaut, -L s’attache uniquement à localhost. Pour permettre à d’autres machines de votre réseau d’utiliser le tunnel :
# Écouter sur toutes les interfaces (0.0.0.0)
ssh -L 0.0.0.0:8080:monitor.internal:3000 admin@jumpbox.example.com
# Ou s'attacher à une interface spécifique
ssh -L 192.168.1.100:8080:monitor.internal:3000 admin@jumpbox.example.com
Avertissement de sécurité : Écouter sur 0.0.0.0 expose le tunnel à tout votre réseau local. Ne faites cela que sur des réseaux de confiance.
Redirection de Port Distante (-R)
La redirection distante fonctionne en sens inverse — elle ouvre un port sur le serveur distant et renvoie le trafic vers votre machine locale.
Syntaxe
ssh -R [bind_address:]remote_port:destination:dest_port user@ssh_server
Exemple : Exposer un Serveur de Développement Local
Vous développez une application web sur localhost:3000 et souhaitez qu’un collègue sur le serveur distant puisse y accéder :
# Ouvrir le port 9000 sur le serveur distant, redirigé vers votre port local 3000
ssh -R 9000:localhost:3000 admin@remote.example.com
Désormais, n’importe qui sur remote.example.com peut accéder à votre serveur de dev local via http://localhost:9000.
Exemple : Accès Distant à un Service Local
Votre machine au bureau expose un service sur le port 8443 et vous souhaitez y accéder depuis chez vous via un serveur cloud :
# Depuis la machine au bureau :
ssh -R 8443:localhost:8443 user@cloud-server.example.com
Depuis chez vous, connectez-vous en SSH sur le serveur cloud et accédez à localhost:8443.
Autoriser les Connexions Externes
Par défaut, les ports redirigés à distance s’attachent à localhost sur le serveur distant. Pour autoriser un accès externe, le serveur SSH doit avoir GatewayPorts activé :
# Sur le serveur SSH, modifiez /etc/ssh/sshd_config :
GatewayPorts yes # Permettre l'écoute sur toutes les interfaces
# ou
GatewayPorts clientspecified # Laisser le client choisir l'adresse d'écoute
Redémarrez ensuite sshd et spécifiez l’adresse d’écoute :
ssh -R 0.0.0.0:9000:localhost:3000 admin@remote.example.com
Redirection Dynamique (-D) — Proxy SOCKS
La redirection dynamique crée un proxy SOCKS5 local. Toute application configurée pour utiliser ce proxy fera transiter l’intégralité de son trafic à travers le tunnel SSH, avec le serveur distant comme point de sortie.
Syntaxe
ssh -D [bind_address:]port user@ssh_server
Exemple : Navigation Web Sécurisée
Vous êtes sur un réseau Wi-Fi non fiable et souhaitez faire passer tout le trafic de votre navigateur par votre serveur domestique :
# Créer un proxy SOCKS5 sur le port local 1080
ssh -D 1080 -f -N user@home-server.example.com
Configurez ensuite votre navigateur :
- Firefox : Paramètres → Paramètres réseau → Configuration manuelle du proxy → Hôte SOCKS :
localhost, Port :1080, SOCKS v5. Cochez “Utiliser un DNS distant lorsque SOCKS v5 est activé”. - Chrome (ligne de commande) :
google-chrome --proxy-server="socks5://localhost:1080" - Système entier (variable d’environnement) :
export ALL_PROXY=socks5://localhost:1080
Exemple : Router les Outils CLI via le Proxy
# Utiliser avec curl
curl --proxy socks5h://localhost:1080 https://ifconfig.me
# Utiliser avec git
git -c http.proxy=socks5h://localhost:1080 clone https://github.com/user/repo.git
# Le 'h' dans socks5h signifie que la résolution DNS se fait côté distant
Important : Utilisez socks5h:// (avec le h) pour résoudre le DNS via le proxy. Le simple socks5:// résout le DNS en local, ce qui expose vos requêtes DNS sur le réseau local.
Rendre les Tunnels Persistants avec autossh
Les tunnels SSH s’interrompent lorsque la connexion tombe (coupure réseau, mise en veille du laptop, redémarrage du serveur). autossh surveille la connexion et se reconnecte automatiquement.
Installation
# Debian / Ubuntu
sudo apt install autossh
# RHEL / Fedora
sudo dnf install autossh
# Arch Linux
sudo pacman -S autossh
Utilisation
# Redirection locale persistante avec autossh
autossh -M 0 -f -N -L 5432:db.internal:5432 admin@jumpbox.example.com
# Proxy SOCKS persistant
autossh -M 0 -f -N -D 1080 user@home-server.example.com
# Redirection distante persistante
autossh -M 0 -f -N -R 9000:localhost:3000 admin@remote.example.com
L’option -M 0 désactive le port de surveillance interne d’autossh et s’appuie sur le mécanisme keepalive natif de SSH (plus fiable et plus simple). Associez-la aux keepalives SSH dans votre configuration.
Lancer en tant que Service systemd
Pour des tunnels qui doivent survivre aux redémarrages, créez une unité systemd :
# /etc/systemd/system/ssh-tunnel-db.service
[Unit]
Description=SSH Tunnel to Database
After=network-online.target
Wants=network-online.target
[Service]
User=tunneluser
ExecStart=/usr/bin/autossh -M 0 -N -L 5432:db.internal:5432 admin@jumpbox.example.com
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now ssh-tunnel-db.service
sudo systemctl status ssh-tunnel-db.service
Configuration SSH pour des Tunnels Réutilisables
Plutôt que de taper de longues commandes, définissez vos tunnels dans ~/.ssh/config :
Host db-tunnel
HostName jumpbox.example.com
User admin
LocalForward 5432 db.internal:5432
ServerAliveInterval 60
ServerAliveCountMax 3
IdentityFile ~/.ssh/id_ed25519
Host socks-proxy
HostName home-server.example.com
User myuser
DynamicForward 1080
ServerAliveInterval 60
ServerAliveCountMax 3
IdentityFile ~/.ssh/id_ed25519
Host expose-dev
HostName remote.example.com
User admin
RemoteForward 9000 localhost:3000
ServerAliveInterval 60
ServerAliveCountMax 3
Utilisez-les ensuite par leur nom :
ssh -f -N db-tunnel
ssh -f -N socks-proxy
ssh -f -N expose-dev
Comparaison du Tunneling SSH avec les Alternatives
| Fonctionnalité | SSH Tunneling | WireGuard VPN | Cloudflare Tunnel | ngrok |
|---|---|---|---|---|
| Chiffrement | Oui (SSH) | Oui (WireGuard) | Oui (TLS) | Oui (TLS) |
| Logiciel serveur requis | sshd (universel) | Module noyau WireGuard | Démon cloudflared | Agent ngrok |
| Redirection par port | Oui | Non (réseau complet) | Oui | Oui |
| Proxy SOCKS | Oui (-D) | Non | Non | Non |
| Surcoût de performance | Modéré (TCP-over-TCP) | Faible (UDP, espace noyau) | Faible | Faible |
| Reconnexion persistante | Avec autossh | Intégrée | Intégrée | Intégrée |
| Coût | Gratuit | Gratuit | Offre gratuite disponible | Offre gratuite disponible |
| Idéal pour | Tunnels ponctuels, accès à des ports spécifiques | Accès réseau complet ou site-à-site | Exposer des services sur internet | Démos rapides, webhooks |
Utilisez le tunneling SSH quand vous avez besoin d’accéder rapidement à un ou deux ports spécifiques et que vous disposez déjà d’un accès SSH — aucun logiciel supplémentaire requis. Passez à WireGuard si vous avez besoin d’un accès réseau complet ou d’un débit élevé. Utilisez Cloudflare Tunnels ou ngrok pour exposer des services à des utilisateurs externes avec des URLs publiques.
Résolution de Problèmes
Le tunnel se connecte mais le trafic ne passe pas
# Vérifier que le tunnel écoute bien
ss -tlnp | grep <local_port>
# Vérifier que la destination est accessible depuis le serveur SSH
ssh admin@jumpbox.example.com "nc -zv db.internal 5432"
Si ss montre le port en écoute mais que les connexions restent bloquées, le service de destination refuse peut-être les connexions depuis l’IP du serveur SSH. Vérifiez les règles de pare-feu sur l’hôte destination.
”bind: Address already in use"
# Trouver ce qui utilise le port
sudo ss -tlnp | grep <port>
# Tuer l'ancien tunnel ou choisir un port local différent
ssh -L 15432:db.internal:5432 admin@jumpbox.example.com
"channel 3: open failed: administratively prohibited”
Le serveur SSH a la redirection TCP désactivée. L’administrateur du serveur doit configurer dans /etc/ssh/sshd_config :
AllowTcpForwarding yes
# ou pour la redirection locale uniquement :
AllowTcpForwarding local
Le tunnel se déconnecte après une période d’inactivité
Ajoutez des keepalives dans votre ~/.ssh/config :
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
Cela envoie un keepalive toutes les 60 secondes et déconnecte après 3 réponses manquées (3 minutes). Cela empêche les équipements NAT et les pare-feux à état de fermer la connexion TCP inactive.
Le port de redirection distante n’est pas accessible de l’extérieur
Vérifiez que GatewayPorts est activé sur le serveur SSH :
grep GatewayPorts /etc/ssh/sshd_config
Si la valeur est no ou absente, les ports redirigés à distance s’attachent uniquement à 127.0.0.1 sur le serveur.
Considérations de Sécurité
-
Restreindre la redirection dans authorized_keys : Limitez ce qu’une clé spécifique peut faire :
no-agent-forwarding,no-X11-forwarding,permitopen="db.internal:5432" ssh-ed25519 AAAA...Cette clé ne peut créer de tunnels que vers
db.internal:5432. -
Désactiver la redirection pour des utilisateurs spécifiques : Dans
/etc/ssh/sshd_config:Match User restricteduser AllowTcpForwarding no -
Performance TCP-over-TCP : Les tunnels SSH souffrent du problème TCP-over-TCP — les piles TCP interne et externe gèrent toutes deux les retransmissions, ce qui peut provoquer un backoff exponentiel sur des connexions à pertes. Pour du trafic nécessitant un débit élevé ou une faible latence, préférez WireGuard.
-
Auditer l’utilisation des tunnels : Surveillez les tunnels actifs sur vos serveurs :
# Afficher toutes les redirections de port SSH actives sudo ss -tlnp | grep sshd # Afficher les sessions SSH connectées avec redirection sudo lsof -i -n | grep ssh | grep LISTEN
Résumé
- La redirection locale (
-L) ramène les services distants sur votre machine locale — cas d’usage le plus courant pour accéder aux bases de données, tableaux de bord et API derrière des pare-feux - La redirection distante (
-R) expose des services locaux sur un serveur distant — utile pour le partage en développement et l’accès externe aux outils internes - La redirection dynamique (
-D) crée un proxy SOCKS5 — route le trafic de n’importe quelle application à travers le tunnel SSH pour une navigation sécurisée sur des réseaux non fiables - Utilisez
autosshpour des tunnels persistants qui résistent aux interruptions réseau, et les services systemd pour des tunnels qui doivent survivre aux redémarrages - Les fichiers de configuration SSH (
~/.ssh/config) éliminent les options répétitives en ligne de commande et rendent les tunnels réutilisables avec des noms simples - Ajoutez des keepalives (
ServerAliveInterval 60) pour empêcher les pare-feux de couper les tunnels inactifs