Mini-Howto: Logical Volume Management und Verschlüsselung

Aus DebianforumWiki
Zur Navigation springen Zur Suche springen
Wiki ‹ Rund um den Kernel ‹ Mini-Howto: Logical Volume Management und Verschlüsselung


Dieses Howto zeigt anhand von Beispielen den Umgang mit Logical Volume Management (LVM) und die Festplatten-Vollverschlüsselung mit dm-crypt. Konkret zeige ich

  • die Umstellung eines Systems von klassischer Partitionierung auf LVM inkl. Wiederherstellung des Bootloaders (GRUB)
  • nachträgliches Hinzufügen von Logical Volumes durch Verkleinerung bestehender Logical Volumes inkl. Verkleinerung des Dateisystems
  • den Umstellung des auf LVM umgestellten Systems auf per dm-crypt verschlüsseltes LVM inkl. Wiederherstellung des Bootloaders
  • nachträgliches Vergrößern eines Logical Volumes inkl. des Dateisystems

Ich erläutere die Schritte und zeige die Befehle samt Ausgabe, werde die Befehle und deren Optionen an sich aber nicht großartig beschreiben. Zum Nachvollziehen der Beispiele ist die Lektüre der manpages unerlässlich.

Für die Aktionen, die man mit einem Rettungssystem durchführen muss, nutze ich SystemRescueCD, da auf dieser alle benötigten Tools vorhanden sind. Welches System gebootet ist, kann man Prompt erkennen: das „Versuchskaninchen” heißt „demo“ und das Rettungssystem „sysresccd“.

Einige der Dinge, die ich hier zeige, kann man auch ähnlich mit md, btrfs-Subvolumes oder ZFS machen. Ich will zeigen, wie es mit LVM geht, und nicht die unterschiedlichen Ansätze vergleichen.

Warnung.png Warnung: Niemals ein Echtsystem ohne vorheriges Backup umstellen! Darüber hinaus rate ich dazu, die Umstellung mit einer virtuellen Maschine zu üben, bevor man ein Echtsystem umstellt.


Getestet.png Getestet: Dieser Hinweis soll dir dabei helfen, zu entscheiden, ob dieser Artikel auf deinem System funktionieren wird oder nicht. Solltest du feststellen, dass dieser Artikel bei einer ungetestet Version funktioniert, kannst du das gerne hier korrigieren oder im Forum anmerken.




Logical Volume Management und dm-crypt

Logical Volume Management ist eine Abstraktionsschicht zwischen Festplatten(partitionen) und Dateisystemen. Partitionen werden als sog. Physical Volumes einer Volume Group hinzugefügt und werden für die Speicherung der Daten verwendet. Der einer Volume Group zugeordnete Speicherplatz wird in Logical Volumes unterteilt, auf denen die Dateisysteme (bis auf /boot) und Swap erzeugt werden. Logical Volumes können nachträglich in der Größe verändert werden. Die Aufteilung in die darunterliegenden Physical Volumes ist dabei irrelevant, diese können sich sogar auf unterschiedlichen Festplatten befinden.

Mit dm-crypt lassen sich Geräte transparent ver- und entschlüsseln. Im Zusammenspiel mit LVM lässt sich so ein nahezu komplett verschlüsseltes System realisieren: das entschlüsselte Gerät wird als Physical Volume verwendet, daraus eine Volume Group erzeugt und in dieser Logical Volumes für die Dateisysteme und Swap. Einzig /boot verbleibt unverschlüsselt. Mit der LUKS-Erweiterung lassen sich Schlüssel bequem verwalten.

Ausgangssituation

Ich habe Debian 9.3 in einer virtuellen Maschine installiert, was die possierlichen Festplattengrößen erklärt. Das System ist weitgehend nackt, d.h. ohne grafische Oberfläche und ähnlichen Schnickschnack, denn der kostet nur Zeit beim Kopieren des Systems (was wir im Zuge dieses Howtos öfters tun werden).

Als erstes wird Debianpackage.png lvm2 installiert, damit Logical Volume Management verfügbar ist:

root@demo:~# apt-get install lvm2

Die Festplatte sieht so aus:

jan@demo:~$ df -h
Dateisystem    Größe Benutzt Verf. Verw% Eingehängt auf
udev            488M       0  488M    0% /dev
tmpfs           100M    1,7M   98M    2% /run
/dev/sda1       6,9G    961M  5,6G   15% /
tmpfs           499M     72K  499M    1% /dev/shm
tmpfs           5,0M       0  5,0M    0% /run/lock
tmpfs           499M       0  499M    0% /sys/fs/cgroup
tmpfs           100M       0  100M    0% /run/user/1000
jan@demo:~$ cat /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda1 during installation
UUID=c5f81e86-f577-446f-b1d3-0468c5e8ea1a /               ext4    errors=remount-ro 0       1
# swap was on /dev/sda5 during installation
UUID=f7fe2f42-b7f9-40bc-b6c6-525983c0514a none            swap    sw              0       0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0

Das ist eine klassische DOS-Partitionierung. Für UEFI und GPT muss man das Schema entsprechend anpassen.

Umzug auf eine neue Festplatte und Einrichten von LVM

Jetzt soll das System auf eine neue Festplatte umgezogen werden. In der virtuellen Maschine wird dazu eine neue virtuelle Festplatte erzeugt und an die VM angeschlossen.

Partitionieren der neuen Festplatte

Wir booten das installierte System und starten die Partitionierung über fdisk. Bei Verwendung von LVM werden i.A. nur zwei Partitionen verwendet:

  • Eine kleine (256 oder 512 MB große) primäre Partition außerhalb der Volume Group, die als /boot eingehängt wird. GRUB startet den Kernel von dieser Partition und lädt von dort die initrd, die wiederum alles mitbringt, um die Logical Volumes verfügbar zu machen und den Bootvorgang fortzusetzen.
  • Eine weitere Partition, die als Physical Volume verwendet wird.
root@demo:~# fdisk /dev/sdb

Welcome to fdisk (util-linux 2.29.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table.
Created a new DOS disklabel with disk identifier 0x81bc95ac.

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p):
Partition number (1-4, default 1):
First sector (2048-33554431, default 2048):
Last sector, +sectors or +size{K,M,G,T,P} (2048-33554431, default 33554431): +256M

Created a new partition 1 of type 'Linux' and of size 256 MiB.

Command (m for help): n
Partition type
   p   primary (1 primary, 0 extended, 3 free)
   e   extended (container for logical partitions)
Select (default p): e
Partition number (2-4, default 2):
First sector (526336-33554431, default 526336):
Last sector, +sectors or +size{K,M,G,T,P} (526336-33554431, default 33554431):

Created a new partition 2 of type 'Extended' and of size 15,8 GiB.

Ob man für das Physical Volume ein logisches Laufwerk oder eine primäre Partition verwendet, ist Geschmackssache. LVM ist das einerlei.

Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
First sector (528384-33554431, default 528384):
Last sector, +sectors or +size{K,M,G,T,P} (528384-33554431, default 33554431):

Created a new partition 5 of type 'Linux' and of size 15,8 GiB.

Die neue Partition möchten wir als Physical Volume verwenden. Wir ändern daher den Partitionstyp daher auf 8e.

Command (m for help): t
Partition number (1,2,5, default 5): 5
Partition type (type L to list all types): 8e

Changed type of partition 'Linux' to 'Linux LVM'.

Zu guter letzt prüfen wir, ob alles korrekt eingerichtet wurde, und schreiben die Änderungen auf die Festplatte. Wir setzen keine Partition auf „bootbar“. Diese Information ist für GRUB nicht relevant.

Command (m for help): p
Disk /dev/sdb: 16 GiB, 17179869184 bytes, 33554432 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x81bc95ac

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sdb1         2048   526335   524288  256M 83 Linux
/dev/sdb2       526336 33554431 33028096 15,8G  5 Extended
/dev/sdb5       528384 33554431 33026048 15,8G 8e Linux LVM

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

/dev/sdb1 soll später als /boot eingehängt werden und wird mit ext2 formatiert. Wir erzeugen das Dateisystem und notieren uns die UUID.

root@demo:~# mkfs -t ext2 /dev/sdb1
mke2fs 1.43.4 (31-Jan-2017)
Ein Dateisystems mit 262144 (1k) Blöcken und 65536 Inodes wird erzeugt.
UUID des Dateisystems: 8159b9a5-e8b3-4235-9b45-cdf2b0fc7dbe
Superblock-Sicherungskopien gespeichert in den Blöcken:
        8193, 24577, 40961, 57345, 73729, 204801, 221185

beim Anfordern von Speicher für die Gruppentabellen: erledigt                    
Inode-Tabellen werden geschrieben: erledigt
Die Superblöcke und die Informationen über die Dateisystemnutzung werden
geschrieben: erledigt

Falls man vergessen haben sollte, sich die UUID zu notieren, kann man sie nachträglich über

root@demo:~# blkid /dev/sdb1
/dev/sdb1: UUID="8159b9a5-e8b3-4235-9b45-cdf2b0fc7dbe" TYPE="ext2" PARTUUID="81bc95ac-01"

anzeigen lassen.

Erzeugen der Volume Group

/dev/sdb5 wird als Physical Volume initialisiert.

root@demo:~# pvcreate /dev/sdb5
  Physical volume "/dev/sdb5" successfully created.

Danach erzeugen wir die Volume Group und fügen /dev/sdb5 als Physical Volume hinzu. Anschließend schauen wir uns die Volume Group an.

root@demo:~# vgcreate demo-vg /dev/sdb5
  Volume group "demo-vg" successfully created
root@demo:~# vgdisplay
  --- Volume group ---
  VG Name               demo-vg
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  1
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                0
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               15,75 GiB
  PE Size               4,00 MiB
  Total PE              4031
  Alloc PE / Size       0 / 0
  Free  PE / Size       4031 / 15,75 GiB
  VG UUID               YLT1Ys-31Dj-dNlc-un7E-RJDb-delq-8FCw8h

Nun erzeugen wir zwei logische Volumes auf der Volume Group: eines für Swap und eines, das das Wurzeldateisystem enthalten soll.

root@demo:~# lvcreate -L 1G -n swap_1 demo-vg
  Logical volume "swap_1" created.

Den verbleibenden Platz wollen wir für das andere LV nutzen.

root@demo:~# lvcreate -l 100%FREE -n root demo-vg
  Logical volume "root" created.
root@demo:~# vgdisplay 
  --- Volume group ---
  VG Name               demo-vg
  …
  Alloc PE / Size       4031 / 15,75 GiB
  Free  PE / Size       0 / 0
  VG UUID               YLT1Ys-31Dj-dNlc-un7E-RJDb-delq-8FCw8h

Erzeugen der Dateisysteme

Die Block Devices erfährt man über lvdisplay:

root@demo:~# lvdisplay
  --- Logical volume ---
  LV Path                /dev/demo-vg/swap_1
  LV Name                swap_1
  VG Name                demo-vg
  LV UUID                e6cWz6-UCSe-BVP4-ViN6-RFNI-dNTX-kkumwx
  LV Write Access        read/write
  LV Creation host, time demo, 2017-12-10 14:59:10 +0100
  LV Status              available
  # open                 0
  LV Size                1,00 GiB
  Current LE             256
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           254:0

  --- Logical volume ---
  LV Path                /dev/demo-vg/root
  LV Name                root
  VG Name                demo-vg
  LV UUID                LXNC2R-O7eM-UMMg-1MVo-Dk6W-VPbo-adBAx8
  LV Write Access        read/write
  LV Creation host, time demo, 2017-12-10 15:00:32 +0100
  LV Status              available
  # open                 0
  LV Size                14,75 GiB
  Current LE             3775
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           254:1

Die Namen der Devices sind gleichbleibend, egal, auf welcher Festplatte sie vorhanden sind und wie diese angeschlossen ist. Daher werden wir sie zukünftig darüber ansprechen anstelle der UUID.

Die beiden Volumes werden nun initialisiert:

root@demo:~# mkswap /dev/demo-vg/swap_1
Setting up swapspace version 1, size = 1024 MiB (1073737728 bytes)
no label, UUID=d5d92154-3f2f-4d77-90d5-17c552c93a3b
root@demo:~# mkfs -t ext4 /dev/demo-vg/root

Ein Dateisystems mit 3865600 (4k) Blöcken und 966656 Inodes wird erzeugt.
UUID des Dateisystems: b1ae0d78-1f7d-46ef-80fd-ac5c05cf421c
Superblock-Sicherungskopien gespeichert in den Blöcken:
        32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

beim Anfordern von Speicher für die Gruppentabellen: erledigt                    
Inode-Tabellen werden geschrieben: erledigt
Das Journal (16384 Blöcke) wird angelegt: erledigt
Die Superblöcke und die Informationen über die Dateisystemnutzung werden
geschrieben: erledigt

Umziehen des Systems

Jetzt sind die Dateisysteme fertig. Nun ist es an der Zeit, SystemRescueCD zu booten. Zunächst machen wir die Volume Group verfügbar.

root@sysresccd /root % vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "demo-vg" using metadata type lvm2
root@sysresccd /root % vgchange -a y demo-vg
  2 logical volume(s) in volume group "demo-vg" now active

Wenn man den Namen der Volume Group kennt, kann man sich vgscan auch sparen.

Jetzt erzeugen wir Mountpoints für das alte und das neue System und hängen die jeweiligen Dateisysteme ein. Das alte Dateisystem hängen wir sicherheitshalber schreibgeschützt ein.

root@sysresccd /root % mkdir /mnt/alt
root@sysresccd /root % mkdir /mnt/neu
root@sysresccd /root % mount -o ro /dev/sda1 /mnt/alt 
root@sysresccd /root % mount /dev/demo-vg/root /mnt/neu 

Jetzt kopieren wir das Dateisystem, wobei wir /boot überspringen. Dessen Inhalt soll ja auf einer separaten Partition landen. Bei der Verwendung von rsync ist unbedingt auf die / am Ende der Verzeichnisnamen zu achten.

root@sysresccd /root % rsync -a --exclude=/boot/ /mnt/alt/ /mnt/neu/

Jetzt erzeugen wir /boot neu, mounten und befüllen es:

root@sysresccd /root % mkdir /mnt/neu/boot
root@sysresccd /root % mount /dev/sdb1 /mnt/neu/boot 
root@sysresccd /root % rsync -a /mnt/alt/boot/ /mnt/neu/boot/

Nun chrooten wir in das umgezogenen System:

root@sysresccd /root % mount -o bind /dev /mnt/neu/dev 
root@sysresccd /root % mount -o bind /proc /mnt/neu/proc 
root@sysresccd /root % mount -o bind /sys /mnt/neu/sys 
root@sysresccd /root % chroot /mnt/neu /bin/bash

Ich gebe hier chroot die Shell explizit vor, da SystemRescueCD die zsh verwendet, die im Demosystem aber nicht installiert ist.

Als erstes passen wir die /etc/fstab an und tragen dort die neuen Devices für / und Swap ein.

root@sysresccd /root % nano /mnt/neu/etc/fstab

# <file system> <mount point>   <type>  <options>	<dump>  <pass>
/dev/demo-vg/root /             ext4    errors=remount-ro 0       1
/dev/demo-vg/swap_1 none        swap    sw              0       0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0

Alternativ kann man auch

/dev/mapper/demo--vg-root /             ext4    errors=remount-ro 0       1
/dev/mapper/demo--vg-swap_1 none        swap    sw              0       0

schreiben. In dieser Nomenklatur schreibt der Debian-Installer, wenn man LVM bereits bei der Installation einrichtet.

Dann ergänzen wir eine weitere Zeile für /boot, bei der wie auf die UUID zurückgreifen:

UUID=8159b9a5-e8b3-4235-9b45-cdf2b0fc7dbe /boot           ext2    defaults        0       2

initramfs möchte wissen, von welchem Device es aufwachen soll. Das wird in /etc/initramfs/conf.d/resume eingestellt. Dort tauschen wir das bisherige Swap-Device

RESUME=UUID=f7fe2f42-b7f9-40bc-b6c6-525983c0514a

gegen das Logical Volume aus

RESUME=/dev/demo-vg/swap_1

und erzeugen das initramfs neu.

root@sysresccd:/# update-initramfs -u -k all
update-initramfs: Generating /boot/initrd.img-4.9.0-4-amd64

Nun erzeugen wir eine Konfiguration für GRUB.

root@sysresccd:/# update-grub
Generating grub configuration file ...
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  …
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
Found linux image: /boot/vmlinuz-4.9.0-4-amd64
Found initrd image: /boot/initrd.img-4.9.0-4-amd64
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
Found Debian GNU/Linux 9 (stretch) on /dev/sda1
done

GRUB findet auch die alte Installation auf /dev/sda1. Das ignorieren wir. Jetzt installieren wir GRUB auf der neuen Platte:

root@sysresccd:/# grub-install /dev/sdb
Installing for i386-pc platform.
Installation finished. No error reported.

Fertig. Jetzt fahren wir das System runter, bauen die alte Platte aus und booten von der neuen. Dort starten wir erneut update-grub, um die alte Installation aus der Liste der Systeme zu entfernen.

root@demo:~# update-grub
GRUB-Konfigurationsdatei wird erstellt …
Linux-Abbild gefunden: /boot/vmlinuz-4.9.0-4-amd64
initrd-Abbild gefunden: /boot/initrd.img-4.9.0-4-amd64
erledigt

Wir haben nunmehr viel mehr Platz:

jan@demo:~$ df -h
Dateisystem               Größe Benutzt Verf. Verw% Eingehängt auf
udev                       487M       0  487M    0% /dev
tmpfs                      100M    1,8M   98M    2% /run
/dev/mapper/demo--vg-root   15G    950M   13G    7% /
tmpfs                      499M     72K  499M    1% /dev/shm
tmpfs                      5,0M       0  5,0M    0% /run/lock
tmpfs                      499M       0  499M    0% /sys/fs/cgroup
/dev/sda1                  248M     37M  199M   16% /boot
tmpfs                      100M       0  100M    0% /run/user/1000

/home auf separates LV verlagern

Jetzt soll /home auf ein separates Dateisystem umgezogen werden. Wir booten wieder von der SystemRescueCD und verschaffen uns Zugriff auf die Volume Group.

root@sysresccd /root % vgchange -a y demo-vg
  2 logical volume(s) in volume group "demo-vg" now active

Zunächst muss das vorhandene root-Dateisystem verkleinert werden. Das neue /home soll 8 GB groß sein; also nehmen wir / genau so viel weg. lvresize kann beides in einem Rutsch:

root@sysresccd /root % lvresize -r -L -8G /dev/demo-vg/root 
fsck from util-linux 2.28.2
/dev/mapper/demo--vg-root: 33926/966656 files (0.1% non-contiguous), 320152/3865600 blocks
resize2fs 1.43.6 (29-Aug-2017)
Resizing the filesystem on /dev/mapper/demo--vg-root to 1768448 (4k) blocks.
The filesystem on /dev/mapper/demo--vg-root is now 1768448 (4k) blocks long.

  Size of logical volume demo-vg/root changed from 14.75 GiB (3775 extents) to 6.75 GiB (1727 extents).
  Logical volume root successfully resized.

In der Volume Group ist nun wieder Platz vorhanden.

root@sysresccd /root % vgdisplay
  --- Volume group ---
  VG Name               demo-vg
  …
  Alloc PE / Size       1983 / 7.75 GiB
  Free  PE / Size       2048 / 8.00 GiB
  VG UUID               YLT1Ys-31Dj-dNlc-un7E-RJDb-delq-8FCw8h

Es ist zu beachten, dass sich nicht jedes Dateisystem verkleinern lässt. Bei ext4 und btrfs geht es, XFS lässt sich dagegen nicht verkleinern. Da hilft nur, die Daten zu sichern, das Dateisystem nach Verkleinerung des Logical Volume neu zu erzeugen und die Daten zurückzusichern.

Wir erzeugen ein neues Logical Volume und weisen diesem allen freien Platz zu. Darauf erzeugen wir ein neues ext4-Dateisystem.

root@sysresccd /root % lvcreate -l 100%FREE -n home demo-vg
  Logical volume "home" created.
root@sysresccd /root % mkfs -t ext4 /dev/demo-vg/home 
mke2fs 1.43.6 (29-Aug-2017)
Creating filesystem with 2097152 4k blocks and 524288 inodes
Filesystem UUID: b7f79630-08d3-484f-badc-f105aa397cc4
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done 

Nun hängen wir das root-Dateisystem ein.

root@sysresccd /root % mkdir /mnt/demo
root@sysresccd /root % mount /dev/demo-vg/root /mnt/demo 

Das vorhandene /home schieben wir aus dem Weg und erzeugen ein neues.

root@sysresccd /root % mv /mnt/demo/home /mnt/demo/home.o
root@sysresccd /root % mkdir /mnt/demo/home

Wir mounten das neue Logical Volume und kopieren. Bei rsync auf die abschließenden / achten. Das alte /home kann anschließend weg.

root@sysresccd /root % mount /dev/demo-vg/home /mnt/demo/home
root@sysresccd /root % rsync -a /mnt/demo/home.o/ /mnt/demo/home/
root@sysresccd /root % rm -rf /mnt/demo/home.o

Nun müssen wir noch den Mountpoint für /home in der /etc/fstab ergänzen.

  <file system> <mount point>   <type>  <options>	<dump>  <pass>
/dev/demo-vg/root /             ext4    errors=remount-ro 0	  1
/dev/demo-vg/swap_1 none        swap    sw              0	0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0
UUID=8159b9a5-e8b3-4235-9b45-cdf2b0fc7dbe /boot           ext2    defaults     $
/dev/demo-vg/home /home	 ext4    defaults        0        2

Neu starten und das installierte System booten. /home liegt jetzt separat:

jan@demo:~$ df -h
Dateisystem               Größe Benutzt Verf. Verw% Eingehängt auf
udev                       487M       0  487M    0% /dev
tmpfs                      100M    1,8M   98M    2% /run
/dev/mapper/demo--vg-root  6,6G    946M  5,4G   15% /
tmpfs                      499M     72K  499M    1% /dev/shm
tmpfs                      5,0M       0  5,0M    0% /run/lock
tmpfs                      499M       0  499M    0% /sys/fs/cgroup
/dev/sda1                  248M     37M  199M   16% /boot
/dev/mapper/demo--vg-home  7,9G     37M  7,4G    1% /home
tmpfs                      100M       0  100M    0% /run/user/1000

LVM auf neue Platte mit Verschlüsselung umziehen

Für Verschlüsselung per dm-crypt installieren wir zunächst Debianpackage.png cryptsetup:

root@demo:~# apt-get install cryptsetup

Neue Festplatte partitionieren

Jetzt soll das System erneut auf eine neue Festplatte umgezogen werden. In dem Zuge soll das System komplett verschlüsselt werden. Die neue Platte partitionieren wir wie gehabt: eine kleine Partition zum booten und eine größere, die als Physical Volume dienen soll.

Ergebnis in fdisk:

Command (m for help): p
Disk /dev/sdb: 32 GiB, 34359738368 bytes, 67108864 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x66755063

Device     Boot  Start      End  Sectors  Size Id Type
/dev/sdb1         2048   526335   524288  256M 83 Linux
/dev/sdb2       526336 67108863 66582528 31.8G  5 Extended
/dev/sdb5       528384 67108863 66580480 31.8G 8e Linux LVM

Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

Verschlüsselung mit dm-crypt einrichten

Wir nutzen /dev/sdb5 aber nicht direkt als Physical Volume, sondern verschlüsseln es zunächst mit dm-crypt. Dazu booten wir die SystemRescueCD.

root@sysresccd /root % cryptsetup luksFormat /dev/sdb5

WARNING!
========
This will overwrite data on /dev/sdb5 irrevocably.

Are you sure? (Type uppercase yes): YES
Enter passphrase: 
Verify passphrase: 

Jetzt entschlüsseln wir /dev/sdb5 als /dev/sdb5_crypt:

root@sysresccd /root % cryptsetup luksOpen /dev/sdb5 sdb5_crypt
Enter passphrase for /dev/sdb5: 
No key available with this passphrase.
Enter passphrase for /dev/sdb5: 

Volume Group ändern

Das entschlüsselte Device initialisieren wir als Physical Volume und fügen es der bestehenden Volume Group hinzu. Die bestehende Volume Group müssen wir zuvor aktivieren.

root@sysresccd /root % vgchange -a y demo-vg
  3 logical volume(s) in volume group "demo-vg" now active
root@sysresccd /root % pvcreate /dev/mapper/sdb5_crypt 
  Physical volume "/dev/mapper/sdb5_crypt" successfully created.
root@sysresccd /root % vgextend demo-vg /dev/mapper/sdb5_crypt 
  Volume group "demo-vg" successfully extended

Die bestehende Volume Group ist nun größer und besteht aus zwei Physical Volumes:

root@sysresccd /root % vgdisplay 
  --- Volume group ---
  VG Name               demo-vg
  System ID             
  Format                lvm2
  Metadata Areas        2
  Metadata Sequence No  6
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                3
  Open LV               0
  Max PV                0
  Cur PV                2
  Act PV                2
  VG Size               47.49 GiB
  Total PE              12157
  Alloc PE / Size       4031 / 15.75 GiB
  Free  PE / Size       8126 / 31.74 GiB
  VG UUID               YLT1Ys-31Dj-dNlc-un7E-RJDb-delq-8FCw8h

Die auf dem alten Physical Volume befindlichen Dateisysteme ziehen wir nicht von Hand um. Stattdessen weisen wir LVM an, die belegten Physical Extents zu bewegen. Damit sind die Dateisysteme effektiv auf das neue, verschlüsselte Physical Volume umgezogen, so dass wir das alte aus der Volume Group entfernen können.

root@sysresccd /root % pvmove /dev/sda5 /dev/mapper/sdb5_crypt 
  /dev/sda5: Moved: 0.0%
  /dev/sda5: Moved: 6.4%
  /dev/sda5: Moved: 13.1%
  …
  /dev/sda5: Moved: 100.0%

Das alte Physical Volume entfernen wir aus der Volume Group.

root@sysresccd /root % vgreduce demo-vg /dev/sda5
  Removed "/dev/sda5" from volume group "demo-vg"
root@sysresccd /root % vgdisplay 
  --- Volume group ---
  VG Name               demo-vg
  System ID             
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  12
  VG Access             read/write
  VG Status             resizable
  MAX LV                0
  Cur LV                3
  Open LV               0
  Max PV                0
  Cur PV                1
  Act PV                1
  VG Size               31.74 GiB
  PE Size               4.00 MiB
  Total PE              8126
  Alloc PE / Size       4031 / 15.75 GiB
  Free  PE / Size       4095 / 16.00 GiB
  VG UUID               YLT1Ys-31Dj-dNlc-un7E-RJDb-delq-8FCw8h

/boot umziehen und System bootbar machen

/boot müssen wir von Hand umziehen und zudem GRUB überarbeiten, so dass er die Verschlüsselung berücksichtigt. Das geht eins Stück weit genau so wie beim Umzug auf LVM. Als erstes erzeugen wir ein Dateisystem auf /boot und notieren uns die UUID.

root@sysresccd /root % mkfs -t ext2 /dev/sdb1
mke2fs 1.43.6 (29-Aug-2017)
Creating filesystem with 262144 1k blocks and 65536 inodes
Filesystem UUID: a200f234-8ae1-4efb-a4e6-6c8a1722b08d
Superblock backups stored on blocks: 
	8193, 24577, 40961, 57345, 73729, 204801, 221185

Allocating group tables: done                            
Writing inode tables: done                            
Writing superblocks and filesystem accounting information: done 

Jetzt erzeugen wir Mountpoints und mounten das Wurzeldateisystem sowie das alte /boot. /home brauchen wir nicht und mounten es daher nicht.

root@sysresccd /root % mkdir /mnt/alt
root@sysresccd /root % mkdir /mnt/neu
root@sysresccd /root % mount -o ro /dev/sda1 /mnt/alt 
root@sysresccd /root % mount /dev/demo-vg/root /mnt/neu 
root@sysresccd /root % mount /dev/sdb1 /mnt/neu/boot

Wir kopieren /boot:

root@sysresccd /root % rsync -a /mnt/alt/ /mnt/neu/boot/

Die UUID des neuen /boot wird in die /etc/fstab eingetragen.

root@sysresccd /root % nano /mnt/neu/etc/fstab 

# <file system> <mount point>   <type>  <options>	<dump>  <pass>
/dev/demo-vg/root /             ext4    errors=remount-ro 0	  1
/dev/demo-vg/swap_1 none        swap    sw              0	0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0
UUID=a200f234-8ae1-4efb-a4e6-6c8a1722b08d /boot           ext2    defaults     $
/dev/demo-vg/home /home         ext4    defaults        0	2

Außerdem tragen wir die UUID des Geräts /dev/sdb5 – also des Geräts, das entschlüsselt werden muss – in die /etc/crypttab ein.

root@sysresccd /root % nano /mnt/neu/etc/crypttab

sda5_crypt UUID=46acca33-6876-4fe5-8af0-97075e890ad4 none luks

Falls es sich um eine SSD handelt und man unbenutzte Bereiche freigeben möchte (trim/discard), dann trägt man

sda5_crypt UUID=46acca33-6876-4fe5-8af0-97075e890ad4 none luks,discard

ein. Das schwächt die Verschlüsselung in einem Ausmaß, das zumindest für mich vertretbar ist. Daher will ich an dieser Stelle nicht weiter darauf eingehen.

Jetzt chrooten wir in das System, erzeugen ein neues initramfs und installieren GRUB neu. Das alte /boot hängen wir zuvor aus, damit GRUB es nicht erkennt. perl beschwert sich über fehlende locales, was wir ignorieren können.

root@sysresccd /root % umount /mnt/alt 
root@sysresccd /root % mount -o bind /dev /mnt/neu/dev 
root@sysresccd /root % mount -o bind /proc /mnt/neu/proc
root@sysresccd /root % mount -o bind /sys /mnt/neu/sys  
root@sysresccd /root % chroot /mnt/neu /bin/bash
root@sysresccd:/# update-initramfs -u -k all
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LC_CTYPE = "de_DE.UTF-8",
	LC_COLLATE = "de_DE.UTF-8",
	LC_MESSAGES = "de_DE.UTF-8",
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
update-initramfs: Generating /boot/initrd.img-4.9.0-4-amd64
perl: warning: Setting locale failed.
perl: warning: Please check that your locale settings:
	LANGUAGE = (unset),
	LC_ALL = (unset),
	LC_CTYPE = "de_DE.UTF-8",
	LC_COLLATE = "de_DE.UTF-8",
	LC_MESSAGES = "de_DE.UTF-8",
	LANG = "en_US.UTF-8"
    are supported and installed on your system.
perl: warning: Falling back to the standard locale ("C").
root@sysresccd:/# update-grub
Generating grub configuration file ...
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
Found linux image: /boot/vmlinuz-4.9.0-4-amd64
Found initrd image: /boot/initrd.img-4.9.0-4-amd64
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
  WARNING: Failed to connect to lvmetad. Falling back to device scanning.
done
root@sysresccd:/# grub-install /dev/sdb
Installing for i386-pc platform.
Installation finished. No error reported.

Nun fahren wir das System herunter, bauen die alte Platte aus und booten von der neuen. Beim Starten fragt das System nach der Passphrase und booten anschließend weiter. Von der Verschlüsselung merkt man nichts, da weiterhin die LVM-Devices angesprochen werden.

jan@demo:~$ df -h
Dateisystem               Größe Benutzt Verf. Verw% Eingehängt auf
udev                       487M       0  487M    0% /dev
tmpfs                      100M    1,8M   98M    2% /run
/dev/mapper/demo--vg-root  6,6G    948M  5,3G   15% /
tmpfs                      499M     72K  499M    1% /dev/shm
tmpfs                      5,0M       0  5,0M    0% /run/lock
tmpfs                      499M       0  499M    0% /sys/fs/cgroup
/dev/sda1                  248M     38M  198M   16% /boot
/dev/mapper/demo--vg-home  7,9G     37M  7,4G    1% /home
tmpfs                      100M       0  100M    0% /run/user/1000

Allerdings ist /home noch immer 8 GB groß, obwohl die neue Platte viel größer ist. Was ist passiert? Wir haben das zugehörige Physical Device nicht in der Größe verändert. In der Volume Group gibt es freie Physical Extents:

jan@demo:~$ su -c 'vgdisplay'
Passwort:
  --- Volume group ---
  VG Name               demo-vg
  …
  Alloc PE / Size       4031 / 15,75 GiB
  Free  PE / Size       4095 / 16,00 GiB
  VG UUID               YLT1Ys-31Dj-dNlc-un7E-RJDb-delq-8FCw8h

/home nachträglich vergrößern

Wir booten wieder einmal von der SystemRescueCD und vergrößern /home. Im Schweinsgalopp:

root@sysresccd /root % cryptsetup luksOpen /dev/sda5 sda5_crypt
Enter passphrase for /dev/sda5: 
root@sysresccd /root % vgchange -a y demo-vg
  3 logical volume(s) in volume group "demo-vg" now active
root@sysresccd /root % lvresize -l 100%FREE -r /dev/demo-vg/home 
fsck from util-linux 2.28.2
/dev/mapper/demo--vg-home: 37/524288 files (0.0% non-contiguous), 58530/2097152 blocks
  Size of logical volume demo-vg/home changed from 8.00 GiB (2048 extents) to 24.00 GiB (6143 extents).
  Logical volume home successfully resized.
resize2fs 1.43.6 (29-Aug-2017)
Resizing the filesystem on /dev/mapper/demo--vg-home to 6290432 (4k) blocks.
The filesystem on /dev/mapper/demo--vg-home is now 6290432 (4k) blocks long.

Gegenprüfung nach Neustart:

jan@demo:~$ df -h
Dateisystem               Größe Benutzt Verf. Verw% Eingehängt auf
udev                       487M       0  487M    0% /dev
tmpfs                      100M    1,8M   98M    2% /run
/dev/mapper/demo--vg-root  6,6G    948M  5,3G   15% /
tmpfs                      499M     72K  499M    1% /dev/shm
tmpfs                      5,0M       0  5,0M    0% /run/lock
tmpfs                      499M       0  499M    0% /sys/fs/cgroup
/dev/sda1                  248M     38M  198M   16% /boot
/dev/mapper/demo--vg-home   24G     44M   23G    1% /home
tmpfs                      100M       0  100M    0% /run/user/1000

Da es sich hier um /home gehandelt hat, hätte man alternativ auch Debian im Recovery Mode booten können, anstelle die SystemRescueCD zu verwenden.

Fehlersuche

Bootvorgang dauert lange nach Umstellung auf LVM

Wenn der Bootvorgang hängt und schließlich mit „Gave up waiting for suspend/resume device“ fortgesetzt wird, dann ist in der etc/initramfs/conf.d/resume das falsche Gerät eingetragen und/oder das initramfs nicht neu erzeugt worden. Siehe oben unter „Umzug auf eine neue Festplatte und Einrichten von LVM“.

System bootet nicht

Das System kann nach Umstellung auf (verschlüsseltes) LVM nicht booten, Fehlersymptome sind möglicherweise

  • Endlosschleife „volume group not found“
  • schwarzer Bildschirm
  • Fehlermeldung „Sie müssen zuerst den Kernel laden“

dann sollte geprüft werden, ob Debianpackage.png lvm2 und bei verschlüsseltem LVM Debianpackage.png cryptsetup installiert sind. Dazu via SystemRescueCD in das installierte System chrooten, die Installation fehlender Pakete nachholen und das initramfs neu erzeugen. Bei verschlüsseltem LVM muss zusätzlich die /etc/crypttab gepflegt werden.

Kein Bootloader

Falls vergessen wurde, GRUB zu installieren oder dieser versehentlich auf der falschen (alten) Platte installiert wurde, dann kann dessen Installation über SystemRescueCD nachgeholt werden, siehe oben. Alternativ kann man GRUB auch wie in Grub reparieren beschrieben neu installieren.