Debian bookworm entièrement chiffrée avec LUKS2
Le but ici est d’installer une Debian "bookworm/sid" (été 2022) sur un disque entièrement chiffré, y compris /boot. Cela était possible depuis quelques années, mais la partition contenant le noyau devait obligatoirement être chiffrée avec LUKS1 (voir [1]). GRUB 2.06 a introduit le support initial de LUKS2, nous pouvons donc à présent profiter des améliorations de LUKS2 y compris pour /boot.
Je suppose ici un démarrage EFI, tout en essayant de documenter les paramètres nécessaires à un démarrage traditionnel (BIOS) — sans les avoir testés.
Les étapes en bref
- Installation (non décrite ici) de Debian “bookworm” (“testing”) avec partitionnement assisté chiffré.
- Chiffrement de la partition /boot selon le même principe que dans [1], mais en LUKS2 avec PBKDF2 (puisque GRUB 2.06 ne supporte pas Argon).
- Création d’une image personnalisée de GRUB comme décrit dans [2], car GRUB 2.06 sait déchiffrer un volume LUKS2, mais n’embarque pas ce code dans le binaire EFI généré par
grub-install
. On va en profiter pour embarquer une carte de clavier personnalisée (bépo dans mon cas), comme décrit dans [1].
N.B. : toutes les commandes décrites ci-dessous sont à exécuter en root.
Chiffrement de /boot
Sauvegarde du contenu de /boot :
mount -oremount,ro /boot install -m0600 /dev/null /boot.tar tar -C /boot --acls --xattrs --one-file-system -cf /boot.tar .
Démontage de la partition :
umount /boot/efi umount /boot
Chiffrement de la partition (N.B. : dans mon cas, /boot est sur /dev/nvme0n1p2, remplacez par le bon périphérique chez vous) :
cryptsetup luksFormat --type luks2 --pbkdf pbkdf2 /dev/nvme0n1p2 uuid="$(blkid -o value -s UUID /dev/nvme0n1p2)" echo boot_crypt UUID=$uuid none luks,discard >>/etc/crypttab # Ici j'en profite pour renommer le volume principal en "root_crypt" dans # /etc/crypttab, mais ce n'est pas nécessaire. cryptdisks_start boot_crypt
Création d’un système de fichiers sur le volume chiffré (en réutilisant l’UUID du volume initial pour éviter d’avoir à modifier /etc/fstab) :
eval $(grep 'UUID=.*/boot ' /etc/fstab | cut -d' ' -f1) mkfs.ext2 -m0 -U $UUID /dev/mapper/boot_crypt mount -v /boot tar -C /boot --acls --xattrs -xf boot.tar
N.B. : contrairement à ce qui est décrit dans [1], il est inutile dans notre cas d’activer GRUB_ENABLE_CRYPTODISK
dans /etc/defaults/grub car nous allons créer notre propre image de GRUB.
Création de l’image GRUB
Créer le fichier de pré-configuration de GRUB (voir ci-dessous pour les explications et les éventuelles modifications à apporter dans votre environnement) :
uuid="$(blkid -o value -s UUID /dev/nvme0n1p2 | tr -d -)" # remplacez nvme0n1p2 cat >/boot/grub/grub-pre.cfg <<EOF terminal_input at_keyboard keymap (memdisk)/keymap.gkb set uuid=$uuid cryptomount -u \$uuid set root=crypto0 set prefix=(\$root)/grub insmod normal normal EOF
Script de génération de l’image GRUB, à enregistrer par exemple dans /boot/grub/grub-install.sh :
#!/bin/sh # Carte de clavier à utiliser (mettre par exemple "fr oss" pour le français # AZERTY) : KEYMAP="fr bepo" # Paramètres pour démarrage EFI : IMAGE_FORMAT=x86_64-efi OUTFILE=/boot/efi/EFI/debian/grubx64.efi # Paramètres pour démarrage BIOS traditionnel : #IMAGE_FORMAT="i386-pc" #OUTFILE=/boot/grub/i386-pc/core.img GRUB_PATH=/boot/grub GRUB_PRECONF="$GRUB_PATH"/grub-pre.cfg MEMDISK="$GRUB_PATH"/memdisk.tar MODULES="part_gpt cryptodisk luks2 pbkdf2 gcry_rijndael gcry_sha256 ext2 memdisk tar terminal keylayouts at_keyboard usb_keyboard" # Notes : # - Ajouter (ou remplacer "part_gpt" par) part_msdos pour gérer les tables de # partitions DOS. # - Remplacer ext2 par le module correspondant au système de fichiers de /boot. # - Ajouter "lvm" si /boot est sur un volume LVM. Ajuster également le chemin # de grub dans grub-pre.cfg (`($root)/boot/grub` au lieu de `($root)/grub`). # - Il est possible que "uhci" et "ehci" soient nécessaires pour un clavier # USB, mais quand ils sont présents le disque n'est plus détecté (même avec # le module ahci), donc à tester. set -x # Création du memdisk contenant la carte de clavier personnalisée : memdisk_tmp="$(mktemp --tmpdir --directory)" grub-kbdcomp -o "$memdisk_tmp"/keymap.gkb $KEYMAP tar -C "$memdisk_tmp" -cf "$MEMDISK" . rm -fr "$memdisk_tmp" # Génération de l'image GRUB : grub-mkimage -p "$GRUB_PATH" -O "$IMAGE_FORMAT" -c "$GRUB_PRECONF" -m "$MEMDISK" -o "$OUTFILE" $MODULES
Donner les droits d’exécution au script, l’exécuter, redémarrer et croiser les doigts :
chmod +x /boot/grub/grub-install.sh /boot/grub/grub-install.sh shutdown -r now
Explications sur grub-pre.cfg
Définition du type de clavier (at_keyboard
fonctionne pour le clavier de mon ordinateur portable ; mettre usb_keyboard
pour un clavier USB) :
terminal_input at_keyboard
Chargement de la carte clavier personnalisée à partir du “memdisk” créé par le script ci-dessus :
keymap (memdisk)/keymap.gkb
N.B. : les deux lignes précédentes peuvent être supprimées si l’on ne souhaite pas utiliser de carte de clavier personnalisée.
L’UUID utilisé ici est l’UUID, sans tirets, du volume chiffré contenant /boot (donc de /dev/nvme0n1p2 chez moi, pas du système de fichiers boot_crypt lui-même).
set uuid=XXXXXXXXXXXXXXXXX
Déchiffrement du volume :
cryptomount -u $uuid
Définition du volume de démarrage (celui qui contient /boot) :
set root=crypto0
Sur du LVM, on pointerait plutôt sur le LV contenant /boot :
set root=lvm/monvg-bootlv
Définition du chemin vers les fichiers de GRUB :
set prefix=($root)/grub
Penser à ajuster le chemin, par exemple si /boot est sur / :
set prefix=($root)/boot/grub
Les instructions suivantes appellent le mode “normal” (par opposition au mode “rescue”) et chargent grub.cfg :
insmod normal normal
Trucs et astuces
Éviter de taper deux fois le mot de passe
[1] propose une méthode pour éviter de taper deux fois le mot de passe au démarrage de la machine (chapitre 4, Avoiding the extra password prompt). Il s'agit d'inclure un fichier de clef (keyfile) dans l'image initrd. J'utilisais cette méthode lorsque mon /boot était chiffré avec LUKS1, car comme expliqué dans l'article, LUKS1 ne protège pas la clef d'un volume déverrouillé (elle est accessible en espace utilisateur via la table du device mapper).
En revanche, comme LUKS2 n'a pas ce problème, avoir un fichier contenant la clef de déchiffrement, lisible depuis l'espace utilisateur une fois la machine démarrée (soit depuis /etc/keys/, soit dans l'image initrd) devient un compromis inacceptable. Je me contente donc de taper deux fois le mot de passe (et deux fois seulement, car la phrase de passe est mise en cache et est automatiquement utilisée pour déchiffrer tous les volumes ayant une phrase de passe identique).
Erreur de mot de passe GRUB
Si l'on se trompe de mot de passe à l'invite de commande de GRUB, plutôt que de redémarrer la machine, on peut simplement taper :
cryptomount $uuid insmod normal normal
À noter qu'il faut retenir ces commandes par cœur car grub-rescue ne propose pas de complétion.
Réinstallation inopinée de GRUB : avec un système de secours
Il arrivera fatalement à un moment où un autre que les paquets de GRUB soient mis à jour et que GRUB soit automatiquement réinstallé. Si vous ne le remarquez pas, vous aurez une petite surprise au prochain redémarrage de votre machine : une invite de commandes GRUB sur fond noir. Comme expliqué en introduction, l'image par défaut de GRUB n'embarque pas le module luks2, il est donc impossible de se dépanner en tapant des commandes, même en étant un gourou du shell GRUB.
Vous devrez démarrer la machine sur un système de secours (par exemple SystemRescue, anciennement System Rescue CD), déchiffrer vos volumes et les monter, puis exécuter notre script d'installation de GRUB depuis un chroot. Quelque chose comme ceci :
cryptsetup open /dev/nvme0n1p2 boot_crypt cryptsetup open /dev/nvme0n1p3 root_crypt mount /dev/mapper/rootvg-rootlv /mnt for i in dev proc sys ; do mount -o bind /$i /mnt/$i ; done chroot /mnt mount -a /boot/grub/grub-install.sh umount -a exit umount /mnt/* umount /mnt shutdown -r now
Réinstallation inopinée de GRUB : en autonomie !
Une alternative au système de secours, c'est d'avoir une petite partition chiffrée avec LUKS1, qui contient de quoi vous dépanner.
Préparation
Si vous n'avez pas prévu le coup, vous pourrez peut-être redimensionner votre dernière partition pour vous faire de la place à la fin du disque (attention à faire les choses dans le bon ordre s'il s'agit de votre partition LVM chiffrée comme chez moi, ce n'est pas parce que je ne prends pas la peine de vous expliquer que je pourrai être tenu responsable de la perte de vos données !) ; quelques mégaoctets suffiront (/boot/grub pèse 12 Mo chez moi).
Dans l'espace libéré, créez une partition chiffrée formatée en ext2 (inspirez-vous du chapitre #Chiffrement de /boot). Vous pouvez utiliser la phrase de passe de votre choix, elle peut être différente de celle de vos volumes principaux. Montez le système de fichier et copiez-y /boot/grub.
Dans le feu de l'action
Voilà, vous avez encore passé une mise à jour sans remarquer que les paquets grub* en faisaient parti, et vous vous retrouvez devant l'invite GRUB, froide, austère, et en QWERTY. Remarquez, pas si austère que cela : ici on est dans un vrai GRUB (et pas dans un grub-rescue comme quand on se trompe de mot de passe), on a donc accès à la complétion via la touche tabulation, très pratique pour compléter les commandes, et surtout les noms de périphériques et de fichiers.
Déchiffrez d'abord votre partition de secours ; chez moi, elle est sur le disque secondaire SATA, détecté par GRUB en tant que hd0, sur la première partition, et le disque est partitionné avec GPT (pro tip : tabulez après avoir tapé « cryptomount (hd0,
» pour voir la liste des partitions, cela peut aider à s'y retrouver). Cela donne donc :
cryptomount (hd0,gpt1)
Une fois la partition déchiffrée (si vous avez passé l'épreuve de taper votre mot de passe en QWERTY), elle est accessible via le périphérique crypto0, et l'on peut aller chercher le graal, c'est-à-dire le module luks2 :
set prefix=(crypto0)/grub insmod luks2
On peut à présent déchiffrer notre vrai volume de démarrage en LUKS2 ; chez moi, il est sur le disque principal NVME, détecté par GRUB en tant que hd1, sur la deuxième partition :
cryptomount (hd1,gpt2)
Ce deuxième volume (dé)chiffré sera accessible via le périphérique crypto1 ; il suffit à présent de charger le fichier de configuration pour se retrouver dans le menu GRUB habituel :
configfile (crypto1)/grub/grub.cfg
On peut maintenant démarrer le système normalement. La bonne nouvelle c'est que pour taper le « deuxième » mot de passe, vous aurez votre carte de clavier habituelle, puisque vous serez au niveau de l'initrd, donc déjà un peu chez vous.