Retailler à la volée une LVM chiffrée LUKS
Par Petaramesh le mardi 27 mai 2008, 11:58 - Informatique non-duelle - Lien permanent
(English abstract at end.)
Et encore un article en bas moldave qui s'annonce ;-)
J'explique ci-dessous comment il est possible d'agrandir à la volée une LVM chiffrée LUKS sur laquelle est installé tout un système GNU/Linux chiffré (ici une Ubuntu 8.04 Hardy).
Si cela vous parle autant que l'élevage du Yaka-Faucon en Patagonie septentrionale, passez votre chemin ;-)
Ma problématique pour cette manip' était la suivante : un ordinateur portable entièrement chiffré (sauf /boot) dont le disque dur était partitionné de la manière suivante :
- sda1:
/boot(non chiffré) - sda2: LVM chiffrée contenant le root filesystem et la quasi-totalité des volumes logiques usuels (
/var,/home...) - sda3: un
/tmpchiffré utilisant une clé aléatoire générée au boot. - sda4: un
swapchiffré utilisant une clé aléatoire générée au boot.
L'objectif de la manip était d'"incorporer" le /tmp et le swap à l'intérieur de la LVM chiffrée principale et non plus à l'extérieur de celle-ci, de manière à pouvoir utiliser la fonction "hibernation sur disque" de la machine, qui nécessite en pratique que le déchiffrement du root filesystem au boot permette également l'accès au swap sur lequel est stocké le fichier de reprise, le plus simple étant alors de mettre le swap dans la même LVM chiffrée que le reste des partitions.
La même manip pourrait être utilisée à d'autres fins, par exemple augmenter l'espace disque utilisable après avoir recopié l'ensemble d'un système chiffré sur un disque neuf plus gros.
Pour que ça soit plus drôle, nous allons faire ça en live, sur le système tournant et bien chaud, et sans recourir au boot sur un CD-Rom.
Cet article est en partie inspiré de l'article de Bodhi.Zazen : How to Resize a LUKS Encrypted File System.
Avertissement : Ce type de manipulation est susceptible de provoquer la perte irréparable de l'ensemble des données présentes sur votre disque, si vous faites la moindre erreur durant les opérations, ou si j'ai fait la moindre erreur en les décrivant ! Faites une copie de sauvegarde de l'ensemble de votre système, vous êtes seul(e) responsable des dégâts que vous vous apprêtez à causer, même si une erreur s'est glissée dans mon article et si c'est moi qui vous ai foutu dedans. À vos risques et périls ! ;-)
Dans mon cas particulier, je vais donc commencer par supprimer les partitions sda3 et sda4, dont le contenu sera perdu durant l'opération, mais cela est sans importance s'agissant d'un /tmp et d'un swap, puis je vais étendre la partition sda2 sur laquelle réside la LVM chiffrée afin de récupérer dedans l'espace laissé libre par les partitions supprimées, puis j'agrandirai le container chiffré qui occupe cette partition, puis j'agrandirai le volume physique de LVM qui est dedans, ce qui ajoutera à la LVM chiffrée l'espace ainsi récupéré, permettant alors d'y créer de nouveaux volumes logiques, ou d'étendre les volumes logiques existants.
Dans le cas général, on considèrera que nous disposerons d'une manière ou d'une autre d'espace disque libre immédiatement après la partition contenant la LVM chiffrée à étendre.
Dans mon cas particulier, il me faut commencer par désactiver le swap (swapoff -a) dont je vais supprimer la partition, démonter le /tmp, et le démontage du /tmp nécessite de fermer toute session graphique X (KDE ou Gnome) et d'arrêter le gestionnaire de session graphique (invoke-rc.d kdm stop ou invoke-rc.d gdm stop selon le cas), ce qui me fera donc travailler en mode console texte. Il me faudra ensuite désactiver les volumes chiffrés correspondants avant de pouvoir en supprimer les partitions.
Dans le cas général, si vous n'avez pas besoin de démonter une partition nécessaire, vous pouvez travailler dans un terminal depuis une session graphique.
Retaillage des partitions
Commençons donc par décrire l'étape de suppression des partitions inutiles, et de redimensionnement de la partition à agrandir.
Nous allons pour cela utiliser le bon vieux fdisk en console, et non pas un outil graphique, car seul fdisk nous permettra de supprimer notre partition essentielle (celle de la LVM chiffrée) et de la recréer exactement au même endroit, mais plus grande.
Lançons donc: fdisk /dev/sda
- La première chose à faire est d'afficher la table de partitions actuelle en utilisant la commande "p", et de noter absolument tous les jolis chiffres qui apparaîssent alors, de manière à pouvoir remettre manuellement les choses en l'état en cas de problème.
- Puis nous utiliserons la commande "d" de fdisk afin de détruire sans regret les partitions "4" et "3" dont nous n'avons plus besoin.
- Puis nous arrivons à l'étape vraiment terrifiante de la manoeuvre, qui consiste à supprimer la partition sda2, c'est-à-dire celle de notre LVM chiffrée, ce qui revient très exactement à scier la branche sur laquelle notre système est assis. Supprimons donc courageusement la partition "2" à l'aide de la commande "d".
- Pas de panique toutefois, les modifications ne seront réellement apportées sur le disque qu'au moment où nous exécuterons la commande "w" finale, et nous aurons recréé la partition vitale d'ici-là, mais en plus grand. D'autre part, la modification de la table de partitions sera alors écrite sur le disque dur lui-même, mais le noyau Linux n'en tiendra aucun compte puisqu'il est incapable de relire la table de partitions d'un disque ayant des partitions montées. Il faudra donc rebooter le système pour que le changement de taille de la partition concernée soit pris en compte.
- Après avoir supprimé la partition "2", nous la recréons maintenant aussitôt, comme partition primaire, en utilisant la commande "n". Nous veillerons alors à ce que la "nouvelle partition 2" commence à l'endroit exact du disque (numéro de cylindre) où elle commençait précédemment, et nous la laisserons s'étendre jusqu'à la fin du disque, utilisant ainsi tout l'espace disponible.
- Après avoir recréé la partition, utilisons la commande "p" pour afficher la nouvelle table de partitions, et vérifions soigneusement à l'aide de nos notes qu'elle commence effectivement exactement au même endroit que précédemment.
- Si c'est bien le cas, nous pouvons alors écrire nos modifications de manière définitive avec la commande "w", qui nous fera également quitter fdisk.
Nous allons maintenant devoir rebooter le système pour que la nouvelle table de partitions soit prise en compte. Toutefois, si nous avons (dans mon cas particulier) supprimé des partitions qui servaient antérieurement, nous devons en faire disparaître toute trace dans /etc/fstab et /etc/crypttab, puis régénérer notre initramfs (update-initramfs -u) pour éviter de cruelles erreurs lors du reboot.
Rebootons donc bien proprement le système. Ceci devrait se dérouler sans erreur.
Extension du volume LUKS chiffré
Après avoir rebooté, il nous faut théoriquement agrandir le volume chiffré supportant notre LVM. Je dis théoriquement car mes observations semblent démontrer que le volume chiffré utilise automatiquement la nouvelle taille entière de la partition, mais comme je n'en suis pas absolument certain, le redimensionner quand même ne fera pas de mal.
- Affichons tout d'abord la taille actuelle de notre container de LVM chiffrée, supposant qu'il s'appelle "encVG" par exemple :
# cryptsetup status encVG /dev/mapper/encVG is active: cipher: aes-cbc-essiv:sha256 keysize: 192 bits device: /dev/sda2 offset: 1032 sectors size: 312061593 sectors mode: read/write
- "Agrandissons" (en théorie) maintenant le container :
cryptsetup resize encVG
- Affichons de nouveau sa taille (
cryptsetup status encVG) : Surprise : il semble que rien n'a changé, et que notre manip n'a donc servi à rien ? Ce n'est pas grave : nous utilisons désormais bel et bien la totalité de l'espace attribué à la partition sda2.
Agrandissement du volume physique de la LVM
C'est là que nous allons nous apercevoir que la manip' a marché !
# pvs PV VG Fmt Attr PSize PFree /dev/mapper/encVG VG1 lvm2 a- 144.80G 0
pvresize /dev/mapper/encVG
# pvs PV VG Fmt Attr PSize PFree /dev/mapper/encVG VG1 lvm2 a- 148.80G 4.0G
Eh oui ! le "pvresize" nous a bien fait gagner 4 Go d'espace libre dans la LVM chiffrée !
Création des nouveaux volumes logiques
Nous pouvons maintenant créer (lvcreate) un ou plusieurs nouveaux volumes logiques dans l'espace désormais disponible sur la LVM. Dans mon cas, j'en recréerai deux, pour le /tmp et pour le swap bien sûr.
Si vous souhaitez utiliser ce nouvel espace non pas pour créer de nouveaux volumes logiques, mais pour agrandir un volume déjà existant (lvextend), je vous conseille toutefois de commencer par créer un nouveau volume logique, que vous supprimerez ensuite, mais entre-temps vous l'aurez rempli de données aléatoires, ce qui est toujours conseillé avant de commencer à utiliser un volume chiffré.
Remplissage des nouveaux volumes logiques avec des données aléatoires
Par exemple :
dd if=/dev/urandom of=/dev/mapper/VG1-newvolume bs=1M
(Si vous voulez accélérer cette étape, vous pouvez utiliser /dev/zero à la place de /dev/urandom, puisque, s'agissant d'un volume chiffré, le chiffrement donnera de toute manière un aspect parfaitement aléatoire aux données qui seront physiquement écrites sur le disque (les zéros seront transformés en random apparent).
Formatage des nouveaux volumes logiques
Nous n'avons plus désormais qu'à formater les nouveaux volumes logiques en fonction de leur utilisation projetée : mke2fs, mkswap, etc... ou, pour l'extension d'un volume existant, lvextend puis resize2fs[1] par exemple.
Mise à jour de fstab
Enfin, nous pouvons monter nos nouveaux volumes, sans oublier bien sûr de les mentionner dans /etc/fstab - il n'y a rien à ajouter dans /etc/crypttab puisque l'entrée servant à déverrouiller globalement la LVM chiffrée y figure déjà.
That's all, folks !
English abstract : This article explains how to expand a LUKS-encryped LVM on which resides a fully encrypted GNU/Linux System, including its root filesystem. This can be done on the "live" system without needing to boot from a live CD or the like. Use an online translator such as Google translate or babelfish to obtain a truly bad, automated translation of this document ;-)
Help Google : resize enlarge expand LUKS encrypted partition LVM container on the fly
Notes
[1] À effectuer sur un volume préalablement démonté









Commentaires
Sauf que ton truc avec fdisk ne marche QUE si les partoches /tmp et swap sont physiquement à côté de la partoche que tu veux redimensionner!
Si elles sont ailleurs, tu vas rien agrandir du tout.
Il faut bien préciser qu'agrandir une partition de cette manière n'est possible que s'il y a de l'espace disque derrière. Et en plus si tu te plante d'un octet lors de la re-création, toute le partoche dégage...
Bref, un peu dangereuse, cette méthode :)
@Gab :
Te ferai-je remarquer que c'était précisé dans le texte ?
>
Tu ne peux pas te planter "d'un octet". Tu peux te planter d'un cylindre ;-)
>
Te ferai-je remarquer que c'était précisé en gras dans le texte ?
Maintenant, si tu en connais une "pas dangereuse", je suis preneur ; dans le cas contraire, j'émets quelques légers doutes quant à l'utilité pratique de ton commentaire...
Tout cela est bel et bien beau mais n'a quand même rien a voir avec les paysages magnifiques de la Patagonie septentrionale surtout vus par l'oeuil d'un Yaka-Faucon en vol, fut-il d'élevage.
Et ben dis donc, pour trouver matière à digression sexuelle, je vais ramer ;-))
@Christine
Pourquoi digresser? On est en plein dans le sujet, non ?
Bon, d'accord ça suppose une certaine orientation-objet de nos penchants, un fau(x)con n'y suffira peut-être pas ...
:-)
@Chompitiarve : c'est vrai, en cherchant bien j'ai trouvé
dur
incorporer
à l'intérieur
à l'extérieur
plus gros
plus drôle
erreur
j'agrandirai le volume physique
manuellement
vraiment terrifiante
montées
changement de taille
truly bad
Finalement, ça peut l'faire ;-))
UNIX Sex:
{look; find; talk; grep; touch; finger; find; flex; unzip; mount; workbone; fsck; yes; gasp; fsck; yes; eject; umount; makeclean; zip; split; done; exit}Correction :
- updfate-initramfs -u
+ update-initramfs -u
Tu utilises aes-cbc-essiv:sha256 pour chiffrer ?
@ccal : Merci, le typo que tu m'as signalé est corrigé.
>
C'est ce que propose cryptsetup par défaut pour LUKS, mais pour des raisons de performances j'utilise généralement une clé plus courte (AES128 ou 192, surtout pour du swap ou du temp) qui me semblent bien suffisants en termes de sécurité (au rapport du contenu des machines), le "SHA256" ici étant pour les IVs.
Tiens, j'ai eu le plaisir de voir hier soir qu'une corrective que j'ai apportée au package cryptsetup a été acceptée et incorporée aux futurs packages cryptsetup Ubuntu...
Quoiii ? en ces temps de disette tu t'adonnes au luks le plus débridé ?
y'en a qui ont de la chance ici :}
@Krysalia : J'adore m'adonner aux trucs les plus débridés, hélas, ma charge guruïque m'en laisse trop peu le loisir :-}
Ouais. Mais t'as un système d'exploitation bien rangé qui tourne bien... On ne peut pas tout avoir :D
@S.A.S. Swâmi
> j'émets quelques légers doutes quant à l'utilité pratique de ton commentaire...
A part insister sur le fait que ce que tu présente un cas très particulier? Aucun :)
Mouarf, c'est pas parce que ça marche que c'est particulier, on n'est pas sous Windows :-D
.
C'est un truc de sanglier ca !
@gab (re) :
Pour revenir là-dessus, il me semble que ce que tu considères comme un "cas particulier" est le fait d'étendre une partition alors qu'on dispose d'espace libre adjacent. Si tu y réfléchis une seconde, tu t'apercevras que toute extension de partition nécessite au préalable de disposer d'espace disque libre adjacent, et que si l'on n'en a pas, il faut donc en faire ;-)
Il me semble donc que ce "cas particulier" ramène donc bel et bien à un cas général.
D'autre part, s'agissant de l'extension d'une LVM chiffrée sur laquelle est installée tout un système, on n'aura généralement sur le disque pas d'autres partitions qu'un petit
/bootet une grosse partition pour la LVM chiffrée. S'il reste de la place, soit elle aura été laissée libre "pour le cas où, un jour...", soit elle aura été utilisée pour des partitions spécifiques, typiquement temporaires, qui peuvent être supprimées sans casse (mon cas), soit elle aura été utilisée pour un quelconque espace de stockage additionnel que l'on pourra sans problème recopier sur un support externe le temps d'effectuer les modifications nécessaires (puisque par définition ce qui n'est pas à l'intérieur de la LVM chiffrée n'est pas vital au fonctionnement du système...).Et il y a bien sûr aussi le cas de figure de l'extension de la LVM après recopie de l'ensemble du système sur un disque plus gros, situation commune où la présence d'espace libre derrière la LVM coule de source.
Décidément, je trouve ce cas particulier vraiment bien général ;-)
Vu comme ça, certes. Mais j'ai toujours trouvé ça contraignant de devoir avoir de la place //après// pour redimensionner une partition. A ma connaissance il n'y a pas de méthode si on a de la place //avant// ou //ailleurs// (à part avec lvm).
Le cas le plus général, en tous cas que j'ai le plus souvent croisé, est que d'un coup une partition ne sert plus (parce qu'on l'a déplacé sur un disque qu'on vient d'acheter, par exemple), et cette partition n'est pas du tout derrière celle qu'on voudrait agrandir.
Et là, ta méthode ne fonctionne pas, d'où la qualification de 'cas particulier' ;)
@Gab : Oui, c'est tout l'intérêt des LVM et systèmes apparentés, que de s'affranchir des limites strictes, bêtes et méchantes qui s'appliquent aux partitions de disques...
Aucun outil libre, à ma connaissance, ne permet de redimensionner une partition autrement que par la fin, aucun outil libre ne permet d'en déplacer le début (sauf à recopier l'ensemble de la partition vers l'avant du disque si on a la place suffisante).
Note que si l'on aime les acrobaties risquées, on peut déplacer une partition vers le début du disque avec un bête "
dd" et la partition s'écrasera alors elle-même pendant sa propre copie. Ça marche, c'est sauvage à faire, mais il vaut mieux que rien n'interrompe le processus avant le coup de fdisk final...Il existe un outil qui permet de retailler, copier et déplacer les partoches dans tous les sens, mais c'est un outil commercial que je ne citerai donc pas ici, et d'autant moins qu'il est très risqué de l'utiliser pour retailler un disque qui a été initialement partitionné avec des outils différents et qui n'avaient pas forcément la même vision de la géométrie du disque. Ah, les différentes visions de la géométrie d'un disque de nos jours, c'est rien que du bonheur... Faut même parfois faire gaffe selon la version de noyau avec laquelle on a booté la machine, je me suis parfois vu obligé de lancer fdisk en forçant manuellement une vision particulière de la géométrie d'un disque pour pouvoir retailler sans casser des trucs qui avaient été faits par gparted sur un live-CD utilisant une autre version de noyau.
Tiens, la machine sur laquelle je suis, là :
Tu noteras peut-être une certaine différence de la vision de la géométrie C/H/S selon qu'on pose la question à fdisk ou hdparm, et je ne préfère même pas savoir ce que le BIOS en pense...
Il y a des cas où ce genre de chose peut avoir des conséquences franchement rigolotes...
Nickel, merci pour ce billet technique. Clair, pertinent, qui permet d'apprendre énormément de chose (comme d'hab. quoi!).
Il ne te reste plus qu'à rédiger des billets du style :
Merci encore pour la qualité de tes billets.
@mitch :
C'est ce que je fais sur le mien (la carte SD reste dedans en permanence, me sert de "disque dur étendu" grâce à un jeu de liens symboliques, est montée automatiquement au boot avec l'ensemble du système chiffré).
Rien n'est plus simple. Il suffit de chiffrer la carte SD en LUKS avec un fichier-clé aléatoire que je conserve dans
/etc/keys(le root filesystem étant lui-même chiffré, cela ne pose pas de problème), le fichier-clé ayant été initialement généré avec une instruction du genre :Avant de chiffrer la carte SD avec :
(Ouvrir ensuite manuellement le container et créer un filesystem dedans avec mke2fs.)
Il suffit ensuite de mettre dans
/etc/crypttab:et dans /etc/fstab :
C'est tout !
N.B.: Si l'on veut que le montage de la carte SD chiffrée survive à une suspension ou une hibernation du système, il faut utiliser un noyau supportant "
USB_PERSIST", c'est-à-dire au moins un 2.6.24. J'utilise celui-ci sur mon EeePC. (Attention, il est vulnérable à l'affreuse faille de "local privilege escalation")Super !!! Merci beaucoup !
M'en vais bidouiller mon EeePC moi ... gnark gnark gnark :-)
c'est /etc/keys/.sdb1.key sans l'extention .bin dans /etc/crypttab non ?
@ccal : Tu as raison, ça s'appelle une erreur de copié/collé de ma part. J'ai suffixé mes propres clés en .bin ce qui n'est pas nécessaire, je l'ai viré de quelques entrées dans le commentaire ci-dessus pour les raccourcir, et je l'ai oublié dans l'autre... Je vais corriger l'erreur ci-dessus, merci :-)