blog-source/content/2013-07-10.12:44:28.md

152 lines
8.7 KiB
Markdown
Raw Normal View History

2014-11-24 22:52:53 +01:00
Title: Le chiffrement de partitions avec dm-crypt et device-mapper
Date: 2013-07-10 03:18
Author: Wxcafe
Slug: le-chiffrement-de-partition-avec-dm-crypt-et-device-mapper
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__](http://en.wikipedia.org/wiki/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](http://wxcafe.net/posts/11/19/12/la-cryptographie-avec-pgp-et-principalement-gnupg))
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](http://en.wikipedia.org/wiki/Linux_Unified_Key_Setup), 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](https://github.com/wxcafe/cryptoscripts).
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.