PC portable entièrement crypté avec boot sur clé USB
De plus en plus de distribution Linux proposent d'installer le système sur des partitions cryptées, c'est le cas de Debian et Fedora.
Dans ce genre d'installation, tout n'est pas crypté, il y a forcément une partition ”/boot” qui contient grub, le kernel et l'initrd, qui ne peuvent être cryptés. En effet le BIOS doit pouvoir lire grub pour le charger et grub doit pouvoir lire le kernel et l'initrd, à ce moment du boot, le système n'a pas les éléments nécessaires pour décrypter un espace disque et y lire ces programmes.
La solution pour avoir le disque dur totalement crypté est de mettre la partition /boot ailleurs, sur une clé USB par exemple. On va donc transférer une Debian sur un espace crypté en LVM et passer le kernel et grub sur une clé USB.
Les noms des devices sont à adapter selon le contexte.
Préparation
Il y a quelques prérequis pour cette opération :
- Pour le backup: une autre machine, un disque dur USB,
- Pour la configuration: un live CD ou SystemRescueCD sur un clé USB,
- Pour le boot: une clé USB. Le BIOS du portable doit pouvoir booter sur une clé USB.
Ensuite, il faut installer tous les packages nécessaires:
# aptitude install lvm2 initramfs-tools cryptsetup hashalot mbr
Sauvegarde du système
Tout d'abord, il faut booter le portable sur SystemRescueCD ou un LiveCD qui possède de quoi faire un tar, scp, cryptsetup, du LVM.
Ensuite, on monte les partitions du système à sauvegarder. Cette techinque est à retenir, car on manipule les fichiers du système à froid, on est donc sûr que le système ne changera pas durant le backup:
Pour trouver quel est le disque dur du portable:
# fdisk -l --> /dev/sda
On crée un répertoire pour monter la partition root du système à sauvegarder et on monte les partitions (à adapter à son /etc/fstab) :
# mkdir /a # mount /dev/sda1 /a # mount /dev/sda3 /a/home
Enfin, on sauvegarde ailleurs, sur une autre machine, par SSH, et on démonte les partitions :
# cd /a # tar cpf - * | ssh orgrim@192.168.0.1 "cat | gzip > laptop.tar.gz" # cd / # umount /a/home # umount /a
La commande crée le tar sur la sortie standard, renvoyée dans ssh, qui se connecte. On demande à SSH d'exécuter la commande entre guillemets au lieu de lancer un shell. Pour capter le flux du tar, on lance cat, qu'on redirige dans gzip puis dans un fichier.
tar pour ne pas altérer les fichiers, avec l'option “p” qui conserve les permissions et propriétaires des fichiers/répertoires.
Crypter le disque dur
Partionnement
On va partitionner le disque dur pour avoir une partition de SWAP (de 1Go, soit 2 fois la RAM, à adapter) et une partition pour un volume physique LVM2, voici pour référence les commandes à effectuer avec fdisk :
# fdisk /dev/sda o, n, p, 1, <return>, +1024M, t, 1, 82 n, p, 2, <return>, <return>, t, 2, 8e
Destruction et initialisation des données du disques
Pour que ça serve à quelque chose, il ne faut pas laisser de trace des données qui sont actuellement sur le disque dur. Il existe des outils dit de “forensic” comme TCT, qui peuvent retrouver des données effacées.
Pour que l'encryption soit efficace sur le disque dur, il faut générer du bruit partout.on va donc prendre du bruit de /dev/urandom (parce /dev/random, c'est bien trop long) :
# dd if=/dev/urandom of=/dev/sda1 # dd if=/dev/urandom of=/dev/sda2
Cette opération est très longue, pour 80 Go ça m'a pris 12 heures environ.
Configuration du LVM crypté
La première chose à faire est de créer un partion LUKS (Linux Unified Key Setup). Ca permet de stocker les clés et la configuration du cryptage au début de la partition, comme ça n'importe quel système GNU/Linux est sensé pouvoir le lire. On fait ça avec cryptsetup, qui demande une passphrase à la création (luksFormat) et déverouille lors de l'ouverture de la partition (liksOpen).
# cryptsetup -y --cipher aes-cbc-essiv:sha256 --key-size 256 luksFormat /dev/sda2 # cryptsetup luksOpen /dev/sda2 cryptpart
Le “luksOpen” a créé un mapping pour la partition cryptée, on n'utilise donc plus ”/dev/sda2” mais ”/dev/mapper/cryptpart”.
On crée ensuite notre configuration LVM2 :
- Volume Physique :
# pvcreate /dev/mapper/cryptpart
- Volume Group :
# vgcreate system /dev/mapper/cryptpart
- Volumes Logiques :
# lvcreate -n root -L 10G system # pvdisplay /dev/mapper/cryptpart | grep Free Free PE 16273 # lvcreate -n home -l 16273 system
Pour “lvcreate”, on utilise une taille fixe pour ”/” (”-L 10G”) et le reste pour ”/home”, en spécifiant le nombre exact de “Physical Extends” restants sur le volume physique.
Enfin, les systèmes de fichiers en ext3 :
# mke2fs -j /dev/mapper/system-root # mke2fs -j -m 0 /dev/mapper/system-home
Restauration du système backupé
On procède maintenant à l'opération inverse :
# mount /dev/mapper/system-root /a # mkdir /a/home # mount /dev/mapper/system-home /a/home # cd /a # ssh orgrim@192.168.0.1 "zcat laptop.tar.gz" | tar xpf -
Tout est désormais en place sur un disque dur crypté.
Modification de la configuration du système
Il faut modifier quelques fichiers de configuration pour que le système puisse booter sur le LVM crypté:
/etc/crypttab, déclaration de la partition root crypté pour le device mapper :
# <target name> <source device> <key file> <options> cryptpart /dev/hda2 none verify,cipher=aes,hash=sha256
/etc/fstab, passage vers LVM2 :
# /etc/fstab: static file system information. # # <file system> <mount point> <type> <options> <dump> <pass> proc /proc proc defaults 0 0 /dev/mapper/system-root / ext3 defaults,errors=remount-ro 0 1 /dev/sda1 /boot ext2 defaults,noauto 0 2 /dev/mapper/system-home /home ext3 defaults 0 2 /dev/mapper/swap none swap sw 0 0 /dev/hdc /media/cdrom0 udf,iso9660 user,noauto 0 0
/dev/sda1 sera le device de la clé USB sur le système définitif, l'option “noauto” permet de ne pas monter automatiquement cette partition, on évite ainsi une erreur si la clé utilise un autre device.
Créer la clé USB pour le boot
Prépartion de la clé
Il faut insérer la clé USB et trouver son device avec fdisk -l puis l'initialiser :
# fidsk /dev/sdd o, n, p, 1, <return>, <return>, a, 1
On formatte en ext2 :
# mk2efs /dev/sdd1
Chroot sur le système restauré
Pour cette opération, on va se “chrooter” sur le système crypté :
# mount -o bind /dev /a/dev # mount -t sysfs none /a/sys # mount -t proc none /a/proc # mkdir /a/usbkey # mount /dev/sdd1 /a/usbkey # chroot /a /bin/bash
On est maintenant sur notre Debian hébergée sur le disque dur du portable.
Mise à jour de l'initrd
Maintenant qu'on est chrooté, on a accès à “initramfs-tools”. On recrée donc un nouvel initrd, qui aura automagiquement tout ce qu'il faut pour gérer le disque crypté :
# update-initramfs -v -t -c -k 2.6.26-1-686 update-initramfs: Generating /boot/initrd.img-2.6.26-1-686 ... Calling hook cryptroot ...
On peut remplacer ”-k <version du noyau>” par ”-k all” qui recréera tout les initrd nécessaires. Il faut bien voir “update-initramfs” ajouter les outils nécessaires à la gestion du disque encrypté, sinon le système ne pourra pas booter.
Pour vérifier, on peut extraire le contenu de l'initrd, il doit y avoir un fichier conf/conf.d/cryptroot, qui reprend les informations de /etc/crypttab :
# cd /tmp # mkdir test # cd test # zcat /boot/initrd.img-2.6.26-1-686 | cpio -i # cat conf/conf.d/cryptroot target=cryptpart,source=/dev/hda2,key=none,lvm=system-root,cipher=aes,hash=sha256 # cd / # rm -rf /tmp/test
Grub sur la clé USB
Il faut mettre à jour le fichier de configuration de Grub (/boot/grub/menu.lst). On va mettre à jour la configuration utilisée par debconf pour la mise à jour de du fichier lors d'une installation de noyau, ça servira pour l'installation de futur noyau :
# kopt=root=/dev/mapper/system-root ro # groot=(hd0,0)
Avec le “root” pour les 2 entrées de boot, on met le premier device car le BIOS oriente le nommage des devices selon l'ordre de boot (donc hd0 sera la clé) :
title Debian GNU/Linux, kernel 2.6.26-1-686 root (hd0,0) kernel /vmlinuz-2.6.26-1-686 root=/dev/mapper/system-root ro initrd /initrd.img-2.6.26-1-686
Ensuite, on doit copier le contenu du répertoire /boot sur la clé, c'est à dire l'installation existante de Grub, le kernel et l'initrd :
# cp -R /boot/* /usbkey
Puis on passe sur la clé :
# umount /usbkey # mount /dev/sdd1 /boot
Et on mets à jour l'installation de Grub :
# grub-install --recheck --no-floppy /dev/sdd ... (hd2) /dev/sdd ...
grub-install donne le mapping des disques entre le noyau et son nommage, dans notre exemple, il faudra utiliser (hd2) pour l'installation de Grub
Enfin, on peut installer Grub sur le MBR de la clé :
# grub grub> root (hd2,0) Filesystem type is ext2fs, partition type 0x83 grub> setup (hd2) Checking if "/boot/grub/stage1" exists... no Checking if "/grub/stage1" exists... yes Checking if "/grub/stage2" exists... yes Checking if "/grub/e2fs_stage1_5" exists... yes Running "embed /grub/e2fs_stage1_5 (hd2)"... 17 sectors are embedded. succeeded Running "install /grub/stage1 (hd2) (hd2)1+17 p (hd2,0)/grub/stage2 /grub/menu.lst"... succeeded Done. grub> quit
Réinitialiser le MBR du disque
Pour faire les chose proprement, il est sympa de supprimer le Grub déjà installé dans le MBR du disque, ainsi la machine apparaitra vierge pour le profane si la clé USB de boot n'est pas en place :
# install-mbr /dev/sda
Sortie du chroot
Pour sortir du chroot :
# sync # umount /boot # exit # umount /a/dev /a/sys /a/proc /a
Voilà, il reste maintenant à booter le système sur la clé…
Démarrage sur la clé USB
On reboote et on essaye de booter sur la clé. Le menu de Grub doit apparaitre, quand on choisit une entrée, le kernel doit être lancé. Les problèmes ici peuvent venir d'une mauvaise configuration utilisant les mauvais de devices, il faut donc bien connaitre son matériel pour bien interpréter la sortie de fdisk -l.
Lors du boot, l'initrd doit demander la passphrase pour décrypter le volume physique.
Une fois la machine booté, on peut débrancher sans risques la clé USB du portable.
Configurer la swap
Une fois qu'on are booté sur le système crypté avec la clé, il reste à faire la swap.
On crée une clé pour la swap qui sera stockée dans le fichier /etc/keys/swapkey, voici une commande pour créer une clé aléatoire :
# dd if=/dev/random bs=5k count=1 2> /dev/null | hashalot -s 'Une bonne phrase de sel bien compliquée' -x sha256 > /etc/keys/swapkey # chmod 600 /etc/keys/swapkey
Puis on crypte la partition dédiée à la swap :
# cryptsetup create swap /dev/hda1 -d /etc/keys/swapkey -c aes-cbc-essiv:sha256 -h sha256
On ajoute une entrée dans /etc/crypttab :
# cat /etc/crypttab swap /dev/hda1 /etc/keys/swapkey cipher=aes,hash=sha256
Puis on crée effectivement la swap :
# mkswap /dev/mapper/swap
Enfin, on l'active :
# swapon /dev/mapper/swap
Backup de la clé USB
Il est conseillé de faire un backup de la clé USB sur une autre machine, au cas où on la perd… Un petit tar c'est vite fait.
En cas de problème
- Si on oublie la passphrase, c'est MORT. On peut donc recommencer à l'étape du “luksFormat”.
- Si on veut reprendre sur SystemRescueCD, pour monter la racine :
# cryptsetup luksOpen /dev/sda2 cryptpart # vgscan # vgchange -ay # mkdir /a # mount /dev/mapper/system-root /a