Le chiffrement en tant que concept informatique est traditionnellement associé au chiffrement de fichiers, c’est a dire au fait de passer d’un fichier en clair a un fichier chiffré dit cyphertext. Cependant, il ne se limite pas a ça, et peut aussi servir a garantir l’intégrité d’un système d’exploitation, ou bien la confidentialité d’un support de stockage, par exemple. Nous allons ici voir comment mettre en place un système de ce type sous GNU/Linux. Cet article n’a pas pour but de vous apprendre a mettre en place un système basé sur une procédure de boot sécurisée, mais plutôt d’expliquer les concepts qui entrent en jeu dans l’utilisation du sous-système du noyau Linux dm_crypt et de présenter un rapide tutoriel concernant la création d’un support chiffré sur lequel garder vos informations confidentielles (par exemple, votre clé GPG)
dm-crypt est un sous-système de device-mapper, qui est lui-même un sous-système
du noyau Linux, et s’appuie sur LUKS, un standard de chiffrement
de disques. Comme son nom l’indique, device-mapper est un système qui a pour but
de mapper des block devices. Pour être plus clair, le kernel considère
comme “block device” tout fichier spécial (en gros, les fichiers disques dans
/dev/
, les systèmes de fichiers type LVM, les RAID logiciels, et, dans le
cas qui nous intéresse, les systèmes de fichier chiffrés). Son mode de
fonctionnement est simple : a partir d’un “fichier de périphérique” (trad.
Wikipédia), il en “crée” un nouveau, virtuel, ayant des propriétés différentes.
Par exemple, un disque partitionné via LVM apparaîtra comme un seul disque dans
/dev, et device-mapper est requis pour pouvoir en voir les partitions (qui
apparaîtront donc dans /dev/mapper)
Ainsi, dans le cas qui nous intéresse ici, device-mapper prend un système de fichier chiffré, crée un périphérique virtuel non chiffré dans /dev/mapper, et déchiffre a la volée tous les accès disques a ce périphérique non chiffré en les traduisant sur le système de fichier chiffré, le tout de manière tout a fait transparente pour les applications utilisant le disque en question. Cela induit bien entendu une baisse de performance relativement significative dans le cas d’un chiffrement du système de fichier root, mais quasiment insignifiante dans le cas de chiffrement de partitions de données.
D’ailleurs, certain-e-s se demandent peut-être comment le système peut démarrer si le système de fichier root est chiffré. Dans ce cas précis, la procédure de boot doit s’appuyer sur une image initrd (l’initrd est un système de fichier minimal qui sert uniquement a initialiser le système. Les kernels de base de la plupart des distributions GNU/Linux en utilisent un dans tous les cas, pour des raisons de compatibilité) et sur une partition de boot qui elle n’est pas chiffrée. Ainsi, le bootloader de niveau 2 (grub, syslinux,…) charge en mémoire le kernel depuis la partition de boot, puis ce dernier décompresse et charge l’initrd en RAM, celui-ci a son tour lance un script permettant de charger les modules nécessaires a la suite du boot (que ce soit pour un boot sans disque root local, ou bien comme ici avec un système chiffré), puis le système de fichier “cible” est remonté sur la racine, et l’initrd est démonté est la RAM qu’il occupait est libérée, puis la procédure de boot normale reprend depuis le système de fichier maintenant monté sur la racine.
La méthode la plus évidente pour contourner le chiffrement du disque est alors
de remplacer le fichier compressé initrd dans /boot, qui n’est pas chiffrée, par
un autre modifié, copiant par exemple la phrase de passe permettant de
déchiffrer la partition cible. Plusieurs méthodes permettent de se prémunir
contre ce genre d’attaques : l’une des plus simple est de faire un checksum du
fichier initrd utilisé et reconnu comme sûr, et de vérifier lors du vrai boot
que l’initrd présente toujours le même checksum. Cela dit, cette méthode a
l’inconvénient d’intervenir après les faits, et de nécessiter au moins un accès
a un fichier initrd reconnu comme sûr.
Une autre approche consisterait a placer le système de fichier /boot sur un
périphérique dédié, protégé en écriture de façon matérielle (par exemple, une
carte SD) ou, de façon encore plus efficace, sur un périphérique chiffré et
protégé en écriture de façon matérielle. Ainsi, il n’est pas possible pour un
attaquant de modifier ce système de fichier, et l’initrd est alors toujours de
confiance. Cependant, cela a pour conséquence de rendre la mise a jour de
l’initrd et du noyau beaucoup plus difficile qu’elle ne le serait sans.
Pour en revenir aux systèmes de fichiers chiffrés, leur gestion est faite par un
programme dédié, cryptsetup
. Ce dernier était en charge de cryptoloop,
l’ancien sous-système de chiffrement du kernel Linux (déprécié depuis), et est
maintenant responsable de l’utilisation userspace de dm-crypt, qui pour sa
part est entièrement kernel-space. Cryptsetup permet ainsi le chiffrement, la
manipulation (montage/démontage/…) et la gestion de clé des systèmes de fichier
LUKS. Cryptsetup est cependant conçu pour être utilisé en tant que root, et les
utilisateurs qui veulent monter de systèmes de fichiers chiffrés devront ainsi
obligatoirement être capables de le faire en tant que root.
Voyons comment il faudrait procéder pour créer une image disque chiffrée de 1Go :
Tout d’abord, il nous faut créer le fichier qui contiendra l’image. Pour cela,
dans une situation réelle ou l’on cherche a chiffrer un disque, il convient
d’utiliser /dev/urandom comme source, pour éviter la détection du système de
fichier chiffré sur le disque.
Ici, par exemple, nous allons faire :
dd bs=1000 count=1000000 if=/dev/urandom of=image.img
Maintenant que notre image est créée, nous pouvons la chiffrer :
sudo cryptsetup luksFormat image.img
cryptsetup
va alors nous demander si nous sommes absolument surs de vouloir
formater ce disque (nous allons donc valider en tapant YES), puis une
passphrase. Il convient ici de choisir une passphrase particulièrement sûre,
puisque toute personne ayant accès a la passphrase aura aussi accès au disque et
donc a vos secrets.
Une fois cela fait, nous allons mapper cette image :
sudo cryptsetup luksOpen image.img crypto
cryptsetup
nous redemande la passphrase, charge pendant quelques secondes,
puis nous redonne le prompt. Que s’est-il passé? En cherchant un peu, nous
voyons qu’il n’y a pas de nouveau disque dans /dev. C’est tout a fait normal. En
effet, cryptsetup (et par lui, device-mapper et dm-crypt) ne monte pas les
systèmes de fichiers chiffrés, il les mappe, et ça n’a rien a voir. On remarque
qu’est apparu dans /dev/mapper le fichier crypto. Ce fichier est le disque
virtuel qui correspond a notre image. Il se comporte comme toute partition, et
peut donc être monté, formaté, etc (il ne peut cependant pas être partitionné.
Il se comporte en effet comme une partition, et non comme un véritable disque.)
Bon, ceci fait, notre disque virtuel n’est pas formaté. Il nous reviens donc de
le faire, pour pouvoir l’utiliser.
sudo mkfs.ext4 /dev/mapper/crypto
Maintenant que notre disque est formaté, il peut être monté :
sudo mount /dev/mapper/crypto /mnt
Et voila, nous avons un système de fichier fonctionnel et chiffré! Si vous
voulez vérifier, un mount | grep crypto
devrait vous donner le résultat
suivant :
/dev/mapper/crypto on /mnt type ext4 (rw,relatime,data=ordered)
Vous pouvez maintenant commencer a stocker tous vos secrets sur ce fichier, ils sont (en fonction de votre passphrase) en sécurité.
Pour résumer :
-
Pour monter vos partitions :
sudo cryptsetup luksOpen <fichier chiffré> <nom de disque virtuel> sudo mount /dev/mapper/<nom de disque virtuel> <emplacement>
-
Pour démonter vos partitions :
sudo umount <emplacement> sudo cryptsetup luksClose <nom de disque virtuel>
Pour simplifier la vie de tous, j’ai créé deux petits scripts vous permettant de créer et de monter/démonter vos images/disques chiffré-e-s en une seule commande. Ils se trouvent sur github.
Par ailleurs, si vous comptez transferer votre image disque sur un véritable
disque (ou clé usb, ou autre), il est préférable de créer une partition de
taille appropriée et de faire un dd if=votre_image of=/dev/votre_partition
pour ce faire.