Hardening initial d'un VPS Ubuntu 24.04
Sécuriser un VPS Hetzner fraîchement rebuild : utilisateur dédié, SSH par clé, UFW, fail2ban, mises à jour automatiques. Zéro port public — Tailscale dans le tuto suivant.
Temps estimé : 15 min
Résultat final : Un VPS Hetzner avec un utilisateur hermes accessible par clé SSH Ed25519, root login désactivé, authentification par mot de passe désactivée, UFW actif, fail2ban et unattended-upgrades configurés. Prêt pour l’installation de Tailscale (TUTO-13).
Objectif
Un VPS Hetzner fraîchement rebuild expose root par mot de passe temporaire. C’est une fenêtre de vulnérabilité : bots, brute-force, mauvaise manipulation. Ce tuto ferme cette fenêtre en moins de 15 minutes.
L’objectif final de la série est un VPS accessible uniquement via Tailscale (aucun port public ouvert). Ce tuto pose les fondations ; le suivant (TUTO-13) installera Tailscale et supprimera la règle SSH publique.
Prérequis
- VPS Hetzner rebuild sur Ubuntu 24.04 LTS
- Clé SSH Ed25519 locale générée (
~/.ssh/hermes_hetzner) - IP publique du VPS connue
- Accès root temporaire Hetzner (mot de passe dans la console Hetzner Cloud)
# Vérification locale avant de commencer
ls ~/.ssh/hermes_hetzner ~/.ssh/hermes_hetzner.pub
# Attendu : les deux fichiers existent
ssh-keygen -l -f ~/.ssh/hermes_hetzner.pub
# Attendu : 256 ED25519 ...
💡 Si la clé n’existe pas encore :
ssh-keygen -t ed25519 -C "hermes@hetzner-hel1" -f ~/.ssh/hermes_hetzner
Étape 1 : Connexion root initiale et téléchargement du script
Depuis ta machine locale, connecte-toi en root avec le mot de passe temporaire Hetzner :
ssh [email protected]
# Saisir le mot de passe temporaire fourni par Hetzner
Ne pas laisser cette fenêtre ouverte sans surveillance. Le mot de passe temporaire Hetzner est généré aléatoirement mais la surface d’attaque est maximale tant que root/password est actif.
Récupère le script depuis le repo :
# Sur le VPS, en root
curl -fsSL https://raw.githubusercontent.com/ton-org/tuto_ai_assistants/main/scripts/setup-01-hardening.sh \
-o /root/setup-01-hardening.sh
chmod 700 /root/setup-01-hardening.sh
💡 Exemple alternatif : si le repo est privé, copier le script via
scp:# Depuis ta machine locale scp scripts/setup-01-hardening.sh [email protected]:/root/
Vérification :
ls -la /root/setup-01-hardening.sh
# Attendu : -rwx------ 1 root root ... setup-01-hardening.sh
Étape 2 : Mise à jour système (Section 1 du script)
Le script commence par mettre à jour le système et installer les paquets de sécurité essentiels.
bash /root/setup-01-hardening.sh
# Le script s'arrête manuellement à la fin de la Section 2 — ne pas fermer le terminal
Ce qui est installé :
| Paquet | Rôle |
|---|---|
ufw | Firewall applicatif — règles simples par port/protocole |
fail2ban | Bannissement IP après N échecs d’authentification |
unattended-upgrades | Mises à jour de sécurité automatiques (security only) |
unattended-upgrades est configuré avec Automatic-Reboot "false". Un redémarrage automatique sur un VPS de production peut créer une fenêtre d’indisponibilité non planifiée. Planifie les reboots manuellement après vérification.
Vérification :
systemctl is-active fail2ban unattended-upgrades
# Attendu :
# active
# active
Étape 3 : Création de l’utilisateur hermes (Section 2 du script)
Le script crée l’utilisateur hermes, l’ajoute à sudo, et déploie la clé SSH.
# Le script affiche automatiquement à ce stade :
# STOP — Ouvre un second terminal et teste : ssh -i ~/.ssh/hermes_hetzner [email protected]
Action manuelle obligatoire — ouvre un second terminal :
# Terminal 2 — depuis ta machine locale
ssh -i ~/.ssh/hermes_hetzner [email protected]
# Attendu : prompt hermes@<hostname>:~$
Ne jamais fermer le terminal root avant d’avoir validé la connexion hermes dans un second terminal. Si la clé SSH est mal configurée et que tu confirmes quand même, tu perds tout accès au VPS sans passer par la console Hetzner (KVM).
Une fois la connexion validée, reviens dans le terminal root et tape oui pour continuer.
Vérification :
# Dans le second terminal (connecté en hermes)
id
# Attendu : uid=1000(hermes) gid=1000(hermes) groups=1000(hermes),27(sudo)
ls -la ~/.ssh/
# Attendu :
# drwx------ 2 hermes hermes ... .ssh/
# -rw------- 1 hermes hermes ... authorized_keys
Étape 4 : Hardening SSH (Section 3 du script)
Après ta confirmation, le script applique les restrictions SSH :
| Directive | Valeur | Effet |
|---|---|---|
PermitRootLogin | no | Connexion root SSH impossible |
PasswordAuthentication | no | Mot de passe refusé — clé obligatoire |
PubkeyAuthentication | yes | Authentification par clé activée |
Le script valide la syntaxe avec sshd -t avant de redémarrer.
Un sshd_config invalide redémarré sans validation coupe l’accès SSH définitivement (jusqu’à la console KVM Hetzner). La validation sshd -t est non négociable avant tout systemctl restart sshd.
Vérification :
# Depuis le terminal root
sshd -T | grep -E "permitrootlogin|passwordauthentication|pubkeyauthentication"
# Attendu :
# permitrootlogin no
# passwordauthentication no
# pubkeyauthentication yes
# Tentative de connexion root — doit échouer
ssh [email protected]
# Attendu : Permission denied (publickey)
Étape 5 : Firewall UFW (Section 4 du script)
# Politiques appliquées par le script
ufw status verbose
Attendu :
Status: active
Logging: on (low)
Default: deny (incoming), allow (outgoing), disabled (routed)
New profiles: skip
To Action From
-- ------ ----
22/tcp ALLOW IN Anywhere # SSH — temporaire
41641/udp ALLOW IN Anywhere # Tailscale WireGuard
Le port 22 est ouvert temporairement. Le script suivant (setup-02-tailscale.sh) installera Tailscale et supprimera cette règle pour n’accepter SSH que depuis l’interface tailscale0. Tant que ce n’est pas fait, le VPS reste exposé aux scans SSH publics — fail2ban atténue ce risque mais ne l’élimine pas.
Dépannage
| Symptôme | Cause probable | Fix |
|---|---|---|
ssh hermes@... Permission denied (publickey) | Mauvaise clé ou mauvais chemin -i | Vérifier ssh -i ~/.ssh/hermes_hetzner ... explicitement |
sshd -t retourne des erreurs | Modification manuelle du sshd_config avant le script | Restaurer le backup : cp /etc/ssh/sshd_config.bak.* /etc/ssh/sshd_config |
| UFW bloque tout après activation | Règle SSH oubliée avant ufw enable | Depuis la console Hetzner KVM : ufw allow 22/tcp && ufw reload |
fail2ban en état failed | Conflit de config avec la default jail | fail2ban-client status puis journalctl -u fail2ban -n 30 |
Le script s’arrête sur set -euo pipefail | Commande retournant un code d’erreur non géré | Lancer avec bash -x setup-01-hardening.sh pour tracer l’exécution |
Références
- Hetzner — Rebuild et accès root — procédure de rebuild VPS
- fail2ban — Configuration de base — documentation officielle
- UFW — Debian/Ubuntu Wiki — référence complète
- unattended-upgrades — configuration fine des mises à jour automatiques
- TUTO-02 — Hardening complémentaire (SSH Ed25519, Tailscale, Fail2ban avancé)