SSH hardening : la check-list qu'on applique sur vos serveurs
SSH est la porte d'entrée principale de votre serveur. Un SSH mal configuré, c'est root accessible par mot de passe sur le port 22, avec des milliers de tentatives de brute force par jour dans vos logs. Ce n'est pas une vue de l'esprit : c'est l'état de quasi-tous les serveurs fraîchement provisionnés avant qu'on intervienne. Voici la check-list que nous appliquons dans notre pack PK.SER en une journée d'intervention.
Définition en une phrase
SSH hardening (durcissement SSH) est l'ensemble des configurations appliquées sur un serveur Linux pour réduire la surface d'attaque de l'accès SSH : changement de port, désactivation des connexions root, authentification par clé uniquement, restriction des utilisateurs autorisés, et limitation des tentatives via fail2ban.
En clair, pour les non-initiés. SSH est le protocole qui vous permet de vous connecter en ligne de commande à votre serveur depuis votre terminal. Par défaut, tous les serveurs Linux l'activent sur le port 22, avec l'utilisateur root accessible, et les mots de passe acceptés. Ce sont trois mauvaises pratiques que les bots d'attaque connaissent et exploitent automatiquement. Le durcissement SSH consiste à fermer ces portes ouvertes par défaut.
Pourquoi c'est important pour votre serveur
Un serveur VPS provisionné chez Hetzner, OVH ou Scaleway avec les paramètres par défaut reçoit ses premières tentatives de connexion SSH dans les minutes qui suivent son démarrage. Des scanners automatiques balaient l'intégralité des plages d'IP des datacenters et testent le port 22 en permanence.
Dans les logs d'un serveur non durci, on trouve couramment :
Jan 15 03:12:45 server sshd[1234]: Failed password for root from 185.143.220.15 port 49832 ssh2
Jan 15 03:12:47 server sshd[1234]: Failed password for admin from 185.143.220.15 port 49835 ssh2
Jan 15 03:12:49 server sshd[1234]: Failed password for ubuntu from 185.143.220.15 port 49838 ssh2
Des milliers de lignes par jour. Un mot de passe faible ou réutilisé, et le compte est compromis. Un root accessible, et c'est le serveur entier.
La check-list opérationnelle PK.SER
1. Changer le port SSH (port non standard)
# /etc/ssh/sshd_config
Port 2222 # ou tout autre port entre 1024 et 65535 non déjà utilisé
Le port 22 est scanné en permanence par des outils automatisés. Un port non standard ne protège pas contre un attaquant ciblé (Nmap trouve les ports ouverts), mais il élimine 99 % du bruit de fond des bots qui ne scannent que le port 22. C'est du security-through-obscurity limité, mais le gain de signal dans les logs est immédiat.
A noter : après le changement, ouvrir le nouveau port dans UFW avant de couper l'accès sur 22, et mettre à jour les règles firewall Cloudflare ou OVH si applicable.
2. Désactiver l'authentification par mot de passe
# /etc/ssh/sshd_config
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no
Un attaquant qui ne connaît pas votre clé privée ne peut pas se connecter, quel que soit le mot de passe qu'il essaie. Cette configuration rend le brute force SSH complètement inefficace.
Prérequis absolu : avoir déposé une clé SSH publique valide dans ~/.ssh/authorized_keys avant d'appliquer cette configuration. Sinon, vous vous coupez l'accès.
3. Désactiver la connexion root directe
# /etc/ssh/sshd_config
PermitRootLogin no
Root ne doit jamais se connecter directement en SSH. On se connecte avec un utilisateur non-root qui dispose des droits sudo pour les opérations qui le nécessitent. Si root est compromis via SSH, l'attaquant a un accès illimité au serveur. Un utilisateur deploy ou ubuntu compromis sans sudo illimité limite les dégâts.
4. Authentification par clé publique uniquement
# /etc/ssh/sshd_config
PubkeyAuthentication yes
AuthorizedKeysFile .ssh/authorized_keys
En complément de la désactivation des mots de passe, on vérifie que PubkeyAuthentication est actif et que le fichier authorized_keys ne contient que les clés connues et légitimes. On supprime les clés orphelines (clés d'anciens prestataires, clés d'environnements de dev).
5. Restreindre les utilisateurs autorisés à se connecter
# /etc/ssh/sshd_config
AllowUsers deploy fouad
# ou AllowGroups ssh-users
Seuls les utilisateurs listés peuvent tenter une connexion SSH. Les autres reçoivent un refus avant même l'étape d'authentification. Si un compte système est compromis mais n'est pas dans AllowUsers, il ne peut pas être utilisé pour accéder via SSH.
6. Désactiver les fonctionnalités SSH non utilisées
# /etc/ssh/sshd_config
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding no
PrintMotd no
AcceptEnv LANG LC_*
La forwarding X11 et le TCP forwarding ouvrent des vecteurs d'attaque latéraux. Sur un serveur de production qui n'a pas besoin de GUI ni de tunnels TCP, on désactive tout.
7. Configurer un timeout de session inactive
# /etc/ssh/sshd_config
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 30
MaxAuthTries 3
MaxSessions 5
ClientAliveInterval 300 : coupe les sessions inactives depuis plus de 5 minutes.
MaxAuthTries 3 : limite les tentatives d'authentification par connexion.
LoginGraceTime 30 : 30 secondes pour s'authentifier après connexion.
8. Appliquer la configuration et vérifier
# Vérifier la syntaxe avant de recharger
sshd -t
# Recharger sans couper les sessions existantes
systemctl reload sshd
# Vérifier depuis une nouvelle fenêtre de terminal (ne pas fermer la session actuelle)
ssh -p 2222 [email protected]
On teste toujours depuis une nouvelle connexion avant de fermer la session courante. Un sshd -t sans erreur ne garantit pas que la connexion fonctionnera avec les nouvelles clés.
9. Installer et configurer fail2ban
fail2ban surveille les logs SSH et bannit les IPs qui échouent trop souvent :
apt install fail2ban -y
# /etc/fail2ban/jail.local
[sshd]
enabled = true
port = 2222
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 3600
findtime = 600
Avec ce paramétrage : 3 tentatives échouées en 10 minutes = bannissement 1 heure. On vérifie que les IPs légitimes (IPs de l'équipe) sont dans la liste ignoreip.
Ce qu'on fait en PK.SER en une journée
Notre pack PK.SER Serveur durci sur un VPS standard (Ubuntu 22.04 LTS / Debian 12, stack Laravel/Symfony/Node) :
- Audit de la configuration SSHD existante.
- Application de la check-list ci-dessus.
- Configuration fail2ban + UFW (règles entrantes/sortantes).
- Auto-updates de sécurité non supervisés (unattended-upgrades).
- Revue des tâches cron et des services actifs.
- Audit des permissions sur les répertoires critiques (
/var/www,/etc). - Rapport PDF avec état initial vs état final, et les recommandations que nous n'avons pas pu appliquer (contexte spécifique, trade-offs).
Ce qu'on ne fait pas : gestion de vos applications, déploiement de code, configuration de bases de données au-delà des paramètres de sécurité de base.
Les erreurs qu'on rencontre le plus souvent
1. Changer le port sans mettre à jour les règles firewall
Le port 22 est fermé, le nouveau port n'est pas ouvert dans UFW ou dans le pare-feu réseau OVH/Hetzner. Résultat : plus d'accès SSH. On change toujours le port après avoir ouvert le nouveau dans toutes les couches réseau.
2. Désactiver PasswordAuthentication sans tester les clés d'abord
Le scénario classique : on désactive les mots de passe, on recharge sshd, on ferme le terminal. La clé publique n'était pas bien configurée. Plus d'accès. Sur un serveur VPS, la récupération passe par le mode rescue de l'hébergeur. On teste toujours la connexion par clé depuis une nouvelle session avant de désactiver les mots de passe.
3. Authorized_keys avec des clés d'anciens prestataires
Un serveur en production depuis 2 ans peut avoir des clés d'agences qui ne travaillent plus sur le projet. Ces clés donnent un accès SSH permanent à des parties tierces. On audite et nettoie ~/.ssh/authorized_keys sur tous les comptes système.
4. fail2ban installé mais non configuré pour le bon port
fail2ban cherche les tentatives SSH sur le port 22 par défaut. Si on a changé le port, il faut mettre à jour jail.local avec le bon port. Sans ça, fail2ban surveille un port qui ne reçoit plus de connexions SSH.
Questions fréquentes
Faut-il changer le port SSH obligatoirement ? Non, c'est une mesure de réduction du bruit, pas une mesure de sécurité forte. Avec fail2ban et l'authentification par clé uniquement, le port 22 est défendable. On change le port parce que les logs deviennent lisibles (plus de milliers de lignes de brute force par jour), mais c'est un bénéfice opérationnel plus que sécuritaire.
Quand utiliser AllowGroups plutôt qu'AllowUsers ? Sur les serveurs avec plusieurs utilisateurs techniques (équipe de développeurs, plusieurs comptes de déploiement), AllowGroups est plus maintenable : on ajoute les nouveaux utilisateurs au groupe sans toucher à sshd_config. Sur un serveur avec 1 à 3 utilisateurs SSH, AllowUsers suffit.
SSH hardening suffit-il à sécuriser un VPS ? Non. C'est une couche parmi d'autres. Un serveur durci sur SSH mais avec des dépendances non mises à jour, des permissions de fichiers laxistes, ou une application web vulnérable peut être compromis sans jamais passer par SSH. PK.SER traite SSH, UFW, et les configurations système de base. La sécurité applicative relève de P.03.
fail2ban est-il suffisant pour remplacer un rate limiting réseau ? fail2ban agit au niveau des logs système, après que les paquets TCP ont atteint le serveur. Un rate limiting réseau (Cloudflare, ou iptables hashlimit) bloque avant l'application SSH. Les deux sont complémentaires. Pour SSH sur un port non exposé via Cloudflare (la plupart des cas), fail2ban + UFW est une protection correcte.
Que faire si on a perdu l'accès SSH après une mauvaise config ?
Sur les VPS Hetzner, OVH, Scaleway : utiliser le mode console/rescue disponible dans le panel. Ce mode donne accès au serveur indépendamment de SSH. On corrige la configuration dans /etc/ssh/sshd_config et on redémarre sshd. C'est pour cette raison qu'on ne ferme jamais la session SSH active avant d'avoir testé la nouvelle configuration.
Pour aller plus loin
- Connexe : TLS 1.2 / 1.3, Rate limiting, IOC (Indicator of Compromise).
- Protocoles concernés : le durcissement SSH est au coeur du pack Serveur durci PK.SER (990 € TTC, livré en 72 h). Il est également dans le scope du durcissement sécurité P.03 quand nous avons accès serveur.
VPS avec SSH sur le port 22 et root accessible par mot de passe ? Notre pack Serveur durci (PK.SER, 990 € TTC, livré en 72 h) applique la check-list complète SSH, UFW, fail2ban et auto-updates. Rapport PDF avant/après. Briefer le pack PK.SER