Checklist de durcissement SSH pour serveurs Linux exposés
Une checklist ordonnée pour un serveur Linux qui doit accepter SSH depuis internet : par quoi commencer, ce que la plupart des listes ratent, et ce qui peut attendre.
1. Authentification
Les compromissions commencent bien plus souvent par des identifiants valides que par un démon non corrigé. Cette section est tout l'enjeu.
- Désactivez entièrement l'authentification par mot de passe : PasswordAuthentication no. C'est la ligne la plus rentable de ce document — sans mot de passe à deviner, les attaques par devinage ne peuvent pas aboutir du tout.
- Mettez aussi KbdInteractiveAuthentication no. Oubliez-le et PAM propose encore une invite de mot de passe : les mots de passe continuent de marcher et vous n'avez rien changé. Vérifiez avec sshd -T, pas en lisant le fichier.
- Mettez PermitRootLogin à prohibit-password, ou no si root ne se connecte jamais directement. Root est le premier nom de toute liste d'attaque.
- Protégez les clés privées par une phrase de passe et gardez-les hors des machines partagées. Une clé fuitée est exactement aussi grave qu'un mot de passe fuité, et elle fuit par les mêmes voies : portable volé, commit accidentel, environnement de runner CI.
- Faites tourner les clés quand quelqu'un part, et auditez ~/.ssh/authorized_keys sur chaque compte. Les vieilles clés s'accumulent silencieusement et personne ne les retire jamais.
- Définissez AllowUsers ou AllowGroups en liste explicite. Même en tout-clé, cela empêche un compte de service nouvellement créé d'être joignable à distance par accident.
2. Réduire ce qui est joignable
La deuxième question après « qui peut se connecter » est « qu'est-ce qui écoute d'autre ». Chaque port ouvert est un service que quelqu'un teste en ce moment.
- Inventoriez ce qui écoute réellement : ss -tlnp sur l'hôte, puis vérifiez depuis un autre réseau lesquels répondent. Les deux listes coïncident rarement.
- Liez à localhost les services qui n'ont pas besoin d'être distants — les bases de données surtout. Un PostgreSQL ou un Redis sur 0.0.0.0 est un problème bien plus gros que SSH ne l'a jamais été.
- Faites tourner un pare-feu en refus par défaut : nftables ou le front-end de la distribution, n'autorisant que ce que vous avez nommé.
- Restreignez les adresses sources SSH si vous le pouvez. Si l'ensemble légitime est petit et stable, c'est le contrôle réel le moins cher — et il cesse de marcher dès que quelqu'un voyage.
- Envisagez de quitter le port 22 pour réduire le bruit, en sachant que c'est une réduction de bruit et non une protection.
3. Blocage automatique des connexions échouées
Le tout-clé supprime le risque d'un devinage réussi. Il ne supprime pas le trafic, et cette section porte sur le trafic.
Les bots ignorent votre configuration. Ils continuent de se connecter, de proposer des mots de passe et d'être rejetés — chaque tentative coûtant une connexion TCP, un fork de sshd, une ligne de journal et une part de CPU. Livré à lui-même, un serveur exposé en absorbe des milliers par jour, et le journal tourne assez vite pour perdre les événements dont vous aviez besoin.
fail2ban est la réponse standard et un point de départ raisonnable. Configurez-le correctement — bantime -1, ignoreip avec vos propres adresses, et supervision du nombre de bannissements plutôt que de l'état du service, car son mode de défaillance est le silence. Ses limites structurelles : bannissement d'adresses uniques face à des botnets qui tournent dans des plages, un état qui ne survit pas à une reconstruction, et aucun savoir partagé entre vos serveurs.
SSH Protector fait le même travail en agent managé : bannissements par sous-réseau, permanents et restaurés au démarrage, le vrai port SSH lu depuis la configuration de sshd, votre adresse en liste blanche dès l'installation, réputation partagée entre tous les serveurs protégés, et une console qui répond s'il tourne encore.
4. Détails de configuration sshd
À régler : individuellement mineurs, collectivement une surface d'attaque plus petite. Lancez sshd -t après chaque changement et rechargez plutôt que redémarrer.
- MaxAuthTries 3 — moins de tentatives d'identifiants par connexion, un bot a donc besoin de plus de connexions pour le même nombre d'essais.
- MaxSessions et MaxStartups abaissés — limite le nombre de connexions non authentifiées simultanées, ce qui est justement ce qu'un flot consomme.
- LoginGraceTime 30 — une connexion non authentifiée ne devrait pas rester ouverte deux minutes.
- X11Forwarding no et AllowAgentForwarding no sauf si quelque chose en a réellement besoin. Le transfert d'agent permet notamment à une destination compromise d'utiliser votre clé.
- Algorithmes modernes uniquement : retirez chiffrements, MAC et échanges de clés hérités. Les distributions actuelles ont des valeurs par défaut sensées, vérifiez donc avant de copier un extrait de durcissement d'il y a dix ans — plusieurs populaires cassent désormais plus qu'ils ne réparent.
5. Journalisation et détection
On ne peut pas enquêter sur ce qu'on n'a pas enregistré, et la configuration par défaut conserve moins que vous ne l'espérez.
- Confirmez que le LogLevel de sshd est au moins INFO. Réglé sur QUIET, il n'enregistre aucun échec d'authentification.
- Augmentez la rétention de journald, ou expédiez les journaux hors de l'hôte. Le journal local d'une machine compromise est une preuve qu'un attaquant peut modifier ; une copie ailleurs ne l'est pas.
- Alertez sur ce qui compte plutôt que sur le volume : une connexion réussie depuis une adresse inconnue, une ligne Accepted password sur un serveur censé être en tout-clé, une nouvelle entrée sudoers, une nouvelle entrée authorized_keys.
- Passez en revue les connexions réussies de temps en temps et délibérément. Les échecs sont du bruit ; un succès que vous ne pouvez pas expliquer est tout l'enjeu.
6. Correctifs et récupération
Les deux derniers, et l'ordre entre eux compte moins que le fait qu'ils existent tous les deux.
Gardez sshd et le noyau à jour — activez les mises à jour de sécurité automatiques si votre processus le permet. OpenSSH a connu des vulnérabilités exploitables avant authentification et en connaîtra d'autres, et la fenêtre entre divulgation et exploitation de masse se compte désormais en jours.
Puis les sauvegardes, avec une propriété qui compte plus que toutes les autres : au moins une copie que le serveur lui-même ne peut ni atteindre ni supprimer. Les opérateurs de rançongiciels cherchent la cible de sauvegarde avant de chiffrer quoi que ce soit, et un montage sur lequel l'hôte compromis peut écrire n'est pas une sauvegarde, c'est une seconde copie qui attend d'être détruite. Et restaurez-en une — une sauvegarde jamais restaurée est une hypothèse, pas un plan.
FAQ
- Quelle est la mesure de durcissement SSH la plus importante ?
- Désactiver l'authentification par mot de passe. Avec PasswordAuthentication no et KbdInteractiveAuthentication no, il n'y a pas de mot de passe à deviner, toute la catégorie des attaques par devinage devient donc impossible plutôt que simplement plus difficile. Rien d'autre sur une liste de durcissement n'en approche pour l'effort demandé.
- Faut-il changer le port SSH dans le cadre du durcissement ?
- Cela vaut pour réduire le bruit, pas pour protéger. Quitter le 22 réduit typiquement le volume de connexions échouées de plus de 90% et rend votre journal à nouveau lisible, mais SSH s'annonce dans sa bannière de version, tout scanner de plage complète le trouve donc immédiatement. Traitez-le comme de l'hygiène de journal, jamais comme un contrôle.
- fail2ban fait-il partie d'un bon durcissement SSH ?
- C'est un socle raisonnable et bien mieux que rien. Mettez bantime à -1, listez vos propres adresses dans ignoreip, et supervisez le nombre de bannissements plutôt que l'état du service — une jail dont le filtre ne correspond plus après une montée de version ressemble à une semaine calme.
- MaxAuthTries protège-t-il du brute-force ?
- Très marginalement. Il limite les tentatives d'identifiants au sein d'une connexion, un attaquant ouvre donc simplement plus de connexions ; cela augmente légèrement son coût sans changer l'issue. Le mettre à 3 vaut la peine, mais ce n'est pas une défense — c'est le blocage de la source au pare-feu qui réduit réellement le trafic.

Comment utiliser cette liste
Les checklists de durcissement échouent le plus souvent pour une raison : elles sont classées par thème et non par risque, on les descend et le temps s'épuise quelque part vers la configuration de la bannière, sans avoir jamais traité l'authentification.
Celle-ci est ordonnée. La section 1 supprime la façon dont les serveurs Linux sont réellement compromis. Si vous n'avez qu'une heure : faites la section 1 et arrêtez — elle vaut plus que tout le reste réuni.
Elle suppose un serveur qui doit accepter SSH depuis des adresses arbitraires. Si le vôtre ne le doit pas, la section 3 se réduit à une règle de pare-feu, et c'est une bonne nouvelle.