Sécuriser un VPS Ubuntu : SSH, pare-feu et fail2ban

Un VPS exposé à Internet est scanné dans les minutes qui suivent sa création. Voici la checklist de durcissement à appliquer avant d'y mettre quoi que ce soit.

Bouclier protégeant un serveur, tentatives de connexion bloquées

Une adresse IPv4 publique fraîchement attribuée reçoit ses premières tentatives d'authentification SSH en moins de dix minutes. Ce ne sont pas des attaques ciblées : ce sont des balayages automatisés qui testent des combinaisons root/123456 sur l'ensemble de l'espace d'adressage. La bonne nouvelle, c'est qu'une heure de configuration suffit à les rendre inoffensifs.

Ce guide s'applique à une VM Ubuntu 24.04 LTS fraîchement provisionnée, mais les principes valent pour Debian 12 et 13 à quelques noms de paquets près.

1. Mettre le système à jour

Une image de base est figée au moment de sa publication. La première commande à lancer, avant toute autre, applique les correctifs de sécurité accumulés depuis.

bash
sudo apt update && sudo apt full-upgrade -y
sudo reboot

Le redémarrage n'est nécessaire que si le noyau a été mis à jour. La commande ls /var/run/reboot-required vous le dira sans deviner.

2. Créer un utilisateur non privilégié

Travailler en root au quotidien supprime le dernier filet de sécurité : une commande mal copiée devient irréversible. On crée un compte administrateur nominatif, on lui donne sudo, et on ferme la porte à root ensuite.

bash
sudo adduser florian
sudo usermod -aG sudo florian

3. Passer aux clés SSH

Un mot de passe se devine, une clé Ed25519 non. Générez la paire sur votre poste, jamais sur le serveur : la clé privée ne doit pas quitter votre machine.

bash
# sur votre poste
ssh-keygen -t ed25519 -C "florian@laptop"
ssh-copy-id florian@2602:xxxx:xxxx::10

Vérifiez que la connexion par clé fonctionne dans un second terminal avant de couper l'authentification par mot de passe. Garder la session courante ouverte est ce qui vous évitera de vous verrouiller dehors.

4. Durcir le serveur SSH

Sur Ubuntu 24.04, ne modifiez pas /etc/ssh/sshd_config directement : une mise à jour du paquet peut écraser vos changements. Déposez un fichier dédié dans le répertoire d'inclusion.

bash
sudo tee /etc/ssh/sshd_config.d/99-durcissement.conf <<'EOF'
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
PubkeyAuthentication yes
MaxAuthTries 3
LoginGraceTime 20
AllowUsers florian
EOF

sudo sshd -t && sudo systemctl restart ssh

À savoir : Ubuntu 24.04 active SSH par socket (ssh.socket). Changer Port dans la configuration ne suffit plus ; il faut passer par sudo systemctl edit ssh.socket et y définir ListenStream=. Cela dit, déplacer le port réduit le bruit dans les journaux, pas le risque réel, la protection vient des clés.

sshd -t valide la syntaxe avant le redémarrage. C'est le garde-fou qui distingue un serveur relancé d'un serveur injoignable.

5. Fermer le pare-feu (IPv4 et IPv6)

UFW applique par défaut ses règles aux deux familles d'adresses si IPV6=yes figure dans /etc/default/ufw, c'est le cas sur Ubuntu. Vérifiez-le : un serveur filtré en IPv4 mais ouvert en IPv6 est un serveur ouvert.

bash
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw limit OpenSSH
sudo ufw enable
sudo ufw status verbose

limit plutôt que allow : UFW refuse alors une adresse qui tente plus de six connexions en trente secondes. N'ouvrez les ports 80 et 443 (sudo ufw allow 'Nginx Full') que le jour où un service écoute réellement dessus.

6. Installer fail2ban

fail2ban lit les journaux et bannit les adresses qui échouent trop souvent. Sur Ubuntu 24.04, la lecture se fait via systemd, précisez-le, sinon la prison reste inactive.

bash
sudo apt install -y fail2ban

sudo tee /etc/fail2ban/jail.local <<'EOF'
[DEFAULT]
backend  = systemd
bantime  = 1h
findtime = 10m
maxretry = 4

[sshd]
enabled = true
EOF

sudo systemctl enable --now fail2ban
sudo fail2ban-client status sshd

7. Automatiser les correctifs de sécurité

Un serveur oublié pendant six mois est un serveur vulnérable. Les mises à jour de sécurité non surveillées valent mieux que les mises à jour surveillées qui n'arrivent jamais.

bash
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
sudo unattended-upgrade --dry-run --debug

Pour les noyaux, activez Unattended-Upgrade::Automatic-Reboot "true"; avec une fenêtre horaire (Automatic-Reboot-Time "04:00";) dans /etc/apt/apt.conf.d/50unattended-upgrades si le service tolère un redémarrage nocturne.

8. Vérifier le résultat

Trois commandes suffisent à confirmer que la surface d'attaque est bien celle que vous croyez.

bash
# ce qui écoute réellement, IPv4 et IPv6
sudo ss -tulpen

# tentatives d'authentification récentes
sudo journalctl -u ssh --since "1 hour ago" | tail -30

# état du pare-feu, familles comprises
sudo ufw status numbered

Si ss révèle un service en écoute sur 0.0.0.0 ou [::] que vous n'avez pas déployé, un serveur de base de données, un cache, liez-le à 127.0.0.1 et ::1 plutôt que de compter sur le pare-feu seul.

Checklist

  • Système à jour et redémarré si le noyau a changé.
  • Compte non-root avec sudo, connexion par clé validée.
  • PermitRootLogin no et PasswordAuthentication no.
  • UFW en refus par défaut, actif sur IPv4 et IPv6.
  • fail2ban actif avec le backend systemd.
  • Mises à jour de sécurité automatiques.
  • Une sauvegarde prise une fois la configuration terminée.

Ce dernier point compte autant que les autres : sur nos VPS, 7 sauvegardes manuelles sont incluses, vous les déclenchez quand vous voulez, et le meilleur moment est juste après un durcissement réussi. C'est le point de retour vers lequel vous reviendrez le jour où une expérimentation tourne mal.