URL:     https://linuxfr.org/users/trim/journaux/installation-personnalisee-de-debian-avec-luks-v2-volumes-btrfs-systemd-boot-et-secure-boot
Title:   Installation personnalisée de Debian avec LUKS v2, volumes Btrfs, systemd-boot et Secure Boot
Authors: Adrien Dorsaz
Date:    2024-09-18T21:39:20+02:00
License: CC By-SA
Tags:    chiffrement, debian, btrfs, secure_boot, luks, argon2id et systemd-boot
Score:   34


Cher journal,

Je me suis amusé en début d’été à réinstaller ma machine avec Debian Bookworm et j’ai pris quelques notes pour en faire un article sur mon blog. Nous voilà déjà à la fin de l’été et j’ai [publié l’article](https://adorsaz.ch/articles/installation-personnalis%C3%A9e-de-debian.html) que je vous ai retranscrit ici directement ci-dessous.

Finalement, cet article que j’avais imaginé _petit_ a pris bien plus de mon temps que prévu :)

# Installation personnalisée de Debian avec disque chiffré par LUKS v2, volumes Btrfs, systemd-boot et Secure Boot

## Introduction

Dans cet article, je vais vous présenter comment j’ai fait pour installer _Debian Bookworm_ de manière chiffrée avec les outils de sécurité les plus récents.

Pour chiffrer une installation, l’installateur de _Debian_ crée actuellement un conteneur [LUKS](https://fr.wikipedia.org/wiki/LUKS) v1 et installe l’outil [GRUB 2](https://www.gnu.org/software/grub/) pour démarrer le système.

L’installateur ne peut ni passer à la version 2 de LUKS ni utiliser l’algorithme de dérivation de clé [_Argon2id_](https://fr.wikipedia.org/wiki/Argon2), car il doit d’abord attendre que _GRUB 2_ réimplémente lui-même ces deux spécifications.

L’intérêt d’_Argon2id_ est qu’il protège la clé de déchiffrement du disque de manière à résister à la puissance des cartes graphiques. Quant à la version 2 de LUKS, son intérêt est qu’il permet justement d’utiliser _Argon2id_.

Heureusement, _Debian_ peut être installée manuellement (sans utiliser d’installateur) depuis un autre _Linux_ grâce au système [debootstrap](https://wiki.debian.org/fr/Debootstrap). Ainsi, à la manière de la distribution _Arch Linux_, l’installation peut être totalement personnalisée.

Pour pouvoir utiliser LUKS v2 et _Argon2id_, j’ai choisi d’utiliser [systemd-boot](https://www.freedesktop.org/software/systemd/man/latest/systemd-boot.html) pour démarrer mon système à la place du traditionnel _GRUB 2_.

_systemd-boot_ ne doit ni implémenter LUKS v2, ni _Argon2id_, parce qu’il se contente d’exécuter le noyau _Linux_ au format _initramfs_[^1]. Le déchiffrement du disque sera géré directement par ce _Linux_ qui a déjà son implémentation de tous les algorithmes nécessaires.[^2]

Pour que ce système fonctionne, il faut installer _systemd-boot_ et les noyaux _Linux_ directement dans la partition système ESP (sans chiffrement). Cette partition est celle utilisée par le firmware de l’ordinateur pour démarrer le système d’exploitation de votre choix. Elle est définie par le standard [UEFI](https://fr.wikipedia.org/wiki/UEFI) (standard qui définit une interface entre le firmware de la machine et le système d’exploitation).

La partition ESP ne peut pas être chiffrée, car elle doit être lisible par le firmware de la machine. D’un côté, c’est un avantage, car c’est grâce à ça que _systemd-boot_ peut démarrer le noyau _Linux_ facilement, mais d’un autre côté, c’est un désavantage, car il n’est plus possible de garantir que le contenu de la partition n’a pas été altéré par un logiciel ou un acteur malveillant.

Bien qu’il ne soit pas possible de chiffrer le contenu de la partition ESP, il est possible de demander au système d’exploitation de [signer numériquement le contenu](https://fr.wikipedia.org/wiki/Signature_num%C3%A9rique) qu’il installe dans cette partition. Ensuite, il faut que le système d’exploitation partage avec le firmware sa clé publique pour que le firmware puisse valider l’authenticité du contenu. Si le firmware détecte que le contenu de la partition ESP a été altéré (la signature est invalide), il doit refuser de démarrer le système d’exploitation.

Le standard UEFI a déjà pensé à ce système de sécurisation du contenu de la partition ESP et l’a nommé [_Secure Boot_](https://wiki.debian.org/SecureBoot#What_is_UEFI_Secure_Boot.3F). Si le démarreur a été altéré, le seul moyen de démarrer le système d’exploitation est de désactiver _Secure Boot_ dans les paramétrages de la machine. Il est donc important de **définir un mot de passe d’accès aux paramétrages de l’UEFI** lors de l’installation de la machine (si non, toute personne qui a accès à la machine peut installer un logiciel malveillant dans la partition ESP et désactiver _Secure Boot_).[^3]

En résumer, dans cet article je vais vous montrer comment j’ai installé _Debian Bookworm_ avec tous ces outils (LUKS v2, _Argon2id_, _systemd-boot_, _Secure Boot_). Les étapes que j’ai suivies sont dans l’ordre :

1.  démarrer une [image autonome (live)](https://www.debian.org/CD/live/ "Image d’installation autonome") de Debian (avec _Secure Boot_ désactivé)
2.  préparer le disque et les partitions
3.  installer le système de base avec _debootstrap_
4.  entrer dans ce système de base
5.  installer _systemd-boot_ comme système de démarrage
6.  configurer et activer _Secure Boot_

## Démarrer une image autonome de _Debian_ avec _Secure Boot_ désactivé

Depuis la page [Obtenir Debian](https://www.debian.org/distrib/), je télécharge l’**« image autonome GNOME »**. Ensuite, je [vérifie l’authenticité de l’image téléchargée](https://www.debian.org/CD/verify) et je peux l’installer sur une clé _USB_ avec l’outil _Disques_ de _GNOME_.

Maintenant que la clé est prête, je peux la brancher à la machine. Je démarre l’ordinateur en entrant d’abord dans son outil de paramétrage du _UEFI_. Il faut y faire les changements suivant :

- autoriser le démarrage sur clé _USB_
- configurer un mot de passe pour accéder à cette interface de configuration
- modifier la configuration de _Secure Boot_ pour le passer en « *Setup Mode* »
  Dans l’UEFI de ma machine, cette option s’appelle « *Secure Boot ⭢ Reset to Setup Mode* » et sa documentation explique bien que « la _Platform Key_ sera supprimée, _Secure Boot_ sera désactivé et passé en *Setup Mode* ».

Enfin, je redémarre la machine et je lui fais démarrer _Debian_ depuis la clé _USB_.

## Préparer les partitions sur le disque

### Organisation du disque dur

Avec le système de démarrage UEFI et les partitions au format [_Btrfs_](https://fr.wikipedia.org/wiki/Btrfs), il est devenu possible de faire une organisation plutôt simple du disque dur.

En effet, UEFI nécessite d’utiliser une table de partition de type [GPT](https://fr.wikipedia.org/wiki/GUID_Partition_Table) ce qui implique plus de souplesse dans la gestion du disque :

- l’espace qui contient les démarreurs de système d’exploitation est lui-même une partition dont la taille peut être choisie
- selon les implémentations, il est possible de créer beaucoup plus de partitions (le système précédent, MBR, était limité à 4 partitions seulement)
- les identifiants uniques GUID sont utilisés pour désigner les partitions de manière univoque

_Btrfs_ quant à lui permet de créer des sous-volumes logiques qui permettent d’organiser les données dans le disque sans avoir besoin de créer des partitions avec des tailles arbitraires difficiles à changer par la suite.

J’ai décidé de ne pas avoir de partition de type _swap_, parce que je ne l’utiliserai pas le système d’hibernation de la machine. Je ferais plus tard un fichier de type _swap_ pour les cas où la mémoire vive ne suffit vraiment plus pendant le fonctionnement.

Le schéma de mon disque est finalement le suivant :

```textual-graph
┌       ┬                                   ┬           ┐
│  ESP  │              Debian               │  Windows  │
│       │  Btrfs dans un conteneur LUKS v2  │           │
└       ┴                                   ┴           ┘
```

La partition _ESP_ contiendra l’outil _systemd-boot_, les images _Linux_ au format _initramfs_ et le démarreur de Windows.

La partie _Debian_ est une partition _Btrfs_ installée dans un conteneur de chiffrement LUKS v2.

La partie _Windows_ sera un espace libre qui sera rempli automatiquement par l’installateur de _Windows_ (au final 2 partitions).

### Créer la partition ESP pour démarrer le système

L’image autonome _GNOME_ de _Debian Bookworm_ est fournie avec le logiciel _Disques_, je l’utilise pour préparer plus facilement la machine avec une interface graphique.

D’abord, je sélectionne le disque de ma machine et je lui crée une nouvelle table de partition de type GPT (**attention, cette opération écrase toutes les données du disque : si des données existent déjà, faites une sauvegarde avant !**).

Pour la première partition, je crée la partition ESP avec le type « *Compatible avec tous les systèmes et périphériques (**FAT**)* » et assez large (10 Gio), parce que _systemd-boot_ nécessite d’installer les images _initramfs_ dans cette partition. Par exemple, maintenant, je n’ai qu’un seul noyau installé et il y a déjà une centaine de Mio d’utilisé (principalement 75 Mio pour un noyau et 27 Mio pour Windows).

Après la création de cette partition, il faut la sélectionner dans _Disques_, cliquer sur la roue dentée en dessous et choisir le menu contextuel « *Edit Partition* ». Dans le dialogue qui s’ouvre, il faut alors changer le « *Type* » et choisir la valeur « *Système EFI* » pour que le _firmware_ UEFI sache que cette partition contient les démarreurs des systèmes d’exploitations.

### Créer la partition chiffrée pour Debian

Pour créer la partition de _Debian_ avec _Disques_, il faut choisir la taille désirée, le type « *Autre* » et l’option « *Pas de système de fichiers* » sur la seconde partie de l’écran de configuration.

Pour le choix de la taille de la partition, j’ai personnellement laissé environ 70 Gio à la fin du disque pour pouvoir installer _Windows_ plus tard.

Je sais que _Disques_ permet aussi de créer facilement une partition Btrfs chiffrée par un conteneur LUKS, mais il ne sait créer que des conteneurs LUKS v1 et non pas **v2**.

Pour créer le conteneur LUKS v2, la commande `sudo cryptsetup luksFormat /dev/sda2` de _Debian Bookworm_ suit déjà par défaut les recommandations actuelles (l’identifiant _/dev/sda2_ est à adapter avec la valeur affichée par _Disques_).

Ensuite, il faut monter le conteneur avec la commande `sudo cryptsetup open /dev/disk/by-uuid/${UUID} luks-debian` ce qui prépare le périphérique _/dev/mapper/luks-debian_.

Pour retrouver facilement le bon identifiant _UUID_ à utiliser, j’utilise la commande `lsblk -f` ou le logiciel _Disques_.

Il reste à créer la partition _Btrfs_ sur ce périphérique avec `sudo mkfs.btrfs /dev/mapper/luks-debian` et la monter sur _/mnt_ avec `sudo mount /dev/mapper/luks-debian /mnt`.

### Créer les sous volumes Btrfs

Pour les sous-volumes, je suis les besoins de l’outil de sauvegarde [Timeshift](https://github.com/linuxmint/timeshift) qui utilise `@` pour la partition racine et `@home` pour la partition de données utilisateurs.

```bash
$ sudo btrfs subvol create /mnt/@
$ sudo btrfs subvol create /mnt/@home
```

### Monter les volumes et les partitions

Avant d’entrer dans le chroot, il faut remonter les partitions pour être prêt à faire l’installation concrète de Debian aux bons endroits :

```bash
$ sudo umount /mnt
$ sudo mount /dev/mapper/luks-debian -o compress=zstd,subvol=@ /mnt
$ sudo mkdir -p /mnt/home
$ sudo mount /dev/mapper/luks-debian -o compress=zstd,subvol=@home /mnt/home
$ sudo mkdir -p /mnt/boot/efi
$ sudo mount /dev/disks/by-uuid/${ESP_UUID} /mnt/boot/efi
```

## Installer le système de base

Pour débuter l’installation, je suis à peu près le manuel Debian pour [Installer Debian GNU/Linux à partir d’un système Unix/Linux](https://www.debian.org/releases/stable/i386/apds03.fr.html).

Comme l’image autonome utilisée est elle-même une distribution Debian, j’installe _debootstrap_ simplement avec *apt* :

```bash
$ sudo apt update
$ sudo apt install debootstrap
```

Ensuite, je débute l’installation minimale :

```bash
$ sudo debootstrap --arch amd64 bookworm /mnt http://ftp.ch.debian.org/debian
```

Avant d’entrer dans le contexte de l’installation (_chroot_), je copie l’état actuel des points de montage qui ciblent le dossier _/mnt_ du système autonome dans le fichier _fstab_ du _chroot_ (ce fichier a été créé par _debootstrap_) :

```bash
$ grep /mnt /etc/mtab | sudo tee -a /mnt/etc/fstab
```

Pour la partie « *Créer les fichiers des périphériques* » du manuel d’installation, j’utilise la commande suivante (trouvée sur le wiki de Debian: [GRUB EFI Reinstall](https://wiki.debian.org/GrubEFIReinstall)) pour partager les montages de l’image autonome avec le conteneur *chroot* :

```bash
$ for i in /dev /dev/pts /proc /sys /sys/firmware/efi/efivars /run; do sudo mount -o bind $i /mnt$i; done
```

Maintenant, je peux entrer concrètement dans le système installé avec la commande `chroot` :

```bash
$ LANG=C.UTF-8 sudo chroot /mnt /bin/bash
```

D’abord, je modifie le fichier _/etc/fstab_ avec les entrées nécessaires pour monter la partition ESP et les sous-volumes _Btrfs_.

Comme j’ai prérempli le fichier avec les lignes du système autonome au-dessus, il faut remplacer les cibles de montages _/mnt_, _/mnt/home_ et _/mnt/boot/efi_ par _/_, _/home_ et _/boot/efi_ respectivement.

Par exemple, sur mon ordinateur le fichier contient :

```bash
$ cat /etc/fstab
# /etc/fstab: static file system information.
#
# file system    mount point   type    options                  dump pass
/dev/nvme0n1p1 /boot/efi vfat rw 0 0
/dev/mapper/luks-debian / btrfs rw,relatime,compress=zstd:3,ssd,space_cache=v2,subvolid=256,subvol=/@ 0 0
/dev/mapper/luks-debian /home btrfs rw,relatime,compress=zstd:3,ssd,space_cache=v2,subvolid=257,subvol=/@home 0 0
```

Pour confirmer que le fichier est correct, le plus simple est de forcer un montage de toutes les partitions :

```bash
$ mount -a
```

Comme le manuel d’installation le propose, je configure le fuseau horaire avec :

```bash
$ dpkg-reconfigure tzdata
```

Ensuite, j’ajoute un serveur DNS de [Quad9](https://www.quad9.net/fr/) temporairement pour continuer l’installation avec un réseau fonctionnel :

```bash
$ echo "nameserver 9.9.9.10" > /etc/resolv.conf
```

Je profite aussi de donner un nom à mon ordinateur :

```bash
$ echo togepi > /etc/hostname
```

Je modifie les listes de source des paquets _Debian_ pour ajouter le dépôt _non-free-firmware_ (mon matériel a besoin de _firmwares_ privateurs pour démarrer correctement) :

```bash
$ editor /etc/apt/sources.list
```

et ajouter _non-free-firmware_ à côté de _main_.

Comme proposé par le manuel, j’installe les locales pour avoir la locale _fr_CH.UTF8_ disponible sur ma machine :

```bash
$ apt update
$ apt install locales
$ dpkg-reconfigure locales
```

Enfin, j’installe comme conseillé _console-setup_ et l’image du noyau *Linux* :

```bash
$ sudo apt install console-setup linux-image-amd64
```

## Préparation des fichiers de configuration avant d’installer _systemd-boot_

Au lieu d’installer _GRUB_ comme dans le manuel d’installation de _Debian_, j’installe _systemd-boot_ en suivant les conseils du blog [Md at debian.org](https://blog.bofh.it/debian/id_465).

Je commence par créer les fichiers de configuration avant d’installer _systemd-boot_ pour que, au moment de son installation, tout se configure directement comme nécessaire.

Le premier fichier à configurer est _/etc/kernel/cmdline_ qui contiendra les options de démarrage de _Linux_. Ces options expliquent à l’image _Linux_ _initramfs_ comment démarrer le noyau _Linux_ complet.

Mon fichier contient une ligne comme celle-ci :

> cryptdevice=UUID=${UUID}:luks-debian root=/dev/mapper/luks-debian rootflags=subvol=@ quiet splash

Quelques explications :

- `cryptdevice=UUID=${UUID}:luks-debian`
  Cette option permet de faire le lien entre la partition désignée par la valeur `${UUID}` (à remplacer par l’identifiant du conteneur LUKS) et son alias `luks-debian` (sa valeur peut être différente, mais elle doit se retrouver dans les fichiers _/etc/fstab_ et _/etc/crypttab_). Cette option sera utilisée par le module _cryptsetup_ pour demander la phrase de passe pour déchiffrer le système (selon les détails retrouvés dans le fichier _/etc/crypttab_, voir plus bas)
- `root=/dev/mapper/luks-debian`
  Cette option annonce où se situe la source de la racine du système de fichier « */* » pour démarrer le noyau _Linux_ complet (avec l’utilisation de l’alias de l’option précédente).
- `rootflags=subvol=@`
  Cette option précise d’utiliser le volume _Btrfs_ `@` comme point de montage pour la racine du système de fichier « */* ».
- `quiet`
  Cette option permet de réduire la quantité de messages affichés au démarrage. Dans un premier temps, il vaut mieux l’omettre pour pouvoir voir les messages d’erreur. Elle peut être ajoutée dans un second temps, quand le démarrage aura réussi une première fois.
- `splash`
  Cette option permet de remplacer le texte de démarrage par une animation graphique proposée par la distribution (via le logiciel [_Plymouth_](https://www.freedesktop.org/wiki/Software/Plymouth/)) à la place des messages de démarrage. Pour les mêmes raisons que l’option _quiet_, il vaut mieux l’activer dans un second temps.

Le second fichier à configurer est _/etc/crypttab_ pour que l’image _initramfs_ et le module _cryptsetup_ sachent comment déchiffrer le conteneur LUKS. Par exemple, le contenu de mon fichier est :

```
# <target name> <source device> <key file> <options>

luks-debian UUID=${UUID} none cipher=aes-xts-plain64,size=512,hash=sha256
```

Il faut de nouveau remplacer _${UUID}_ par l’identifiant du conteneur LUKS et _luks-debian_ par l’alias choisi.

Ce fichier répète le lien entre la partition et l’alias, mais il précise surtout qu’il n’y a pas de fichiers contenant une clé de déchiffrement et quels sont les algorithmes à utiliser pour pouvoir déchiffrer les données.

Pour retrouver les bonnes options, j’ai utilisé la commande _cryptsetup_ pour afficher les informations du conteneur LUKS (il faut installer le paquet _cryptsetup_ d’abord si vous exécutez cette commande dans le _chroot_) :

```bash
$ cryptsetup luksDump /dev/disk/by-uuid/${UUID}
```

## Installation des outils personnels et de ceux nécessaires pour l’image _initramfs_

L’environnement _Debian_ dans le _chroot_ est bien configuré, mais il est encore très minimal. Je lui ajoute les outils _standards_ de *Debian* :

```bash
$ tasksel install standard
```

Je profite pour installer un environnement de bureaux (personnellement j’apprécie _GNOME_) :

```bash
$ tasksel install gnome-desktop
```

Quelques outils spécifiques au matériel de ma machine :

```bash
$ tasksel install laptop # mon ordinateur est un portable
$ apt install amd64-microcode firmware-amd-graphics # mon ordinateur utilise du matériel AMD
$ apt install firmware-misc-nonfree # mon ordinateur a une carte wifi MediaTek
```

Enfin, il est **important** d’installer dans le _chroot_ et dans l’image _initramfs_ le module _cryptsetup_ qui permet de gérer les conteneurs LUKS. Sans cet outil, il est impossible de déchiffrer les partitions.

```bash
$ apt install cryptsetup cryptsetup-initramfs
```

Avec cette commande _Debian_ reconstruit l’image _initramfs_ avec tous les outils nécessaires pour déverrouiller le disque au démarrage. Il ne reste donc plus qu’à installer le démarreur _systemd-boot_.

## Installation de _systemd-boot_

Depuis la version 12 (alias _Bookworm_) de _Debian_, il suffit d’exécuter :

```bash
$ apt install systemd-boot
```

Ensuite, la configuration de cet outil se fait directement dans la partition _ESP_ en modifiant le fichier _/boot/efi/loader/loader.conf_.

## Configuration de _Secure Boot_

Pour configurer _Secure Boot_ j’ai également suivi les conseils du [même article](https://blog.bofh.it/debian/id_465) du blog _Md at debian.org_.

L’utilisation de l’outil _sbctl_ permet de configurer _Secure Boot_ sans installer _GRUB_, mais, comme cet outil ne se trouve pour l’instant pas dans _Debian_, il faut le télécharger et l’installer à la main.

Je documente ici comment je l’ai fait, mais si c’était à refaire, je pense que j’essaierais d’installer quand même l’outil _shim_ prévu par _Debian_ même s’il installe _GRUB_ en trop. Je ne sais pas si ça peut fonctionner, c’est à essayer.

_sbctl_ est un outil crée en _go_, il est donc possible de récupérer le binaire pré-compilé et distribué par le projet. J’utilise une version amd64 de _Linux_, j’ai donc procédé ainsi pour l’ajouter à mon système[^4] :

```bash
$ sudo apt install curl # je n’avais pas encore installé curl
$ curl -L -O 'https://github.com/Foxboron/sbctl/releases/download/0.14/sbctl-0.14-linux-amd64.tar.gz'
$ tar xf sbctl-0.14-linux-amd64.tar.gz
$ sudo mv sbctl/sbctl /usr/local/sbin/
$ sudo sbctl status
Installed:      ✘ sbctl is not installed
Setup Mode: ✘ Enabled
Secure Boot:    ✘ Disabled
Vendor Keys:    none
```

La sortie de la dernière commande explique que _Secure Boot_ est bien en mode _configuration_ (_Setup Mode: Enabled_) et qu’il est désactivé. Si ce n’est pas le cas, il faut redémarrer dans l’_UEFI_ et activer la gestion des clés.

Je crée ma clé personnelle (_propriétaire_) pour la machine, elle sera à ajouter comme clé de confiance dans l’*UEFI* :

```bash
$ sbctl create-keys
Created Owner UUID e15b9fe0-6bdd-421d-8f4f-f582257a8f14
Creating secure boot keys...✔
Secure boot keys created!
$ sbctl status
Installed:      ✔ sbctl is installed
Owner GUID: e15b9fe0-6bdd-421d-8f4f-f582257a8f14
Setup Mode: ✘ Enabled
Secure Boot:    ✘ Disabled
Vendor Keys:    none
```

Pour ajouter cette nouvelle clé dans l’_UEFI_, j’ai choisi d’utiliser l’option _--microsoft_ pour ajouter aussi les clés de _Microsoft_, car je vais installer _Windows_ également sur le disque :

```bash
$ sbctl enroll-keys --microsoft
Enrolling keys to EFI variables...
With vendor keys from microsoft...✔
Enrolled keys to the EFI variables!
root@debian:/# sbctl status
Installed:      ✔ sbctl is installed
Owner GUID: e15b9fe0-6bdd-421d-8f4f-f582257a8f14
Setup Mode: ✔ Disabled
Secure Boot:    ✘ Disabled
Vendor Keys:    microsoft
```

La configuration des clés est terminée dans l’_UEFI_. Il faut maintenant utiliser les clés pour signer les fichiers de démarrage actuellement installés :

```bash
$ for file in /boot/efi/*/*/linux /boot/efi/EFI/*/*.efi; do sbctl sign -s $file; done
✔ Signed /boot/efi/9ee8db2eeacf4118a2d7f194bfbc3e43/6.1.0-25-amd64/linux
✔ Signed /boot/efi/EFI/systemd/systemd-bootx64.efi
```

Pour le faire à chaque mise à jour de noyau, il faut ajouter le script _[91-sbctl.install](https://raw.githubusercontent.com/Foxboron/sbctl/0.14/contrib/kernel-install/91-sbctl.install) (il faut faire attention à récupérer le même **numéro de version** que le binaire sbctl)_ dans le dossier _/etc/kernel/install.d_ et le rendre exécutable (`chmod +x 91-sbctl.install`).

J’ai eu besoin de personnaliser ce script pour utiliser le chemin complet de l’installation du binaire _/usr/local/sbin/sbctl_ à la place de juste _sbctl_ pour m’assurer que le script fonctionne avec tous les environnements utilisateurs (notamment _\_apt_). Pour faire ça, j’ai ajouté en début de script une ligne qui crée l’alias nécessaire :

```bash
#!/bin/sh
#  This file is part of sbctl.

# Adrien: set full path for sbctl so it works within apt user environment
alias sbctl=/usr/local/sbin/sbctl

# reste du script
```

Enfin pour s’assurer que le script est bien exécuté lors de la mise à jour du noyau, je force la mise à jour des images *initramfs* :

```bash
$ sudo update-initramfs -k all -u
update-initramfs: Generating /boot/initrd.img-6.1.0-25-amd64
Updating kernel version 6.1.0-25-amd64 in systemd-boot...
sbctl: Signing kernel /boot/efi/9ee8db2eeacf4118a2d7f194bfbc3e43/6.1.0-25-amd64/linux
$ sudo sbctl list-files
/boot/efi/9ee8db2eeacf4118a2d7f194bfbc3e43/6.1.0-25-amd64/linux
Signed:     ✔ Signed

/boot/efi/EFI/systemd/systemd-bootx64.efi
Signed:     ✔ Signed
```

Quand des mises à jour de _systemd-boot_ sont proposées par _Debian_, il faut également signer le fichier que le paquet installe dans _/boot/efi_.

Je ne sais pas comment faire pour déclencher automatiquement une ligne de commande lors de la mise à jour d’un paquet. Par contre, avec _systemd_, il est assez facile de demander au système de surveiller les modifications sur un fichier et d’exécuter un service à ce moment-là.

J’ai créé le service _/etc/systemd/system/systemd-boot-sign.service_ avec la commande pour signer le binaire de *systemd-boot* :

```ini
[Unit]
Description=Sign the systemd-boot binary in ESP partition

[Service]
ExecStart=/usr/local/sbin/sbctl sign -s /boot/efi/EFI/systemd/systemd-bootx64.efi
```

Pour déclencher ce service automatiquement, j’ai créé l’unité _/etc/systemd/system/systemd-boot-sign.path_ avec :

```ini
[Unit]
Description=On update of systemd-boot binary in ESP partition, sign it

[Path]
PathModified=/boot/efi/EFI/systemd/systemd-bootx64.efi

[Install]
WantedBy=default.target
```

Enfin, il faut demander à _systemd_ d’activer et démarrer cette dernière unité :

```bash
$ sudo systemctl daemon-reload
$ sudo systemctl enable --now systemd-boot-sign.path
```

## Conclusion

La démarche était longue, mais le résultat est vraiment bien: ma machine démarre de manière sécurisée une _Debian_ stable installée par mes soins avec _Secure Boot_ et une interface graphique pour entrer la phrase de déchiffrement.

J’ai écrit cet article depuis l’historique des commandes entrées dans mon terminal pendant l’installation de ma machine. Il est probable que j’ai oublié certains détails, mais l’essentiel devrait être là.

[^1]: Le noyau _Linux_ au format [« *initramfs* »](https://fr.linuxfromscratch.org/view/blfs-12.1-fr/postlfs/initramfs.html) (ou « *image initramfs* ») contient une petite copie du noyau Linux à charger en mémoire vive pour démarrer le noyau complet et la distribution.

[^2]: Le fonctionnement de _GRUB_ est bien plus complexe, car il n’installe pas les noyaux _Linux_ dans la partition de démarrage. Ceci est dû à sa compatibilité avec les anciennes tables de partition de type _bios_ qui ne disposait que d’un espace très réduit pour les démarreurs (l’espace MBR en début de disque).

[^3]:
    Il faut bien faire attention que l’application de _Secure Boot_ est seulement de permettre au firmware de n’exécuter que les systèmes d’exploitations choisis par le propriétaire de la machine. Par exemple, si quelqu’un s’empare du disque dur et le démarre sur une autre machine, _Linux_ va démarrer sans remarquer qu’il n’est plus dans la machine prévue et il va permettre à l’attaquant d’essayer de déchiffrer le disque dur. Dans ce cas, _Secure Boot_ est inutile, car il ne sécurise que le démarrage que pour une machine.
    Si l’on voulait que _Linux_ refuse de démarrer quand le matériel change, il faudrait appliquer un système de vérification du démarrage : chaque composant logiciel doit vérifier que l’état du système est celui attendu et mettre à jour l’état actuel pour indiquer qu’il s’est bien exécuté. Le principe est de créer une chaîne de confiance qui nécessite une puce _TPM_ pour sauver l’état de la chaîne entre chaque démarrage.
    C’est une présentation sommaire de ce que j’ai compris en lisant l’article _[Roots of Trust are difficult](https://mjg59.dreamwidth.org/66907.html)_ de _Matthew Garrett_ qui présente le système de vérification de démarrage prévu par le _Trusted Computing Group_ et pointe les difficultés pour le mettre en place.

[^4]: J’ai fait cette installation en juillet 2024, la version la plus récente de _sbctl_ était celle documentée dans cet article (0.14). Pendant les relectures, j’ai essayé d’utiliser la version 0.15.4 pour refaire les procédures dans une machine virtuelle, mais [ce bug](https://github.com/Foxboron/sbctl/issues/373) m’a empêché d’utiliser la version _0.15.4_ de _sbctl_, j’ai donc préféré garder les références à la version 0.14 pour cet article.

