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. Il traite aussi le cas des
paramètres noyau, où la méthode classique échoue en silence sur RHEL. Toutes
les commandes ont été validées en VM sur Debian 12, AlmaLinux 9.8 et
AlmaLinux 10.2. Cette page couvre la recommandation ANSSI-BP-028 R5 et
les contrôles CIS 1.4.1 / 1.4.2.
Ce que vous allez apprendre
Section intitulée « Ce que vous allez apprendre »- 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)
- Poser un paramètre noyau persistant avec l'outil qui fonctionne vraiment sur votre distribution
- Vérifier la configuration et la restaurer en cas d'erreur
Pourquoi protéger le bootloader
Section intitulée « Pourquoi protéger le bootloader »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.
Prérequis
Section intitulée « Prérequis »- Un accès root (ou
sudo). - Une VM de test avec snapshot avant toute manipulation.
- GRUB 2 (le standard sur toutes les distributions modernes).
Générer un mot de passe GRUB chiffré
Section intitulée « Générer un mot de passe GRUB chiffré »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) :
grub-mkpasswd-pbkdf2L'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...70D4AC03Copiez 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.
Déclarer le superuser et le mot de passe
Section intitulée « Déclarer le superuser et le mot de passe »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) :
cat >> /etc/grub.d/40_custom <<'EOF'set superusers="bootadmin"password_pbkdf2 bootadmin grub.pbkdf2.sha512.10000.VOTRE.HASH.ICIEOFset superusersdéfinit qui peut éditer les entrées et ouvrir la console.password_pbkdf2associe l'utilisateur GRUBbootadminà son hachage.
Choisissez un nom de superuser distinct de root (défense en profondeur).
Red Hat fournit un utilitaire dédié, grub2-setpassword (interactif, exige un
vrai terminal) :
grub2-setpasswordIl écrit le hachage dans /boot/grub2/user.cfg sous la forme
GRUB2_PASSWORD=grub.pbkdf2..., et crée automatiquement le superuser root
(inutile de définir set superusers). Par défaut, il ne protège que l'édition et
la console, pas le démarrage : c'est exactement le comportement recherché, livré
sans configuration supplémentaire.
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 :
grep '^CLASS=' /etc/grub.d/10_linux# CLASS="--class gnu-linux --class gnu --class os"
sed -i '/^CLASS=/ s/"$/ --unrestricted"/' /etc/grub.d/10_linuxToutes les entrées normales hériteront de --unrestricted à la régénération.
Rien à faire : grub2-setpassword configure déjà la protection pour qu'elle ne
s'applique qu'à l'édition, pas au démarrage. Si vous vouliez au contraire exiger
le mot de passe à chaque boot, il faudrait retirer --unrestricted des entrées
(via 10_linux) avant de régénérer.
Régénérer et vérifier
Section intitulée « Régénérer et vérifier »Appliquez la configuration en régénérant grub.cfg :
update-grubGenerating grub configuration file ...Found linux image: /boot/vmlinuz-6.1.0-49-amd64doneVérifiez que les directives et l'option sont bien écrites :
grep -E 'set superusers|password_pbkdf2' /boot/grub/grub.cfggrep -c 'menuentry.*--unrestricted' /boot/grub/grub.cfgLa sortie doit montrer set superusers="bootadmin", la ligne password_pbkdf2, et
un compteur non nul d'entrées --unrestricted.
grub2-mkconfig -o /boot/grub2/grub.cfgVérifiez le hachage et son chargement :
grep GRUB2_PASSWORD /boot/grub2/user.cfgEn UEFI, localisez grub.cfg au lieu de le supposer
Section intitulée « En UEFI, localisez grub.cfg au lieu de le supposer »L'emplacement du grub.cfg actif en UEFI a bougé d'une version à l'autre, et
c'est une source d'erreur classique. Sur une AlmaLinux 9.8,
/boot/grub2/grub.cfg n'existait pas : le fichier actif était
/boot/efi/EFI/almalinux/grub.cfg. Sur une AlmaLinux 10.2, c'est unifié :
/boot/grub2/grub.cfg existe, /etc/grub2.cfg et /etc/grub2-efi.cfg sont deux
liens symboliques qui pointent tous deux dessus, et le fichier EFI n'est plus
qu'une amorce de quatre lignes qui délègue :
search --no-floppy --root-dev-only --fs-uuid --set=dev cea79fb2-...set prefix=($dev)/grub2export $prefixconfigfile $prefix/grub.cfgDans les deux cas, le user.cfg écrit par grub2-setpassword est bien pris en
compte, puisqu'il est chargé via ${prefix}/user.cfg. La règle à retenir est donc
la même quelle que soit la version : localisez votre grub.cfg actif au lieu
de supposer son chemin, puis ciblez-le pour grub2-mkconfig.
find /boot -name grub.cfgRestreindre 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 :
# Debian/Ubuntuchown root:root /boot/grub/grub.cfgchmod og-rwx /boot/grub/grub.cfg
# RHEL/AlmaLinux/Rockychown root:root /boot/grub2/grub.cfg /boot/grub2/user.cfgchmod og-rwx /boot/grub2/grub.cfg /boot/grub2/user.cfgVérifiez :
stat -c '%a %U:%G' /boot/grub/grub.cfg600 root:rootLa 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).
Vérifier que la protection fonctionne
Section intitulée « Vérifier que la protection fonctionne »La preuve se fait au redémarrage :
-
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 -
Redémarrer la machine. Le système doit démarrer normalement, sans demander de mot de passe (grâce à
--unrestricted). -
Au menu GRUB, presser
e(éditer) ouc(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.
Dépannage
Section intitulée « Dépannage »| Symptôme | Cause probable | Solution |
|---|---|---|
| Mot de passe demandé à chaque boot | superusers défini sans --unrestricted | Ajouter --unrestricted à CLASS dans 10_linux, puis régénérer |
| Système non démarrable après config | Erreur 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.cfg | Toujours 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 distro | find /boot -name grub.cfg puis cibler ce fichier |
Paramètre noyau absent de /proc/cmdline après édition de /etc/default/grub et régénération, sur RHEL | Le BLS est actif : grub2-mkconfig ne réécrit pas /boot/loader/entries/ | sudo grubby --update-kernel=ALL --args="…" |
Ajouter un paramètre noyau : grub2-mkconfig ne suffit pas sur RHEL
Section intitulée « Ajouter un paramètre noyau : grub2-mkconfig ne suffit pas sur RHEL »Le durcissement amène souvent à poser un paramètre noyau persistant
(audit=1, slab_nomerge, init_on_alloc=1). La méthode qu'on lit partout,
« éditez /etc/default/grub puis régénérez », ne fonctionne pas sur RHEL 8
et suivantes, ni sur AlmaLinux et Rocky. Elle échoue en silence, ce qui est
pire qu'une erreur.
La cause est le BLS (Boot Loader Specification), actif par défaut
(GRUB_ENABLE_BLSCFG=true dans /etc/default/grub). Chaque noyau installé a
son propre fichier d'entrée sous /boot/loader/entries/, et c'est la ligne
options de ce fichier qui est réellement lue au démarrage.
Mesuré sur AlmaLinux 10.2 : après édition de GRUB_CMDLINE_LINUX puis
grub2-mkconfig -o /boot/grub2/grub.cfg, le fichier d'entrée BLS est
identique au bit près. Le paramètre n'apparaît que dans grub.cfg, à un
endroit que GRUB ne lit jamais quand le BLS est actif.
| Emplacement | Après grub2-mkconfig | Après grubby --update-kernel=ALL |
|---|---|---|
/boot/loader/entries/*.conf (lu au boot) | inchangé | modifié |
/boot/grub2/grub.cfg (repli kernelopts, ignoré) | modifié | inchangé |
/etc/default/grub | modifié à la main | modifié aussi |
/etc/kernel/cmdline (modèle des futurs noyaux) | inchangé | modifié |
/proc/cmdline au redémarrage suivant | inchangé | modifié |
L'outil qui agit sur les noyaux déjà installés est donc grubby :
sudo grubby --update-kernel=ALL --args="audit=1"sudo grubby --info=ALL | grep ^argsÉditer /etc/default/grub reste utile, mais pour une autre raison : ce fichier
alimente /etc/kernel/cmdline, le modèle appliqué aux futurs noyaux à leur
installation. Les deux gestes ne visent pas la même population de noyaux, et
c'est pour cela qu'il faut souvent les deux.
Pour retirer un paramètre, grubby sait aussi défaire :
sudo grubby --update-kernel=ALL --remove-args="audit=1"Le sujet a sa page dédiée, avec le détail des quatre emplacements possibles, la méthode Debian, la vérification après redémarrage et le dépannage : Passer des paramètres au noyau au démarrage.
Mettre en pratique
Section intitulée « Mettre en pratique »Manipuler la configuration GRUB reste abstrait tant qu'on n'a pas régénéré soi-même un grub.cfg et constaté l'effet au redémarrage. Ce lab vous fait ajouter un paramètre noyau persistant, l'appliquer avec l'outil adapté à votre distribution (grubby sur RHEL, update-grub sur Debian), puis prouver le résultat dans /proc/cmdline après redémarrage, sur une VM jetable où l'erreur ne coûte rien.
À retenir
Section intitulée « À retenir »- 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_pbkdf2dans/etc/grub.d/40_custom, puisupdate-grub - RHEL :
grub2-setpasswordfait tout, et ne protège que l'édition par défaut --unrestrictedest la clé : le système démarre sans mot de passe, seule l'édition est protégée- Ne touchez jamais
grub.cfgdirectement (régénéré) ; snapshot obligatoire avant tout test - Sur RHEL et dérivées, un paramètre noyau se pose avec
grubby --update-kernel=ALL: à cause du BLS,/etc/default/grub+grub2-mkconfigne touche pas les noyaux déjà installés
Pour aller plus loin
Section intitulée « Pour aller plus loin »- Méthode de diagnostic Linux : La démarche à suivre avant de toucher à une machine devenue capricieuse après un durcissement.
- Un serveur qui ne termine pas son démarrage : Reprendre la main quand le boot s'arrête, la situation où le mot de passe GRUB se fait sentir.