Chapitre 4.5 — Transferts & tunnels
⏱️ TL;DR — SSH ne sert pas qu’à ouvrir un shell : il transporte des fichiers et des connexions. Pour copier :
scp(simple,scp fichier user@host:/chemin,-rpour un dossier) et surtoutrsync -avz(incrémental — il ne renvoie que ce qui a changé —, avec--progresset l’option--delete), l’outil de déploiement par excellence.sftpoffre une session interactive de transfert. Côté connexions, les tunnels SSH font passer un port dans le tunnel chiffré :-L(port local → service distant, ex. atteindre une base Postgres distante sans l’exposer),-R(l’inverse : exposer un service local sur le serveur),-D(proxy SOCKS pour router du trafic). Cas d’école :ssh -L 5433:localhost:5432 host, puis tu te connectes à Postgres en local comme s’il était sur ta machine.
🎯 Objectifs
- Copier des fichiers vers/depuis un serveur avec
scp(etscp -rpour un dossier). - Synchroniser efficacement avec
rsync -avz(incrémental,--progress,--delete) et comprendre pourquoi c’est l’outil de déploiement. - Ouvrir une session
sftpinteractive. - Comprendre et utiliser les tunnels :
-L(local),-R(remote),-D(SOCKS). - Atteindre un service distant non exposé (ex. Postgres) via un tunnel
-L, en sécurité.
Copier des fichiers : scp
scp (secure copy) copie des fichiers dans le tunnel chiffré de SSH. La syntaxe ressemble à cp, mais un côté peut être distant, noté user@host:/chemin.
# envoyer un fichier local VERS le serveur :
scp build.tar.gz deploy@203.0.113.10:/var/www/formacampus/
# scp -> secure copy
# build.tar.gz -> le fichier LOCAL a envoyer
# deploy@203.0.113.10 -> destination : utilisateur@hote
# :/var/www/... -> le chemin DISTANT ou deposer le fichier
# recuperer un fichier DEPUIS le serveur (source distante, destination locale) :
scp deploy@203.0.113.10:/var/log/nginx/error.log ./
# le "." final = le dossier local courantPour un dossier entier, ajoute -r (recursive) :
scp -r ./dist deploy@203.0.113.10:/var/www/formacampus/
# -r -> copie recursive : le dossier dist et tout son contenuscp profite de ton ~/.ssh/config : si tu as un alias prod (chapitre 4.3), tu écris directement scp build.tar.gz prod:/var/www/. Pas besoin de répéter user, port et clé.
💡 Réflexe —
scpest parfait pour un fichier ponctuel. Mais dès que tu copies un dossier que tu réenverras plus tard (un déploiement, un dump, un dossier d’assets), passe àrsync:scprecopie tout à chaque fois,rsyncne renvoie que ce qui a changé. Sur un gros dossier, c’est le jour et la nuit.
Synchroniser malin : rsync
rsync est l’outil de synchronisation incrémentale. Il compare source et destination, et ne transfère que les différences. Sur SSH, il chiffre tout comme scp, mais en bien plus efficace pour les mises à jour répétées.
rsync -avz --progress ./dist/ deploy@203.0.113.10:/var/www/formacampus/dist/
# -a -> mode archive : preserve permissions, dates, liens (copie fidele, recursive)
# -v -> verbeux : liste ce qui est transfere
# -z -> compresse pendant le transfert (gain sur le reseau)
# --progress -> barre de progression par fichier⚠️ Piège — Le slash final sur la source change tout.
rsync ./dist/ dest/copie le contenu dedistdansdest.rsync ./dist dest/(sans slash) copie le dossierdistlui-même dansdest(tu obtiensdest/dist/…). En cas de doute, teste avec-n(ou--dry-run) : il simule sans rien écrire et te montre ce qui serait transféré.
L’option --delete : miroir exact
Par défaut, rsync ajoute et met à jour, mais ne supprime rien côté destination. Pour obtenir un miroir exact (ce qui n’existe plus à la source disparaît de la destination), ajoute --delete :
rsync -avz --delete ./dist/ deploy@203.0.113.10:/var/www/formacampus/dist/
# --delete -> supprime cote destination les fichiers absents de la source
# resultat : la destination devient une COPIE EXACTE de la source⚠️ Piège —
--deleteest puissant et dangereux : si tu te trompes de dossier source (un dossier vide, un mauvais chemin), tu effaces la destination. Toujours un--dry-rund’abord pour vérifier la liste des suppressions. Unrsync --deletemal ciblé a déjà vidé des dossiers de prod entiers.
💡 Réflexe —
rsyncest le cœur du déploiement par SSH. En CI/CD (Partie 13), on build l’app puis onrsyncle résultat sur le serveur : seuls les fichiers modifiés partent, le déploiement est rapide et atomique. On réutilisera exactement cette commande, pilotée par GitHub Actions. Ce que tu apprends ici sert directement plus tard.
Une session interactive : sftp
sftp ouvre une session de transfert interactive, façon FTP mais chiffrée par SSH. Utile pour explorer l’arborescence distante et déposer/récupérer des fichiers à la main.
sftp deploy@203.0.113.10
# ouvre une invite sftp> ; commandes typiques :
# ls / cd -> naviguer cote DISTANT
# lls / lcd -> naviguer cote LOCAL (prefixe "l" = local)
# put fichier -> envoyer un fichier local vers le serveur
# get fichier -> recuperer un fichier distant
# bye -> quitterC’est pratique pour du ponctuel manuel ou quand un client graphique (type gestionnaire de fichiers SFTP) se connecte. Pour de l’automatisation, on préfère scp/rsync en une ligne.
Les tunnels SSH : faire passer un port dans le tunnel
Un tunnel SSH transporte une connexion réseau (un port) à l’intérieur de ta connexion SSH chiffrée. Ça permet d’atteindre un service comme s’il était local, sans l’exposer sur Internet. Trois formes.
-L : redirection de port locale (la plus utile)
-L ouvre un port sur TA machine qui, quand tu t’y connectes, ressort côté serveur vers une destination que lui peut joindre. La syntaxe : -L portLocal:destination:portDest.
ssh -L 5433:localhost:5432 deploy@203.0.113.10
# -L 5433:localhost:5432 :
# 5433 -> un port ouvert sur TA machine (choisi libre, ici 5433)
# localhost -> "localhost" vu DEPUIS LE SERVEUR (donc le serveur lui-meme)
# 5432 -> le port Postgres sur le serveur
# tant que ce ssh est ouvert, ta machine expose un port 5433
# qui debouche sur le Postgres distant, a travers le tunnel chiffreConcrètement : avec ce tunnel ouvert, tu lances ton client Postgres en local sur localhost:5433, et tu parles à la base distante — sans que Postgres soit jamais ouvert sur Internet. La base écoute uniquement en local côté serveur (comme il se doit) ; le tunnel est le seul chemin, et il est chiffré et authentifié par SSH.
🔒 Sécurité — C’est le bon pattern pour administrer une base distante. Le mauvais réflexe serait d’ouvrir le port 5432 de Postgres sur Internet pour s’y connecter directement : ce serait exposer ta base aux scans et aux attaques du monde entier. Avec
-L, la base reste fermée à l’extérieur (écoute locale seulement) et tu y accèdes via SSH — rien de nouveau n’est exposé, tout passe par ta clé et ton tunnel. On applique ce principe en Partie 11.
-R : redirection remote (l’inverse)
-R fait le trajet opposé : il ouvre un port sur le serveur qui ressort vers une destination joignable depuis ta machine. Ça sert à exposer temporairement un service local (ex. ton app en dev) à travers le serveur.
ssh -R 8080:localhost:3000 deploy@203.0.113.10
# ouvre un port 8080 SUR LE SERVEUR, qui ressort vers localhost:3000 de TA machine
# quelqu'un qui atteint le serveur sur 8080 tape en fait ton app locale sur 3000À manier avec prudence : tu exposes ta machine via le serveur. Utile pour un démo/webhook ponctuel, pas pour du permanent.
-D : proxy SOCKS dynamique
-D transforme ta connexion SSH en proxy SOCKS local : tout le trafic que tu routes vers ce proxy sort par le serveur.
ssh -D 1080 deploy@203.0.113.10
# ouvre un proxy SOCKS local sur le port 1080
# configure ton navigateur pour utiliser SOCKS localhost:1080
# -> ta navigation sort par l'IP du serveur, dans le tunnel chiffrePratique pour tester ce que voit ton serveur (une API géo-restreinte, un service filtré par IP) ou router du trafic de façon sûre depuis un réseau non fiable.
🐚 Au terminal — Astuce lisibilité : ajoute
-Npour un tunnel « pur » (pas de shell distant, juste le port) et-fpour le passer en arrière-plan.
ssh -fN -L 5433:localhost:5432 prod
# -N -> n'execute AUCUNE commande distante (tunnel seul, pas de shell)
# -f -> passe en arriere-plan une fois le tunnel etabli
# (utilise l'alias "prod" de ~/.ssh/config : user, port et cle sont deja connus)📚 La doc — Les options de redirection (
-L,-R,-D), leurs formes complètes (avec adresse de bind) et les réglages associés (GatewayPorts,AllowTcpForwarding) sont détaillés dansman sshetman sshd_config. Le principe est simple, la syntaxe a des variantes : vérifie-la au manuel plutôt que de deviner.
🧭 Sur FormaCampus — Deux usages concrets chez FormaCampus. (1) Déploiement : le pipeline build le front Next.js, puis
rsync -avz --deletepousse le résultat sur/var/www/formacampus/du VPS — seuls les fichiers modifiés transitent, déploiement rapide et reproductible (la brique qu’on automatisera en CI/CD). (2) Admin base : pour inspecter la prod, un dev ouvressh -fN -L 5433:localhost:5432 prodet branche son client SQL surlocalhost:5433. Il voit la vraie base Postgres — qui n’est jamais exposée sur Internet (écoute locale + pare-feu). Le tunnel, chiffré et authentifié par sa clé, est le seul chemin. Confort et sécurité, sans compromis.
En résumé
- Copier :
scp fichier user@host:/chemin(-rpour un dossier). - Synchroniser :
rsync -avz --progress(incrémental),--deletepour un miroir (avec--dry-rund’abord). L’outil du déploiement. - Explorer/déposer à la main :
sftp. - Tunnels :
-L(atteindre un service distant non exposé),-R(exposer un service local),-D(proxy SOCKS).-fNpour un tunnel pur en arrière-plan.
✏️ Exercices
Exercice 1 — Choisis l’outil. Pour chaque cas, scp ou rsync ? (a) Envoyer une archive .tar.gz sur le serveur. (b) Redéployer dix fois par jour un dossier dist/ de 500 fichiers dont 3 changent à chaque fois.
✅ Solution
(a) scp : un fichier unique, ponctuel, scp build.tar.gz prod:/var/www/ suffit. (b) rsync : redéploiements répétés d’un dossier — rsync -avz ./dist/ prod:/var/www/formacampus/dist/ ne renvoie que les 3 fichiers modifiés à chaque fois, là où scp -r recopierait les 500 à chaque déploiement. rsync est l’outil du déploiement incrémental.
Exercice 2 — Atteindre la base sans l’exposer. La base Postgres de la prod écoute sur 5432 en local uniquement (non exposée). Tu veux la brancher sur ton client SQL local. Quelle commande ouvres-tu, et sur quel port local branches-tu ton client ?
✅ Solution
ssh -L 5433:localhost:5432 prod (ou ssh -fN -L 5433:localhost:5432 prod pour un tunnel en arrière-plan). Le localhost:5432 est vu depuis le serveur (donc son Postgres). Je branche ensuite mon client SQL sur localhost:5433 de ma machine : le trafic ressort côté serveur vers Postgres, à travers le tunnel chiffré. La base reste fermée à l’extérieur — je n’ai rien exposé.
Exercice 3 — Le --delete qui fait peur. Tu tapes rsync -avz --delete ./dist/ prod:/var/www/formacampus/dist/ mais tu n’es pas sûr du contenu de ./dist/. Comment vérifies-tu avant d’exécuter, et pourquoi est-ce important ici ?
✅ Solution
J’ajoute --dry-run (ou -n) : rsync -avz --delete --dry-run ./dist/ prod:/var/www/formacampus/dist/. Ça simule et liste ce qui serait transféré et supprimé, sans rien écrire. C’est crucial avec --delete : si ./dist/ était vide ou mauvais, rsync effacerait le dossier de prod côté destination. Le --dry-run me montre les suppressions avant qu’elles n’arrivent.
🧠 Quiz de révision
1. Quelle est la différence de fond entre scp et rsync ?
scp et rsync ?scp recopie tout à chaque fois ; rsync est incrémental : il compare source et destination et ne transfère que les différences. Pour un fichier ponctuel, scp suffit ; pour des dossiers redéployés régulièrement, rsync est bien plus rapide (et c’est l’outil du déploiement).
2. Que fait l’option --delete de rsync, et quelle précaution prendre ?
--delete de rsync, et quelle précaution prendre ?Elle supprime côté destination les fichiers absents de la source, pour obtenir un miroir exact. Précaution : toujours lancer un --dry-run (-n) d’abord, car une erreur de dossier source peut effacer la destination.
3. À quoi sert un tunnel -L, et donne l’exemple Postgres.
-L, et donne l’exemple Postgres.-L portLocal:destination:portDest ouvre un port local qui ressort côté serveur vers une destination qu’il peut joindre. Exemple : ssh -L 5433:localhost:5432 host — se connecter à localhost:5433 sur ta machine atteint le Postgres distant (port 5432, vu du serveur), sans exposer la base sur Internet.
4. Pourquoi un tunnel -L est-il plus sûr qu’ouvrir le port de la base sur Internet ?
-L est-il plus sûr qu’ouvrir le port de la base sur Internet ?Parce que la base reste fermée à l’extérieur (écoute locale + pare-feu) : rien de nouveau n’est exposé aux scans et attaques. L’accès passe uniquement par le tunnel SSH, chiffré et authentifié par ta clé. Ouvrir le port 5432 au monde exposerait la base à Internet entier.
5. Que font -R et -D, brièvement ?
-R et -D, brièvement ?-R (remote) fait l’inverse de -L : il ouvre un port sur le serveur qui ressort vers un service local à toi (exposer temporairement ton app locale via le serveur). -D crée un proxy SOCKS local : le trafic que tu y routes sort par le serveur, dans le tunnel chiffré.
Fin de la Partie 4. Ta porte d’entrée est maîtrisée et durcie. On enchaîne : Partie 5 — Provisionner & durcir le VPS — pare-feu (UFW), fail2ban et mises à jour automatiques, pour boucler la sécurisation d’un serveur qu’on met en ligne.