L08 - SSH, clés, rebond, tunnels, SCP et SFTP
Objectif
Se connecter à un serveur à distance de façon sécurisée, sans mot de passe (clés), à travers une machine de rebond, transférer des fichiers, et durcir le serveur SSH.
1. Principe
SSH (Secure SHell, TCP 22) ouvre un terminal sur une machine distante dans un tunnel chiffré. Il remplace Telnet (non chiffré).
sequenceDiagram participant C as Ton PC (client ssh) participant S as Serveur (sshd) C->>S: Connexion TCP 22 S->>C: Clé d'hôte du serveur Note over C: 1re fois : « Are you sure ? » → yes<br/>empreinte enregistrée dans ~/.ssh/known_hosts C->>S: « J'ai la clé publique X » S->>C: Défi (vérifie ~/.ssh/authorized_keys) C->>S: Réponse signée avec la clé PRIVÉE S->>C: ✅ Session chiffrée ouverte
2. Se connecter
ssh utilisateur@192.168.1.20 # port 22 par défaut
ssh -p 2222 utilisateur@127.0.0.1 # autre port (ex. redirection VirtualBox)
ssh utilisateur@serveur "df -h" # exécuter UNE commande puis revenir
exit # ou Ctrl+DInstaller le serveur SSH sur une VM :
sudo apt install openssh-server && sudo systemctl enable --now ssh # Debian/Ubuntu
sudo pacman -S openssh && sudo systemctl enable --now sshd # Arch3. Authentification par clé (recommandée)
Une paire de clés : la privée (reste sur ton PC, secrète) et la publique (copiée sur les serveurs).
ssh-keygen -t ed25519 -C "thesky1966@pop-os" # Entrée pour le chemin par défaut, phrase de passe conseillée
ls -l ~/.ssh/ # id_ed25519 (privée, 600) id_ed25519.pub (publique)
ssh-copy-id utilisateur@192.168.1.20 # copie la publique dans ~/.ssh/authorized_keys du serveur
ssh utilisateur@192.168.1.20 # plus de mot de passe serveur demandéScript tout-en-un : scripts/linux/creer_cle_ssh.sh utilisateur@serveur [port]
#!/usr/bin/env bash
set -euo pipefail
cible="${1:?Usage : $0 utilisateur@serveur [port]}"
port="${2:-22}"
cle_privee="$HOME/.ssh/id_ed25519"
mkdir -p "$HOME/.ssh" && chmod 700 "$HOME/.ssh"
-f "$cle_privee" || ssh-keygen -t ed25519 -C "$(whoami)@$(hostname)-$(date +%Y)" -f "$cle_privee"
chmod 600 "$cle_privee"
ssh-copy-id -i "${cle_privee}.pub" -p "$port" "$cible"
ssh -p "$port" -o PasswordAuthentication=no -o BatchMode=yes "$cible" \
'echo "OK : connecté à $(hostname) sans mot de passe."'Éviter de retaper la phrase de passe : eval "$(ssh-agent -s)" && ssh-add (ou KeePassXC comme agent → S05 - Mots de passe et KeePassXC).
| Erreur | Cause |
|---|---|
Permission denied (publickey) | Clé non copiée, mauvais utilisateur, ou droits trop ouverts sur ~/.ssh (doit être 700) / authorized_keys (600) |
WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! | La VM a été réinstallée (nouvelle clé d’hôte) → ssh-keygen -R 192.168.1.20 |
Connection refused | sshd arrêté ou pare-feu |
Connection timed out | IP injoignable / port filtré |
4. Le fichier ~/.ssh/config (gain de temps énorme)
Host routeur
HostName 172.16.118.6
User sercha
Host vm-web
HostName 172.30.16.2
User jarvis
ProxyJump routeur # passe par le routeur (rebond)
Host vm-bdd
HostName 172.30.16.5
User user
ProxyJump routeur
Host pi
HostName raspberrypi.local
User pi
IdentityFile ~/.ssh/id_ed25519chmod 600 ~/.ssh/config
ssh vm-web # au lieu de : ssh -J sercha@172.16.118.6 jarvis@172.30.16.25. Rebond (jump host) - projet transversal
Les VM internes (172.30.16.x) ne sont pas joignables directement : on passe par la VM routeur.
flowchart LR PC["Ton PC"] -->|"ssh -J"| R["VM routeur<br/>172.16.118.6<br/>(bastion)"] R -->|"SSH interne"| W["VM web<br/>172.30.16.2"] R -->|"SSH interne"| B["VM BDD<br/>172.30.16.5"]
ssh -J sercha@172.16.118.6 jarvis@172.30.16.26. Tunnels SSH (redirection de port)
# Local : http://localhost:8080 sur TON PC → port 80 de la VM web (à travers le routeur)
ssh -L 8080:172.30.16.2:80 sercha@172.16.118.6
# Accéder à MariaDB d'une VM sans ouvrir le 3306 au réseau :
ssh -L 3307:127.0.0.1:3306 jarvis@vm-bdd # puis : mysql -h 127.0.0.1 -P 3307 -u ...
# Distant (inverse) : exposer ton port local 3000 sur le serveur
ssh -R 9000:localhost:3000 utilisateur@serveur
# Proxy SOCKS (naviguer comme si tu étais sur le serveur)
ssh -D 1080 utilisateur@serveur7. Transférer des fichiers
scp fichier.txt utilisateur@serveur:/tmp/ # PC → serveur
scp utilisateur@serveur:/var/log/syslog ./ # serveur → PC
scp -r dossier/ vm-web:~/ # dossier (et utilise ~/.ssh/config)
rsync -avz --progress dossier/ vm-web:~/dossier/ # synchronisation (reprend si coupure)
sftp utilisateur@serveur # session interactive
sftp> ls / cd / lcd (dossier local) / put fichier / get fichier / mkdir / exitGraphique : FileZilla (sudo apt install filezilla), ou l’explorateur de fichiers (sftp://utilisateur@serveur). Pour Pterodactyl, le SFTP est sur le port 2022 avec l’identifiant utilisateur.idserveur affiché dans le panel → O07 - Pterodactyl.
Windows : ssh et scp sont intégrés (PowerShell) ; PuTTY / WinSCP en graphique (PuTTY utilise des clés .ppk : conversion avec puttygen).
8. Durcir le serveur SSH
/etc/ssh/sshd_config (ou un fichier dans /etc/ssh/sshd_config.d/) - seulement après avoir vérifié que la connexion par clé fonctionne :
# Pas de connexion directe en root
PermitRootLogin no
# Clés uniquement
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
# Liste blanche d'utilisateurs
AllowUsers etudiant jarvis
# Changer de port réduit le bruit des robots (ce n'est pas une vraie sécurité)
# Port 2222Dans
sshd_config, les commentaires doivent être sur leur propre ligne (pas après une directive).
sudo sshd -t # tester la syntaxe AVANT de redémarrer
sudo systemctl restart ssh # (sshd sur Arch) — garde ta session ouverte et teste dans un 2e terminal !Bonus : fail2ban bannit les IP qui échouent trop souvent (sudo apt install fail2ban).
Voir aussi
- S05 - Mots de passe et KeePassXC · L07 - Scripting Bash · O08 - Tailscale
- Retour : 00 - Index général