← RETOUR À L'INDEX
/tutoriels/ infrastructure / hardening-initial-d'un-vps-ubuntu-24.04.md

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.

CAT · INFRA LECTURE · 6 min PUBLIÉ · 2026-04-12

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 root@95.216.161.94
# Saisir le mot de passe temporaire fourni par Hetzner
⚠️ Sécurité

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 root@95.216.161.94:/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é :

PaquetRôle
ufwFirewall applicatif — règles simples par port/protocole
fail2banBannissement IP après N échecs d’authentification
unattended-upgradesMises à jour de sécurité automatiques (security only)
⚠️ Sécurité

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 hermes@95.216.161.94

Action manuelle obligatoire — ouvre un second terminal :

# Terminal 2 — depuis ta machine locale
ssh -i ~/.ssh/hermes_hetzner hermes@95.216.161.94
# Attendu : prompt  hermes@<hostname>:~$
⚠️ Sécurité

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 :

DirectiveValeurEffet
PermitRootLoginnoConnexion root SSH impossible
PasswordAuthenticationnoMot de passe refusé — clé obligatoire
PubkeyAuthenticationyesAuthentification par clé activée

Le script valide la syntaxe avec sshd -t avant de redémarrer.

⚠️ Sécurité

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 root@95.216.161.94
# 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
⚠️ Sécurité

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ômeCause probableFix
ssh hermes@... Permission denied (publickey)Mauvaise clé ou mauvais chemin -iVérifier ssh -i ~/.ssh/hermes_hetzner ... explicitement
sshd -t retourne des erreursModification manuelle du sshd_config avant le scriptRestaurer le backup : cp /etc/ssh/sshd_config.bak.* /etc/ssh/sshd_config
UFW bloque tout après activationRègle SSH oubliée avant ufw enableDepuis la console Hetzner KVM : ufw allow 22/tcp && ufw reload
fail2ban en état failedConflit de config avec la default jailfail2ban-client status puis journalctl -u fail2ban -n 30
Le script s’arrête sur set -euo pipefailCommande retournant un code d’erreur non géréLancer avec bash -x setup-01-hardening.sh pour tracer l’exécution

Références

VR · 2026-04-12 · vraffin.dev FIN DU DOCUMENT