Aller au contenu
Sécurité medium

Protéger GRUB par mot de passe (durcissement du bootloader)

9 min de lecture

Sans protection, toute personne ayant un accès physique à votre serveur peut, au menu GRUB, presser e pour éditer la ligne de commande du noyau, y ajouter init=/bin/bash ou single, et obtenir un shell root sans mot de passe. Tout votre durcissement système est alors contourné en dix secondes. Ce guide montre comment protéger l'édition des entrées GRUB par mot de passe, tout en laissant le serveur démarrer normalement (sans invite à chaque boot), sous Debian/Ubuntu et RHEL/AlmaLinux/Rocky. Toutes les commandes ont été validées en VM sur Debian 12 et AlmaLinux 9.8. Cette page couvre la recommandation ANSSI-BP-028 R5 et les contrôles CIS 1.4.1 / 1.4.2.

  • Générer un mot de passe GRUB chiffré (PBKDF2)
  • Protéger l'édition des entrées et la console GRUB
  • Laisser le système démarrer sans mot de passe (éviter le piège du blocage)
  • Vérifier la configuration et la restaurer en cas d'erreur

Le mot de passe root, SELinux, auditd : tout cela s'applique après le démarrage du noyau. Or GRUB s'exécute avant, et il permet par défaut de modifier les paramètres de boot. Un attaquant avec un accès console (physique, KVM, ou une VM) édite une entrée, force un shell d'urgence, et lit ou modifie le système hors de tout contrôle. Protéger GRUB ferme cette porte.

L'objectif n'est pas de demander un mot de passe à chaque démarrage (ingérable sur un serveur qui doit redémarrer seul), mais de n'exiger l'authentification que pour éditer une entrée ou ouvrir la console GRUB. Le démarrage normal reste automatique.

  • Un accès root (ou sudo).
  • Une VM de test avec snapshot avant toute manipulation.
  • GRUB 2 (le standard sur toutes les distributions modernes).

GRUB ne stocke jamais le mot de passe en clair : il utilise un hachage PBKDF2 (SHA-512). Générez-le avec grub-mkpasswd-pbkdf2 (Debian/Ubuntu) ou grub2-mkpasswd-pbkdf2 (RHEL) :

Fenêtre de terminal
grub-mkpasswd-pbkdf2

L'outil demande le mot de passe deux fois, puis affiche le hachage :

PBKDF2 hash of your password is grub.pbkdf2.sha512.10000.809AB137...38817EB8.5E09FF7B...70D4AC03

Copiez la chaîne complète qui commence par grub.pbkdf2.sha512 : c'est elle que vous placerez dans la configuration. Le mot de passe en clair n'apparaît nulle part.

La déclaration diffère entre les deux familles de distributions. Ne modifiez jamais grub.cfg directement : ce fichier est régénéré (et donc écrasé) à chaque mise à jour de noyau.

Créez un fichier dans /etc/grub.d/. Le 40_custom est le bon endroit (les CIS déconseillent 00_header, écrasé lors des mises à jour du paquet) :

Fenêtre de terminal
cat >> /etc/grub.d/40_custom <<'EOF'
set superusers="bootadmin"
password_pbkdf2 bootadmin grub.pbkdf2.sha512.10000.VOTRE.HASH.ICI
EOF
  • set superusers définit qui peut éditer les entrées et ouvrir la console.
  • password_pbkdf2 associe l'utilisateur GRUB bootadmin à son hachage.

Choisissez un nom de superuser distinct de root (défense en profondeur).

Le piège : booter sans mot de passe, protéger l'édition

Section intitulée « Le piège : booter sans mot de passe, protéger l'édition »

C'est l'étape la plus importante, et celle que beaucoup ratent. Dès que superusers est défini, GRUB protège TOUTES les entrées par défaut : le serveur demande alors le mot de passe à chaque démarrage. Sur un serveur, c'est inacceptable.

La solution est le flag --unrestricted : une entrée marquée ainsi démarre sans mot de passe, mais son édition (e) et la console GRUB (c) restent protégées.

Les entrées sont générées par /etc/grub.d/10_linux. Lisez d'abord la ligne CLASS= réellement installée (elle varie selon la version), puis ajoutez --unrestricted :

Fenêtre de terminal
grep '^CLASS=' /etc/grub.d/10_linux
# CLASS="--class gnu-linux --class gnu --class os"
sed -i '/^CLASS=/ s/"$/ --unrestricted"/' /etc/grub.d/10_linux

Toutes les entrées normales hériteront de --unrestricted à la régénération.

Appliquez la configuration en régénérant grub.cfg :

Fenêtre de terminal
update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-6.1.0-49-amd64
done

Vérifiez que les directives et l'option sont bien écrites :

Fenêtre de terminal
grep -E 'set superusers|password_pbkdf2' /boot/grub/grub.cfg
grep -c 'menuentry.*--unrestricted' /boot/grub/grub.cfg

La sortie doit montrer set superusers="bootadmin", la ligne password_pbkdf2, et un compteur non nul d'entrées --unrestricted.

Restreindre les permissions (CIS 1.4.2, ANSSI R29)

Section intitulée « Restreindre les permissions (CIS 1.4.2, ANSSI R29) »

Le fichier grub.cfg contient le hachage du mot de passe et les paramètres de boot. S'il est lisible par tous, ces éléments fuitent. Restreignez-le à root seul :

Fenêtre de terminal
# Debian/Ubuntu
chown root:root /boot/grub/grub.cfg
chmod og-rwx /boot/grub/grub.cfg
# RHEL/AlmaLinux/Rocky
chown root:root /boot/grub2/grub.cfg /boot/grub2/user.cfg
chmod og-rwx /boot/grub2/grub.cfg /boot/grub2/user.cfg

Vérifiez :

Fenêtre de terminal
stat -c '%a %U:%G' /boot/grub/grub.cfg
600 root:root

La valeur exacte attendue varie selon le référentiel (0400 pour le CIS Ubuntu 22.04, 0600 pour le CIS CentOS 7) ; og-rwx retire dans tous les cas l'accès aux autres comptes, ce qui satisfait l'intention. Pensez aussi à restreindre /boot lui-même (ANSSI R29).

La preuve se fait au redémarrage :

  1. Confirmer la présence des directives dans la configuration active :

    Fenêtre de terminal
    grep -E 'password_pbkdf2|GRUB2_PASSWORD' /boot/grub/grub.cfg /boot/grub2/user.cfg 2>/dev/null
  2. Redémarrer la machine. Le système doit démarrer normalement, sans demander de mot de passe (grâce à --unrestricted).

  3. Au menu GRUB, presser e (éditer) ou c (console) : GRUB doit alors réclamer un identifiant et un mot de passe. C'est la protection en action.

En lab, le redémarrage a confirmé l'absence de blocage : la VM est revenue en moins de dix secondes sans invite, tout en conservant la directive password_pbkdf2 active dans grub.cfg.

SymptômeCause probableSolution
Mot de passe demandé à chaque bootsuperusers défini sans --unrestrictedAjouter --unrestricted à CLASS dans 10_linux, puis régénérer
Système non démarrable après configErreur de syntaxe ou hachage tronquéRestaurer le snapshot ; sinon démarrer sur un live USB et corriger /etc/grub.d/
Modifications perdues après mise à jourÉdition directe de grub.cfgToujours passer par /etc/grub.d/ + /etc/default/grub, jamais grub.cfg
grub2-setpassword échoue (Inappropriate ioctl)Pas de vrai terminal (script, pipe)Le lancer en interactif ; ou générer le hachage avec grub2-mkpasswd-pbkdf2 et écrire user.cfg à la main
grub.cfg introuvable au chemin attendu (UEFI)Emplacement EFI variable selon la distrofind /boot -name grub.cfg puis cibler ce fichier
  • GRUB s'exécute avant le noyau : sans mot de passe, l'édition d'une entrée donne un root sans authentification
  • Le hachage PBKDF2 se génère avec grub-mkpasswd-pbkdf2 ; le clair n'est jamais stocké
  • Debian : set superusers + password_pbkdf2 dans /etc/grub.d/40_custom, puis update-grub
  • RHEL : grub2-setpassword fait tout, et ne protège que l'édition par défaut
  • --unrestricted est la clé : le système démarre sans mot de passe, seule l'édition est protégée
  • Ne touchez jamais grub.cfg directement (régénéré) ; snapshot obligatoire avant tout test

Ce site vous est utile ?

Sachez que moins de 1% des lecteurs soutiennent ce site.

Je maintiens +700 guides gratuits, sans pub ni tracking. Un soutien, même symbolique, m'aide à couvrir l'hébergement et à garder ces ressources gratuites. Merci pour votre appui.

Le formulaire ne s'affiche pas ? Ouvrir Ko-fi dans un onglet.

Abonnez-vous et suivez mon actualité DevSecOps sur LinkedIn