Les images de ressources sont des fichiers d’images disque montés en lecture seule pour créer le système de fichiers de citadel. Le premier bloc (4096 octets) du fichier image contient un en-tête, et immédiatement après l’en-tête se trouve le contenu brut de l’image disque.
L’en-tête contient des informations sur l’image, y compris les paramètres de configuration de dm-verity destinés à garantir l’immuabilité de l’image. L’en-tête contient également une signature par clé publique portant sur les informations de l’image, afin que l’authenticité des informations de l’en-tête puisse être vérifiée.
Le système de fichiers racine de citadel est également distribué sous forme d’image de ressources, et cette image sera installée sur une partition de disque pour le fonctionnement normal.
Les images de ressources autres que le système de fichiers racine sont montées en créant des périphériques loop sur le fichier image. Avant de monter l’image, dm-verity est configuré sur le périphérique loop ou sur la partition rootfs.
Types d’images de ressources
Les types d’images suivants sont actuellement définis pour être utilisés dans Citadel :
1) Système de fichiers racine de base (« rootfs »)
L’image rootfs de base est le seul type d’images qui soit installé sur une partition. Elle est montée à la racine du système de fichiers de Citadel. Lorsqu’une image est installée sur une partition, le bloc d’en-tête de 4906 octets est stocké dans le dernier bloc (8 secteurs) de la partition.
Citadel utilise deux partitions (A et B) pour le système de fichiers racine. Cela permet de mettre à jour une partition pendant que l’autre est utilisée. Le système peut ensuite être redémarré sur la partition rootfs mise à jour. Si le système échoue au démarrage après la mise à jour, il reviendra à l’utilisation de la partition fonctionnelle.
2) Image du noyau (« kernel »)
Les modules du noyau en cours d’exécution sont stockés dans une image de ressources afin que le système de fichiers racine soit indépendant du noyau en cours d’exécution.
Pendant le démarrage, cette image est montée, ainsi que les modules du noyau, et un montage bind est créé par-dessus /usr/lib/modules sur le système de fichiers racine de Citadel.
3) Image de ressources supplémentaire (« extra »)
Ce type d’image contient des répertoires de fichiers supplémentaires qui sont montés au démarrage sur le système de fichiers racine de Citadel. Il contient des fichiers tels que des fichiers de micrologiciels et des icônes de bureau, qui occupent un espace considérable mais n’ont pas besoin d’être mis à jour fréquemment.
En plaçant ces fichiers dans une image distincte, la taille de l’image du système de fichiers racine est réduite. L’image rootfs, mise à jour plus fréquemment, est ainsi plus petite.
4) Image du système de fichiers du realm (« realmfs »)
Ce type d’image contient l’ensemble du système de fichiers racine nécessaire à l’exécution d’un conteneur ou d’une machine virtuelle de realm. Contrairement aux autres types d’images de ressources, ces images peuvent être modifiées puis signées avec des clés contrôlées par l’utilisateur. Cela permet les mises à jour et l’installation de logiciels tout en préservant la propriété de lecture seule.
Organisation de l’image
Chaque fichier d’image de ressources réserve un bloc initial de 4096 octets où est stocké un en-tête. Il s’agit de la longueur maximale de l’en-tête, qui est généralement bien inférieure à cette taille.
À la suite de l’en-tête se trouve une image brute de système de fichiers disque, qui peut éventuellement être compressée avec l’algorithme de compression xz. Le système de fichiers de l’image disque est ext4, mais il s’agit d’un détail d’implémentation susceptible de changer à l’avenir. Un indicateur d’en-tête (FLAG_DATA_COMPRESSED) indique si une image est compressée ; dans ce cas, l’image doit être décompressée avant d’être utilisée. Les mises à jour d’images sont distribuées sous forme compressée et sont décompressées une seule fois lors de l’installation.
Lorsque dm-verity est utilisé, un arbre de hachage doit être généré pour l’image. Lors de l’installation d’une image, elle est d’abord décompressée, puis les données de hachage dm-verity sont générées. Ces données de hachage sont stockées dans le fichier image immédiatement après les données de l’image, et l’indicateur FLAG_HASH_TREE est défini pour signaler la présence de ces données.
Fichier image :
[ Header ][ Ext4 Disk Image ][ dm-verity hash data ]
Partition :
[ Ext4 Disk Image ][ dm-verity hash data ][ unused space ][ Header ]
En-tête de l’image
L’en-tête de l’image contient les champs suivants.
| Champ | Taille | Contenu |
|---|---|---|
| MAGIC | 4 octets | (‘S’, ‘G’, ‘O’, ‘S’) |
| status | 1 octet | Utilisé pour les images installées sur une partition |
| flags | 1 octet | Diverses valeurs d’indicateurs |
| metainfo-len | 2 octets | Longueur sur 16 bits en gros-boutien |
| metainfo | (metainfo-len) octets | Document TOML contenant des paires clé-valeur |
| signature | 64 octets | Signature ed25519 portant sur le champ metainfo |
Champs de l’en-tête
MAGIC
Les 4 premiers octets sont toujours définis aux octets ASCII « SGOS » afin qu’un fichier image valide puisse être facilement identifié.
status
Le champ status n’est utilisé que sur l’image rootfs de base installée sur une partition. Il doit être défini à 0 pour toutes les autres images. Ce champ sert à décider de la partition dont on doit tenter le démarrage.
La valeur de status est stockée dans le quartet de poids faible (4 bits) de ce champ, et le quartet de poids fort est réservé au comptage des tentatives de démarrage dans l’état STATUS_TRY_BOOT.
Les valeurs de status définies sont :
| status | valeur | description |
|---|---|---|
| STATUS_INVALID | 0 | La partition ne contient pas d’image valide |
| STATUS_NEW | 1 | Partition nouvellement écrite qui n’a pas encore été démarrée |
| STATUS_TRY_BOOT | 2 | Défini lors du premier démarrage d’une partition |
| STATUS_GOOD | 3 | La partition a démarré avec succès au moins une fois |
| STATUS_FAILED | 4 | La partition a échoué au démarrage |
| STATUS_BAD_SIG | 5 | Échec de la vérification de signature sur metainfo |
| STATUS_BAD_META | 6 | Échec de l’analyse du champ metainfo |
flags
| indicateur | valeur | description |
|---|---|---|
| FLAG_PREFERRED_BOOT | 0x01 | Force le choix de démarrage sur cette partition |
| FLAG_HASH_TREE | 0x02 | L’image contient un arbre de hachage dm-verity ajouté |
| FLAG_DATA_COMPRESSED | 0x04 | L’image est compressée avec xz |
metainfo-len
Longueur en octets du champ metainfo.
La page d’en-tête ayant une taille fixe d’un bloc (4096 octets) et tous les autres champs de l’en-tête ayant des tailles fixes, la longueur maximale du champ metainfo est de 4096 - (4 + 2 + 2 + 64) = 4024 octets.
metainfo
signature
Lorsque la partition rootfs est choisie pour le montage, une tentative de vérification de la signature est effectuée avant la configuration de dm-verity. Si cette vérification échoue, le statut de la partition est changé en STATUS_BAD_SIG.
Démarrage
Pendant le démarrage de Citadel, l’initramfs met en place le système de fichiers racine de Citadel. Le système de fichiers est construit en localisant et en montant trois composants :
- Système de fichiers racine de base * Modules du noyau * Ressources supplémentaires
Le système de fichiers racine de base est stocké sur une partition, sauf dans certains modes spéciaux tels que l’installateur et le disque live. Pendant l’installation, la même image du système de fichiers racine de base est montée depuis un fichier image monté en loop. Ce même fichier sera finalement écrit sur une partition au cours de l’installation.
Les modules du noyau et les ressources supplémentaires sont stockés dans des fichiers images qui sont montés en loop pendant le démarrage.
Un type supplémentaire d’image de ressources, appelé image d’application scellée, existe pour la création de systèmes de fichiers d’images d’applications immuables.
Les images de ressources peuvent éventuellement avoir dm-verity activé lors de leur montage.