Activer Le Secure Boot Avec REFInd Et Une Clé Personnelle
Même si cela apporte plus de problème qu’autre chose, nous allons voir comment activer le secure boot avec une distribution Linux comme Pop OS avec le lanceur de démarrage ReFind. Le principe devrait être le même avec Grub, à savoir signer l’ensemble de la chaine de boot.
Le contexte
La machine de référence pour cet article :
- firmware UEFI avec Secure Boot activable et clés Microsoft d’origine
- dual boot Windows 11 et Pop!_OS 24.04 LTS (COSMIC)
- rEFInd comme gestionnaire de démarrage
La chaîne de confiance
Le Secure Boot est une chaîne : chaque maillon vérifie le suivant avant de lui passer la main. Si un seul maillon n’est pas signé par une clé approuvée, tout s’arrête là.
Le firmware ne fait confiance qu’aux certificats présents dans sa base db. En pratique, sur une machine du commerce, ce sont ceux de Microsoft et du fabricant. Signer soi-même du code revient donc à insérer sa propre clé quelque part dans cette chaîne. Le plus simple est de continuer à utiliser la clé Windows pour démarrer Windows et de rajouter votre propre clé pour la partie Linux.
Il existe un lanceur de démarrage nommé Shim signé par la clé de Microsoft qu’on va pouvoir configurer pour accepter des binaires signés avec notre clé.
flowchart TD
FW["Firmware UEFI
base db : Microsoft + ASUS"]
SHIM["shimx64.efi
signé par Microsoft"]
MOK[("MOK
notre clé personnelle")]
REFIND["grubx64.efi = rEFInd
signé avec la MOK"]
DRIVER["drivers_x64/ext4_x64.efi
signé avec la MOK"]
KERNEL["/boot/vmlinuz
signé avec la MOK"]
WIN["Windows Boot Manager
signé par Microsoft"]
FW -->|vérifie via db| SHIM
FW -->|vérifie via db| WIN
SHIM -->|charge le nom fixe grubx64.efi| REFIND
MOK -.->|base de clés secondaire| SHIM
REFIND -->|lecture de la partition ext4| DRIVER
DRIVER --> KERNEL
flowchart TD
FW["Firmware UEFI
base db : Microsoft + ASUS"]
SHIM["shimx64.efi
signé par Microsoft"]
MOK[("MOK
notre clé personnelle")]
REFIND["grubx64.efi = rEFInd
signé avec la MOK"]
DRIVER["drivers_x64/ext4_x64.efi
signé avec la MOK"]
KERNEL["/boot/vmlinuz
signé avec la MOK"]
WIN["Windows Boot Manager
signé par Microsoft"]
FW -->|vérifie via db| SHIM
FW -->|vérifie via db| WIN
SHIM -->|charge le nom fixe grubx64.efi| REFIND
MOK -.->|base de clés secondaire| SHIM
REFIND -->|lecture de la partition ext4| DRIVER
DRIVER --> KERNEL
flowchart TD
FW["Firmware UEFI
base db : Microsoft + ASUS"]
SHIM["shimx64.efi
signé par Microsoft"]
MOK[("MOK
notre clé personnelle")]
REFIND["grubx64.efi = rEFInd
signé avec la MOK"]
DRIVER["drivers_x64/ext4_x64.efi
signé avec la MOK"]
KERNEL["/boot/vmlinuz
signé avec la MOK"]
WIN["Windows Boot Manager
signé par Microsoft"]
FW -->|vérifie via db| SHIM
FW -->|vérifie via db| WIN
SHIM -->|charge le nom fixe grubx64.efi| REFIND
MOK -.->|base de clés secondaire| SHIM
REFIND -->|lecture de la partition ext4| DRIVER
DRIVER --> KERNEL
|
|
Trois points méritent d’être soulignés sur ce schéma.
shim charge un fichier au nom figé. Il cherche grubx64.efi dans son propre répertoire, quel que soit le chargeur réellement utilisé. On copie donc refind_x64.efi sous ce nom.
Le noyau Linux n’est pas sur l’ESP. Contrairement à Windows, dont tout le nécessaire de démarrage tient sur la partition FAT32, le noyau vit dans /boot, sur la racine ext4. Or le firmware UEFI ne sait lire que du FAT. rEFInd contourne ça avec ses propres pilotes de système de fichiers, dans drivers_x64/.
Ces pilotes sont du code EFI comme un autre. Sous Secure Boot, ils doivent donc être signés. C’est le maillon que l’on oublie, parce qu’il est invisible tant que le Secure Boot est désactivé : sans signature, rEFInd démarre parfaitement, affiche son menu, mais ne peut plus lire la partition Linux. L’entrée Pop!_OS disparaît du menu, ou échoue si elle est déclarée manuellement dans refind.conf.
Une remarque sur Pop!_OS
Pop!_OS n’utilise pas GRUB mais systemd-boot, alimenté par kernelstub, qui recopie le noyau et l’initrd dans l’ESP sous \EFI\Pop_OS-<uuid-racine>\. Si vous démarrez par systemd-boot, c’est cette copie qu’il faut signer, et pas /boot/vmlinuz-* — la signer serait sans effet.
Avec rEFInd le comportement est différent : il lit /boot directement sur la racine ext4. Pour savoir dans quel cas vous êtes, regardez la ligne de commande du noyau après un démarrage réussi :
|
|
Un initrd=\boot\initrd.img avec des antislashs et sans BOOT_IMAGE= indique que rEFInd a chargé le noyau depuis la partition Linux. Un chemin sous \EFI\Pop_OS-… indique un passage par systemd-boot.
Dans mon cas, j’ai choisi de ne pas passer par systemd-boot pour éviter une étape supplémentaire.
Prérequis
|
|
sbsigntool fournit sbsign et sbverify, mokutil permet de gérer la base MOK, et shim-signed fournit le binaire shim signé par Microsoft ainsi que MokManager.
1. Générer la clé
Les clés seront utilisées par un hook exécuté en root lors des mises à jour du noyau. On les range donc dans /root.
J’utilise l’option codeSigning pour signer des binaires EFI. Cela permet de réutiliser cette même clé pour signer les modules du noyau. Sans cela les pilotes NVidia par exemple ne fonctionneront pas.
-nodes génère une clé privée sans passphrase : c’est indispensable pour que la signature automatique fonctionne sans intervention. En contrepartie, quiconque obtient un accès root à la machine peut signer du code qui démarrera avec le Secure Boot actif. Protégez le répertoire en conséquence :
mokutil attend un certificat au format DER, on en produit une conversion :
On garde les deux formats : le .crt (PEM) pour sbsign et sbverify, le .der pour mokutil.
2. Enrôler la clé dans la MOK
|
|
La commande demande un mot de passe. Il est à usage unique : il ne servira qu’au prochain démarrage pour confirmer l’enrôlement. Choisissez quelque chose de simple à saisir sur un clavier QWERTY, car MokManager ne tient pas compte de la disposition du clavier configurée dans le système.
mokutil --import ne fait qu’enregistrer une demande. Il faut ensuite redémarrer. Un écran bleu apparaît alors, avant tout gestionnaire de démarrage :
- Enroll MOK
- Continue
- Yes
- saisir le mot de passe choisi à l’étape précédente
- Reboot
Si vous laissez le compte à rebours expirer ou si vous choisissez Continue boot, la demande est abandonnée et la clé n’est pas enrôlée. Il faut donc reprendre au mokutil --import.
Pour vérifier, une fois redémarré :
|
|
Un piège de plus : quand le Secure Boot est désactivé, shim ne recopie pas la MokList complète dans la variable runtime que lit mokutil. Il est donc parfaitement normal de ne voir que le certificat Canonical dans cette situation, sans que cela signifie que votre clé a disparu. Refaites la vérification avec le Secure Boot actif si vous avez un doute. Pour lever complètement l’ambiguïté, la meilleure preuve reste de regarder ce qui est effectivement signé, avec sbverify --list.
Une demande d’enrôlement encore en attente se consulte avec :
|
|
3. Installer shim à côté de rEFInd
On copie shim et MokManager dans le répertoire de rEFInd sur l’ESP. Attention à renommer shim au passage : le paquet Ubuntu le livre sous le nom shimx64.efi.dualsigned.
mmx64.efi est MokManager, l’écran bleu de l’étape précédente. Il doit se trouver dans le même répertoire que shim, sinon l’enrôlement des clés devient impossible. Ni l’un ni l’autre ne doit être re-signé : shim est signé par Microsoft, MokManager par Canonical, et shim reconnaît ce dernier grâce à son certificat embarqué.
On copie ensuite rEFInd sous le nom que shim ira chercher :
|
|
Cette copie doit être refaite après chaque mise à jour de rEFInd — et signée, comme l’original.
4. Signer les binaires
Une remarque de méthode avant les commandes. On lit souvent :
Écrire la sortie sur le fichier d’entrée est risqué : une interruption ou une erreur en cours de route laisse un binaire tronqué, donc une machine qui ne démarre plus. On signe vers un fichier temporaire, et on ne remplace l’original qu’une fois la signature réussie. Cette petite fonction fait le travail et évite au passage d’empiler à nouveau une signature sur un fichier déjà valide :
|
|
Ce garde-fou n’est pas cosmétique : sbsign ajoute une signature au lieu de remplacer l’existante. Un binaire re-signé à chaque mise à jour finit avec une pile de signatures identiques qui grossit indéfiniment.
Reste à l’appliquer aux bons fichiers :
|
|
Si vous avez plusieurs noyaux installés et que vous souhaitez pouvoir les sélectionner dans rEFInd, signez-les tous :
Vérifier
sbverify --list affiche les signatures présentes sur un binaire :
|
|
signature 1
image signature issuers:
- /CN=MyCustom
image signature certificates:
- subject: /CN=MyCustom
issuer: /CN=MyCustomEt pour valider un fichier contre une clé précise, ce qui est plus parlant :
Aucun KO ne doit subsister avant de réactiver le Secure Boot.
5. Créer l’entrée de démarrage
Le firmware doit maintenant démarrer sur shim, et non plus directement sur rEFInd :
|
|
Adaptez -d (le disque portant l’ESP) et -p (le numéro de partition) à votre machine. Pour les retrouver :
|
|
Vérifiez ensuite que la nouvelle entrée existe et arrive en tête de BootOrder :
|
|
Ne supprimez pas tout de suite l’ancienne entrée pointant sur refind_x64.efi : elle reste un filet de sécurité tant que le Secure Boot est désactivé.
6. Automatiser pour les mises à jour du noyau
Chaque nouveau noyau arrive non signé. Sans automatisation, la machine cesse de démarrer à la première mise à jour. On place donc un hook dans /etc/kernel/postinst.d/.
Le nom du fichier compte : les hooks sont exécutés dans l’ordre alphabétique. Sur Pop!_OS, zz-kernelstub, zz-systemd-boot et zz-update-grub s’exécutent déjà en fin de liste et manipulent les fichiers de démarrage. On préfixe donc en zzz- pour être certain de passer en dernier.
/etc/kernel/postinst.d/zzz-sign-secureboot :
|
|
|
|
Le exit 0 final est délibéré : un hook qui échoue interrompt la configuration du paquet du noyau et laisse dpkg dans un état bancal. Il vaut mieux un message d’erreur bien visible et un système qu’on peut réparer à froid.
On teste sans attendre la prochaine mise à jour :
|
|
La sortie doit contenir les lignes zzz-sign-secureboot : signé …, ou rien du tout si tout était déjà signé.
7. Activer le Secure Boot
Il ne reste plus qu’à réactiver le Secure Boot dans le firmware, en veillant à démarrer sur l’entrée shim. Une fois le système lancé :
|
|
SecureBoot enabledVérifiez aussi que le noyau se sait démarré en mode vérifié :
|
|
Le noyau active alors le mode lockdown : kexec non signé, écriture dans /dev/mem et chargement de modules dont la signature n’est pas vérifiable sont refusés. C’est le sujet de la section suivante, et il vaut mieux la lire avant de redémarrer.
8. Les modules du noyau : NVIDIA et les autres DKMS
Le symptôme est déconcertant parce qu’il ne ressemble pas à une panne de démarrage. Le système démarre, la session graphique s’ouvre, tout a l’air normal — mais un seul écran s’allume. Sur une machine à deux GPU, ceux qui sont câblés sur la carte NVIDIA restent noirs, tandis que le GPU intégré continue de piloter l’écran principal. Rien dans l’interface ne signale quoi que ce soit.
L’explication tient au lockdown. Le pilote propriétaire NVIDIA n’est pas dans le noyau : il est compilé sur la machine par DKMS à chaque nouvelle version du noyau. Sous Secure Boot, un module dont la signature ne remonte pas à une clé approuvée est purement et simplement refusé.
Solution propre : une seule clé pour tout
Pour n’avoir qu’une clé à gérer, on dit à DKMS d’utiliser la vôtre. Les deux variables se déclarent dans /etc/dkms/framework.conf.d/, un répertoire que DKMS lit en complément de framework.conf :
/etc/dkms/framework.conf.d/secureboot.conf :
mok_signing_key="/root/secureboot-keys/MOK.key"
mok_certificate="/root/secureboot-keys/MOK.der"Ces valeurs sont évaluées avant la logique par distribution, donc DKMS n’ira plus chercher /var/lib/shim-signed/mok/. Ne supprimez pas pour autant ce répertoire : il reste votre filet de secours si vous voulez revenir en arrière.
Les modules déjà construits portent encore l’ancienne signature. Comme celle-ci est apposée au moment du build, il faut forcer une reconstruction :
|
|
Vérifiez le résultat sans même redémarrer : le signer doit maintenant afficher le CN de votre clé.
|
|
C’est ici que l’extension codeSigning ajoutée à l’étape 1 prend son sens. Si votre certificat a été généré sans elle, régénérez-le — mais sachez que cela vous obligera à re-signer rEFInd, ses pilotes et les noyaux, puis à enrôler à nouveau la clé. D’où l’intérêt de la poser dès le départ.
Une fois redémarré avec le Secure Boot actif :
|
|
Conclusion
Votre PC doit désormais redémarrer en mode secure boot via ReFind et s’autogérer comme un grand lors des mises à jour du noyau. Cela offre une protection supplémentaire à votre PC.