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+D

Installer 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             # Arch

3. 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).

ErreurCause
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 refusedsshd arrêté ou pare-feu
Connection timed outIP 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_ed25519
chmod 600 ~/.ssh/config
ssh vm-web          # au lieu de : ssh -J sercha@172.16.118.6 jarvis@172.30.16.2

5. 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.2

6. 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@serveur

7. 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 / exit

Graphique : 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 2222

Dans 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