Comment je sécurise un serveur, du premier accès SSH au guide de la NSA
TL;DR
Un serveur neuf, exposé sur internet, se fait scanner en quelques minutes par des bots qui cherchent un mot de passe faible sur le port 22. La base : une clé SSH plutôt qu'un mot de passe, un utilisateur non-root aux droits limités, un pare-feu qui ferme tout sauf le strict nécessaire, fail2ban contre le bruit, et des backups qu'on restaure vraiment pour vérifier qu'ils marchent. Le guide de durcissement de la NSA, documenté depuis 2011, formalise les mêmes principes : chiffrer, réduire la surface d'attaque, donner le minimum de privilèges.
1. Une clé SSH, jamais un mot de passe
À la création du serveur, je génère une paire de clés si je n'en ai pas déjà une disponible :
ssh-keygen -t ed25519
La clé publique (.pub) part sur le serveur, de deux façons selon le moment :
- À la création du VPS : la plupart des hébergeurs (Hostinger, DigitalOcean, Scaleway...) affichent un champ "Clé SSH" pendant la configuration de l'instance, avant même le premier démarrage. Coller le contenu de
~/.ssh/id_ed25519.pub(récupérable aveccat ~/.ssh/id_ed25519.pub) dans ce champ : la clé est déjà en place au premier accès, sans jamais taper de mot de passe. - Sur un serveur déjà créé :
ssh-copy-id thomas@ip-du-serveur, ou à défaut manuellement :mkdir -p ~/.ssh && chmod 700 ~/.ssh echo "contenu-de-la-clé-publique" >> ~/.ssh/authorized_keys chmod 600 ~/.ssh/authorized_keys
La clé privée ne quitte jamais ma machine. Une clé remplace un mot de passe : rien à retenir, rien à deviner par force brute, et une compromission se révoque en supprimant une ligne d'authorized_keys.
2. Un utilisateur non-root, avec des droits comptés
Se connecter en root donne un accès total à qui devine le mot de passe ou vole la clé. Je crée un utilisateur nommé, jamais "admin" ou "user" (ces noms génériques font gagner la moitié du travail à un attaquant, qui n'a plus qu'à trouver le secret) :
adduser thomas
usermod -aG sudo thomas
Par défaut, le groupe sudo peut tout faire, sans mot de passe, depuis n'importe où. visudo ouvre le fichier de configuration (/etc/sudoers) dans un éditeur qui vérifie la syntaxe avant sauvegarde, pour éviter de se retrouver bloqué dehors avec un fichier cassé. Une ligne comme celle-ci restreint l'utilisateur à quelques commandes précises plutôt qu'à un accès total :
thomas ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/docker
C'est le principe du moindre privilège appliqué à un compte, pas seulement à un service.
3. Mises à jour, tous les jours si possible
Une image de VPS est construite à un instant donné. Entre cet instant et le démarrage du serveur, des correctifs de sécurité sortent. Premier réflexe après la connexion :
apt-get update && apt-get upgrade -y
Le guide de la NSA recommande de le faire quotidiennement, pas hebdomadairement : une faille connue et publiée reste exploitable tant que le correctif n'est pas appliqué. Une semaine d'attente, c'est une semaine d'exposition à une vulnérabilité documentée publiquement.
4. Durcir la configuration SSH
Dans /etc/ssh/sshd_config, trois lignes à changer avant toute autre chose :
PermitRootLogin no
PasswordAuthentication no
UsePAM no
La première ferme l'accès root direct. La deuxième force l'usage de la clé : sans elle, PermitRootLogin no peut être contourné si PAM reste actif. La troisième désactive le module d'authentification qui, dans certaines configurations, repasse par un mot de passe malgré tout. Redémarrer le service après modification :
systemctl restart sshd
5. Fail2ban contre le bruit, pas contre les experts
Avec une authentification par clé, une attaque par force brute a une chance quasiment nulle d'aboutir. Le problème n'est pas là : un serveur exposé se fait bombarder de tentatives de connexion en continu, et ce trafic gonfle les journaux jusqu'à les rendre inutilisables.
apt-get install fail2ban
jail.conf se fait écraser à chaque mise à jour du paquet : la configuration se met dans une copie dédiée, jamais dans l'original.
cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Dans jail.local, sous la section [sshd], je fixe un seuil large (maxretry = 15, findtime = 10m) plutôt qu'agressif : un seuil trop bas finit par bannir l'IP du bureau le jour où plusieurs clés sont testées à la suite. Puis :
systemctl restart fail2ban
fail2ban-client status sshd
La dernière commande confirme que la prison sshd est active et montre les IP actuellement bannies. Fail2ban limite le spam, il ne remplace pas une bonne authentification.
6. Pare-feu : deux couches, pas une
Premier réflexe, iptables, en n'autorisant que ce qui doit passer :
iptables -A INPUT -i eth0 -p tcp --dport 22 -j ACCEPT
iptables -A INPUT -j DROP
Ces règles disparaissent au prochain redémarrage si elles ne sont pas sauvegardées. Sur Debian/Ubuntu :
apt-get install iptables-persistent
netfilter-persistent save
Deuxième couche : le pare-feu fourni par l'hébergeur, configuré depuis son interface web plutôt qu'en ligne de commande. Sur Hostinger, c'est dans hPanel > VPS > Pare-feu ; sur DigitalOcean, Networking > Firewalls ; sur Scaleway, Réseau > Security Groups. Le principe est le même partout : une liste de règles entrantes/sortantes par port et par IP source, appliquée avant même que le trafic n'atteigne le serveur. Ce pare-feu ne remplace pas iptables, il s'y ajoute, avec un avantage concret : une erreur de configuration dans iptables peut couper l'accès au serveur depuis le serveur lui-même. Le pare-feu du provider reste pilotable depuis l'extérieur, donc récupérable même après une mauvaise manipulation locale.
7. Réseau privé et bastion, pour tout ce qui n'a pas besoin d'internet
Une base de données n'a aucune raison d'avoir une IP publique : seuls les serveurs applicatifs doivent l'atteindre. La plupart des hébergeurs proposent un réseau privé (plage 10.0.0.0/8 typiquement), à créer et à rattacher aux machines concernées depuis leur interface (section "Réseau privé" ou "Private Network" du panneau du VPS, distincte du réseau public créé par défaut). Une machine peut appartenir aux deux réseaux à la fois, ou au réseau privé seul si elle n'a aucune raison d'être jointe depuis internet.
Le montage classique : un serveur bastion, seul point d'entrée public, avec juste un SSH durci dessus, relié au réseau privé où vivent les bases de données et les services internes. Depuis le bastion, une connexion SSH classique (ssh utilisateur@ip-privée) atteint les machines internes sans jamais les exposer publiquement. Tout doit passer par le bastion. Les efforts de sécurité se concentrent sur une seule machine, pas sur dix.
8. Backups : les restaurer, pas seulement les programmer
Un backup programmé et jamais testé est une fausse sécurité. La panne arrive, la restauration échoue, et le problème se découvre au pire moment. Deux façons de programmer les backups :
- Depuis le panneau de l'hébergeur : la plupart proposent un onglet "Sauvegardes" avec une fréquence (quotidienne, hebdomadaire) et une rétention configurables, sans rien installer sur le serveur.
- En scriptant soi-même, pour un contrôle plus fin (base de données uniquement, envoi vers un stockage externe) : un
cronqui appelle un script de dump (pg_dump,mysqldump...) suivi d'un envoi vers un stockage S3-compatible.
Dans les deux cas, à intervalle régulier, restaurer un backup au hasard sur une machine de test et vérifier que les données attendues sont là, en entier. Un backup qu'on n'a jamais restauré n'est qu'une hypothèse.
9. Ce que le guide de la NSA ajoute
Le guide "Hardening Network Infrastructure" de la NSA (documenté depuis 2011, révisé jusqu'en 2016) formalise trois principes qui recoupent cette checklist et vont un peu plus loin :
- Réduire la surface d'attaque : désactiver tout service non utilisé, pas seulement le sécuriser. Un serveur X11, une imprimante réseau ou un service NTP qui tourne sans raison ne protège de rien : chaque service actif est une faille potentielle, même si elle n'est jamais exploitée.
- SELinux ou un module équivalent : un module noyau qui vérifie, pour chaque action d'un programme (lire un fichier, ouvrir un port), s'il en a le droit selon une base de règles centralisée. Peu utilisé en production tant c'est perçu comme complexe à configurer, mais c'est une couche de contrôle qu'un pare-feu seul ne fournit pas.
- Sécurité physique : mot de passe BIOS, désactivation des ports USB sur un serveur en datacenter. Si personne n'est censé y brancher une clé USB, autant rendre le port inopérant.
Aucune de ces mesures ne remplace les huit premières. Elles ferment des angles qu'une checklist orientée SSH et réseau ne couvre pas.