Ce que vous allez apprendre

Votre serveur SSH est exposé sur internet. Des milliers de tentatives d'intrusion automatiques arrivent chaque jour. Vous allez apprendre à sécuriser SSH, créer des tunnels, et traverser des réseaux complexes avec les jump hosts.


Sécuriser le serveur SSH — sshd_config

Le fichier de configuration du serveur SSH se trouve dans /etc/ssh/sshd_config. C'est là que tout se joue.

sudo nano /etc/ssh/sshd_config

Désactiver l'authentification par mot de passe

C'est la mesure la plus importante. Une fois vos clés en place, les mots de passe ne servent plus — et ils ouvrent la porte aux attaques par force brute.

# Désactiver les mots de passe
PasswordAuthentication no

# Désactiver la connexion root directe
PermitRootLogin no

# Autoriser uniquement les clés SSH
PubkeyAuthentication yes

# Désactiver les protocoles obsolètes
Protocol 2

Changer le port par défaut

Les robots qui scannent internet ciblent en priorité le port 22. Changer le port réduit drastiquement le bruit dans vos logs.

# Changer le port (ex: 2222 ou n'importe quel port libre > 1024)
Port 2222

Limiter les utilisateurs autorisés

# Seuls ces utilisateurs peuvent se connecter via SSH
AllowUsers ubuntu deployer

Réduire les tentatives de connexion

# Nombre maximum d'authentifications échouées
MaxAuthTries 3

# Déconnexion si pas d'authentification en 30 secondes
LoginGraceTime 30

# Limite les connexions simultanées non authentifiées
MaxStartups 3:50:10

Après chaque modification, rechargez SSH :

sudo systemctl reload sshd

# Tester la config avant de recharger (évite de se bloquer)
sudo sshd -t

fail2ban — bloquer les attaquants automatiquement

fail2ban surveille les logs SSH et bannit automatiquement les IP qui échouent trop souvent.

# Installation
sudo apt install fail2ban

# Créer la config locale (ne pas modifier le fichier original)
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.local

Configuration recommandée pour SSH :

[sshd]
enabled = true
port    = 2222
filter  = sshd
maxretry = 3
bantime  = 3600
findtime = 600

Signification : - maxretry = 3 — banni après 3 échecs - bantime = 3600 — banni pendant 1 heure (3600 secondes) - findtime = 600 — les 3 échecs doivent arriver dans les 10 minutes

# Démarrer fail2ban
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Voir les IP bannies
sudo fail2ban-client status sshd

# Débannir une IP (si vous vous êtes bloqué vous-même)
sudo fail2ban-client set sshd unbanip 41.190.32.14

Les tunnels SSH

Un tunnel SSH fait passer le trafic d'un port local à travers une connexion SSH vers un port distant. Utile pour accéder à des services non exposés sur internet.

Tunnel local (L) — accéder à un service distant

Vous voulez accéder à une base de données PostgreSQL sur le serveur (port 5432), mais ce port n'est pas exposé sur internet (bonne pratique de sécurité).

ssh -L 5433:localhost:5432 ubuntu@production

Décryptage : - -L : tunnel local - 5433 : port sur votre machine locale - localhost:5432 : port sur le serveur distant - ubuntu@production : connexion SSH

Maintenant, depuis votre ordinateur, connectez votre client PostgreSQL à localhost:5433 — vous accédez à la base de données distante.

psql -h localhost -p 5433 -U postgres -d mabase

Tunnel inverse (R) — exposer un service local

Vous développez localement et voulez montrer votre application à un client, mais vous n'avez pas d'IP publique fixe.

ssh -R 8080:localhost:3000 ubuntu@production

Votre application locale (port 3000) est maintenant accessible sur production:8080.


Tunnel dynamique (D) — proxy SOCKS

Crée un proxy SOCKS sur votre machine qui fait passer tout le trafic via le serveur SSH. Utile pour naviguer comme si vous étiez sur le réseau du serveur.

ssh -D 1080 ubuntu@production

Configurez votre navigateur pour utiliser le proxy SOCKS5 sur localhost:1080.


Tunnels en arrière-plan

# -f : passer en arrière-plan
# -N : ne pas ouvrir de shell, juste le tunnel
# -T : désactiver l'allocation de terminal
ssh -fNT -L 5433:localhost:5432 ubuntu@production

Jump hosts (ProxyJump)

Dans un réseau sécurisé, les serveurs de production ne sont pas accessibles directement depuis internet. On passe par un bastion (ou jump host) — un serveur intermédiaire.

Internet → Bastion (IP publique) → Serveur interne (IP privée)

La méthode classique (ProxyJump)

ssh -J ubuntu@bastion.example.com ubuntu@192.168.1.100

Dans ~/.ssh/config (recommandé)

Host bastion
    HostName 41.190.32.14
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519

Host serveur-interne
    HostName 192.168.1.100
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519
    ProxyJump bastion

Maintenant, une seule commande traverse les deux serveurs automatiquement :

ssh serveur-interne

SSH se connecte d'abord au bastion, puis rebondit vers le serveur interne. Tout est chiffré de bout en bout.

Chaîner plusieurs serveurs

ssh -J user@bastion1,user@bastion2 user@serveur-final

Agent forwarding — transférer votre agent SSH

Quand vous êtes connecté à un serveur et que vous voulez vous connecter à un autre serveur depuis là (ex: faire un git clone depuis le serveur), vous avez besoin que votre clé privée soit disponible.

L'agent forwarding transmet votre agent SSH local au serveur distant — sans copier votre clé privée.

# Connexion avec agent forwarding
ssh -A ubuntu@production

# Dans ~/.ssh/config
Host production
    HostName 41.190.32.14
    User ubuntu
    ForwardAgent yes

Attention : activez le ForwardAgent uniquement sur des serveurs de confiance. Un administrateur malveillant pourrait utiliser votre agent.


Commandes de diagnostic SSH

# Mode verbose (-v, -vv, -vvv) pour déboguer une connexion
ssh -v ubuntu@production
ssh -vvv ubuntu@production

# Vérifier la configuration du serveur SSH (syntaxe)
sudo sshd -t

# Voir les logs SSH en temps réel
sudo journalctl -u sshd -f

# Voir les connexions SSH actives sur le serveur
who
ss -tnp | grep :22

# Voir les tentatives d'intrusion
sudo grep "Failed password" /var/log/auth.log | tail -20
sudo grep "Accepted" /var/log/auth.log | tail -20

Checklist de sécurité SSH

☐ PasswordAuthentication no
☐ PermitRootLogin no
☐ Port différent de 22 (ex: 2222)
☐ AllowUsers configuré
☐ MaxAuthTries 3
☐ fail2ban installé et actif
☐ Clés SSH uniquement (pas de mots de passe)
☐ sudo sshd -t avant chaque rechargement
☐ Pare-feu (ufw) configuré pour autoriser uniquement le bon port

Configuration du pare-feu :

sudo ufw allow 2222/tcp
sudo ufw enable
sudo ufw status

À retenir

  • Désactivez PasswordAuthentication dès que vos clés SSH sont en place
  • Changez le port par défaut (22) pour réduire le bruit des attaques automatiques
  • fail2ban bannit les IP qui échouent trop souvent — indispensable en production
  • Les tunnels SSH (-L, -R, -D) permettent d'accéder à des services non exposés
  • ProxyJump permet de traverser plusieurs serveurs en une seule commande
  • L'agent forwarding (-A) transmet vos clés sans les copier sur le serveur

Prochaine étape

Appliquez ces pratiques de sécurité SSH dans votre pipeline CI/CD : configurez GitHub Actions pour déployer automatiquement sur votre serveur via SSH, en utilisant des clés dédiées stockées dans les secrets GitHub.