Un serveur exposé sur Internet reçoit des tentatives d'intrusion dans les minutes suivant sa mise en ligne. Voici les mesures indispensables, dans l'ordre.
1. Créer un utilisateur non-root
adduser admin
usermod -aG sudo admin
rsync --archive --chown=admin:admin ~/.ssh /home/admin
visudo # vérifier que %sudo a bien ALL=(ALL:ALL) ALL
2. Désactiver SSH par mot de passe
Dans /etc/ssh/sshd_config.d/99-hardening.conf :
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
X11Forwarding no
AllowUsers admin
Puis sudo systemctl restart sshd. Testez une nouvelle connexion avant de fermer la session courante.
3. Pare-feu avec UFW
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit 22/tcp comment 'SSH anti-brute-force'
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
La règle limit bloque une IP au-delà de 6 connexions en 30 secondes. Générez vos règles avec le générateur UFW.
4. fail2ban
sudo apt install fail2ban
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
Dans jail.local :
[sshd]
enabled = true
maxretry = 3
bantime = 3600
findtime = 600
Vérifiez ensuite sudo fail2ban-client status sshd.
5. Mises à jour automatiques
sudo apt install unattended-upgrades
sudo dpkg-reconfigure --priority=low unattended-upgrades
Pour un redémarrage automatique une fois par mois : Unattended-Upgrade::Automatic-Reboot "true";.
6. Services et secrets
- Chaque service tourne sous son propre utilisateur (générateur systemd).
- Les secrets vivent dans des fichiers 600 ou des variables d'environnement, jamais dans le dépôt Git.
- Vérifiez les permissions : cf. calculateur chmod.
7. Supervision et sauvegardes
- Sauvegardez la base hors du serveur (rclone, S3, rsync) et testez la restauration.
- Surveillez l'uptime, le disque et les erreurs HTTP (Uptime Kuma, Healthchecks).
- Journalisez les actions sensibles et relisez les journaux :
journalctl -u ssh --since "24 hours ago".
8. En cas de doute
sudo ss -tulpn # quels services écoutent réellement ?
sudo ufw status verbose
last -a | head # dernières connexions
sudo grep -i "Failed password" /var/log/auth.log | tail
Un serveur durci n'est jamais terminé : la revue régulière fait partie du travail.