Dans cette leçon, tu vas découvrir comment créer des tunnels SSH pour sécuriser tes connexions réseau. Le port forwarding te permet d'accéder à des services distants comme si ils tournaient en local — un outil indispensable pour administrer des serveurs et accéder à des services protégés.
Par défaut, beaucoup de services (bases de données, interfaces web) écoute uniquement en localhost pour des raisons de sécurité. SSH te permet de créer un tunnel chiffré pour y accéder à distance.
C'est le plus courant. Tu rediriges un port de ta machine locale vers un service sur la machine distante.
# Syntaxe
ssh -L [port_local]:localhost:[port_distant] user@serveur
# Exemple : accéder à une interface web distante sur le port 80
ssh -L 8080:localhost:80 user@serveur-distant
# Maintenant, ouvre http://localhost:8080 sur ta machine
Dans cet exemple :
8080 = le port sur ta machine locale (choisis un port libre)localhost = le serveur distant vu de lui-même80 = le port du service sur le serveur distantTu rends un port de ta machine accessible depuis le serveur distant. Pratique pour accéder à ton réseau local depuis l'extérieur.
# Syntaxe
ssh -R [port_distant]:localhost:[port_local] user@serveur
# Exemple : exposer ton serveur web local (port 3000) sur le port 8080 du serveur distant
ssh -R 8080:localhost:3000 user@serveur-distant
# Depuis le serveur distant : curl http://localhost:8080
Tu crées un proxy SOCKS qui fait passer tout ton trafic par le serveur SSH. C'est comme un VPN simple.
# Syntaxe
ssh -D [port_local] user@serveur
# Exemple : créer un proxy SOCKS sur le port 1080
ssh -D 1080 user@serveur-distant
# Configurer ton navigateur pour utiliser le proxy SOCKS localhost:1080
Par défaut, SSH peut se déconnecter après un temps d'inactivité. Ajoute ces options :
# -N : n'exécute pas de commande distante (juste le tunnel)
# -f : passe en arrière-plan
# -o ServerAliveInterval=60 : envoie un ping toutes les 60s
ssh -L 8080:localhost:80 -N -f -o ServerAliveInterval=60 user@serveur
Pour redémarrer automatiquement le tunnel si la connexion coupe :
# Installer autossh
sudo apt install autossh
# Créer un tunnel permanent
autossh -M 10984 -L 8080:localhost:80 -N -f user@serveur-distant
-M 10984 = port de monitoring pour vérifier que le tunnel est vivant.
ssh -L 8080:localhost:80 -i ~/.ssh/ma_cle_rsa user@serveur-distant
# Le serveur distant a phpMyAdmin sur le port 80, accessible seulement en localhost
ssh -L 8888:localhost:80 user@serveur-distant
# Dans ton navigateur : http://localhost:8888/phpmyadmin
# MySQL écoute sur localhost:3306 du serveur distant
ssh -L 3307:localhost:3306 user@serveur-distant
# Maintenant connecte-toi avec ton client MySQL local :
mysql -h 127.0.0.1 -P 3307 -u root -p
# Accéder à un serveur Git qui n'est accessible que via SSH sur un port non standard
ssh -L 7999:serveur-git:22 -p 2222 user@gateway.com
# Clone via le tunnel
git clone ssh://localhost:7999/repo.git
# Depuis chez toi, expose ton service local pour qu'un collègue y accède via le serveur
ssh -R 8080:localhost:3000 user@serveur-distant
# Ton collègue peut maintenant accéder à ton app via http://serveur-distant:8080
Au lieu de retaper les options à chaque fois, ajoute-les à ton fichier de config SSH :
nano ~/.ssh/config
# Tunnel vers le serveur de prod
Host prod-tunnel
HostName serveur-production.com
User admin
LocalForward 3307 localhost:3306
LocalForward 8080 localhost:80
ServerAliveInterval 60
IdentityFile ~/.ssh/cle_production
# Proxy SOCKS vers le serveur de backup
Host backup-proxy
HostName backup.example.com
User deploy
DynamicForward 1080
ServerAliveInterval 60
Maintenant, un simple ssh prod-tunnel crée tous les tunnels définis !
Pour qu'un tunnel survive aux redémarrages, crée un service systemd :
sudo nano /etc/systemd/system/ssh-tunnel.service
[Unit]
Description=SSH Tunnel vers serveur-prod
After=network.target
[Service]
ExecStart=/usr/bin/ssh -N -L 3307:localhost:3306 -L 8080:localhost:80 -o ServerAliveInterval=60 -i /home/user/.ssh/cle_production user@serveur-production.com
Restart=always
RestartSec=10
User=user
[Install]
WantedBy=multi-user.target
# Activer et démarrer le service
sudo systemctl daemon-reload
sudo systemctl enable ssh-tunnel
sudo systemctl start ssh-tunnel
# Vérifier le statut
sudo systemctl status ssh-tunnel
Les tunnels inverses exposent ton réseau à l'extérieur. Utilise ces protections :
# Limiter le tunnel inverse à localhost uniquement sur le serveur
ssh -R 8080:localhost:3000 -o GatewayPorts=no user@serveur
# Ou autoriser uniquement certaines IP sur le serveur distant
# Dans /etc/ssh/sshd_config du serveur :
GatewayPorts clientspecified
# Générer une clé
ssh-keygen -t ed25519 -f ~/.ssh/tunnel_cle
# La copier sur le serveur
ssh-copy-id -i ~/.ssh/tunnel_cle user@serveur
chmod 600 ~/.ssh/tunnel_cle
Crée un tunnel SSH pour accéder à une base de données PostgreSQL qui tourne sur un serveur distant et n'accepte que les connexions locales.
ssh user@serveur-distant
sudo ss -tlnp | grep 5432
ssh -L 5433:localhost:5432 -N -f -o ServerAliveInterval=60 user@serveur-distant
ss -tlnp | grep 5433
# Tu dois voir LISTEN sur 127.0.0.1:5433
sudo apt install postgresql-client
psql -h 127.0.0.1 -p 5433 -U postgres -d ma_base
SELECT version();
\q
nano ~/.ssh/config
# Ajoute un bloc "Host pg-tunnel" avec LocalForward 5433:localhost:5432
# Trouve et tue le tunnel
ps aux | grep "ssh -L"
kill [PID]
Tu peux te connecter à la base de données distante uniquement quand le tunnel SSH est actif. Sans SSH, la connexion est refusée — c'est la sécurité par conception.
| Commande | Description |
|---|---|
ssh -L port:host:port_dist user@srv | Tunnel local : accède à un service du serveur |
ssh -R port:host:port_local user@srv | Tunnel inverse : expose un service local vers le serveur |
ssh -D port user@srv | Proxy SOCKS : tout le trafic passe par SSH |
-N | N'exécute pas de commande distante |
-f | Passe en arrière-plan |
autossh -M port ... | Tunnel automatique qui redémarre si coupé |
~/.ssh/config | Configurer des tunnels persistants |
Les tunnels SSH sont un outil puissant pour accéder en sécurité à des services qui ne sont pas exposés directement sur le réseau. Comprends bien les trois types (local, inverse, dynamique) et utilise toujours des clés SSH plutôt que des mots de passe.