Booter son serveur avec RAID, chiffrement et LVM depuis une clef USB

Introduction

Il arrive à tout le monde d’avoir un accident (Grub cassé, mise à jour du kernel qui tourne mal, etc.) qui empêche de démarrer son ordinateur ou son serveur sous Linux. Dans ce cas, plutôt que de tout réinstaller comme un bourrin, il est utile d’avoir sous la main une procédure pour démarrer depuis une clef USB et monter ses disques. L’objectif étant au mieux de réparer ce qui est cassé, au pire faire un backup complet.

Contexte

Si la procédure est relativement simple, il y a un certains nombre de commandes à connaitre selon les cas. Dans mon cas, la configuration des disques est assez “complexe” (mais classique pour un serveur), avec du RAID et du chiffrement des disques, ce qui nous permettra de faire le tour des différentes manipulations.

Dans mon exemple j’utilise un serveur contenant 2 disques dur montés en RAID 1 (mirroring). Sur chaque disque se trouvent 2 partitions : la première sert au RAID du /boot (c’est une partition en ext4) et la seconde sert de volume chiffré pour tout le reste du système.
On a donc 2 disques “virtuels” qui sont /dev/md0 (pour le boot) et /dev/md1 (pour le reste du système). Le disque /dev/md1 est chiffré à l’aide de LUKS et sert de Physical Volume pour LVM. Je l’ai ensuité découpé en Logical Volume différents pour /, /home, /tmp, /var/lib/vz et /var/lib/vz/dump (c’est un serveur Proxmox).

Création de la clef USB

On va donc utiliser une image live Debian qui va nous permettre de lancer un système temporaire sur notre serveur, depuis une clef USB. On télécharge simplement l’ISO sur le site officiel de Debian. Puis on branche notre clef USB et on repère son nom avec la commande fdisk :

kyane@laptop:~$ sudo fdisk -l
Disque /dev/sda : 232,9 GiB, 250059350016 octets, 488397168 secteurs
[...]

Disque /dev/sdb : 29,3 GiB, 31457280000 octets, 61440000 secteurs
Unités : secteur de 1 × 512 = 512 octets
Taille de secteur (logique / physique) : 512 octets / 512 octets
taille d'E/S (minimale / optimale) : 512 octets / 512 octets
Type d'étiquette de disque : dos
Identifiant de disque : 0x4939c41e

Périphérique Amorçage Début      Fin Secteurs Taille Id Type
/dev/sdb1              2048 61439999 61437952  29,3G  b W95 FAT32

Dans la longue liste qui sort, on repère la clef USB (ici /dev/sdb1) sur laquelle copier l’image ISO. On utilise la commande suivante :

sudo dd bs=4M if=/path/to/iso-image.iso of=/dev/sdb && sync

On prépare…

Tout est prêt pour démarrer notre serveur sur l’image live. On branche la clef, on démarre le serveur et on choisi la clef USB dans les périphériques au boot. On arrive sur une image légère mais suffisante de Debian, sur laquelle on s’empresse d’ouvrir un terminal en root. Nous allons avoir besoin de quelques commandes qui sont, normalement, disponibles par défaut. Dans le doute on peut lancer la commande suivante :

apt-get update && apt-get install mdadm lvm2 cryptsetup

Nous allons ensuite monter les différents disques et volumes.

Monter les disques

On commence par reconstituer les grappes RAID. Si vous n’avez pas de RAID, sautez cette étape. Si tout va bien, la commande mdadm --assemble --scan va automatiquement scanner les disques et en déduire la configuration RAID existante. Ceci va créer 2 disques : /dev/md0 et /dev/md1. Ce sont les 2 volumes RAID du serveur, dans mon cas le volume pour le /boot et celui du système.

Dans mon cas, le système est chiffré (si ce n’est pas votre cas, sautez l’étape), il va donc falloir ouvrir un autre volume pour accèder aux données, déchiffrées, de /dev/md1. Pour cela on utilise simplement la commande cryptsetup luksOpen /dev/md1 NAME, où NAME est le nom, au choix, du volume déchiffré (dans mon cas ce sera decrypt). Ceci va me créer un nouveau volume, /dev/mapper/decrypt, qui est donc le contenu déchiffré de /dev/md1. Dans mon cas, c’est mon Physical Volume pour LVM.

Monter les volumes

On a désormais accès aux Physical Volume LVM, que l’on peut lister avec la commande pvs, mais aussi les Volumes Group (que l’on liste avec vgs). Si les Volumes Group ne sont pas visibles, on peut faire un scan pour les détecter avec vgscan. On active ensuite nos Volumes Group. Dans mon cas il n’y en a qu’un seul, qui s’appelle raid :

vgchange -ay raid

Nous allons ensuite monter, un à un, les différents Logical Volumes dans /mnt pour reconstruire l’arborescence du serveur. Dans mon cas je lance les commandes suivantes, il faut adapter en fonction de votre partitionnement :

# On monte le système
mount -t ext4 /dev/mapper/raid-root /mnt
mount -t ext4 /dev/mapper/raid-home /mnt/home
mount -t ext4 /dev/mapper/raid-tmp /mnt/tmp
mount -t ext4 /dev/mapper/raid-pve /mnt/var/lib/vz
mount -t ext4 /dev/mapper/raid-dump /mnt/var/lib/vz/dump

# On monte la partition de boot
mount /dev/md0 /mnt/boot

# On monte les filesystems spéciaux
mount -t proc /proc /mnt/proc/
mount -t sysfs /sys /mnt/sys/
mount -o bind /dev /mnt/dev/
mount -o bind /run  /mnt/run

À partir de là, on a tout notre système de fichier qui est accessible dans /mnt.

…et on répare !

Se placer dans l’arborescence avec chroot

Modifier ses fichiers c’est bien, pouvoir exécuter des commandes c’est mieux ! Par exemple si on veut installer des paquets (en cas de problème de kernel) ou reconfigurer Grub.
Pour cela on va utiliser la commande chroot qui permet de changer la racine d’un système, permettant ainsi de basculer sur l’arborescence du serveur que l’on a monté dans /mnt. Pour cela rien de plus simple :

chroot /mnt /bin/bash

On se retrouve ainsi avec un prompt comme si on était connecté sur notre serveur, avec un shell Bash.

On quitte proprement

Une fois que l’on a fini ce que l’on avait à faire, on peut quitter proprement avec la commande exit. Avant de redémarrer, on prend soin de démonter les différents disques :

umount /mnt/run
umount /mnt/dev
umount /mnt/sys
umount /mnt/proc
umount /mnt/boot
umount /mnt/var/lib/vz/dump
umount /mnt/var/lib/vz
umount /mnt/tmp
umount /mnt/home
umount /mnt

Il ne reste plus qu’à rebooter, en espérant que l’on ai réussi à réparer son serveur !