KVM: fsck direkt auf dem KVM-Host zu Gast-Filesystemen in LUKS-verschlüsselten LVM-Volumes – Unterschiede zwischen Raw Devices und qcow2-Image-Files

Ich betreibe bestimmte Linux-Systeme als KVM-Gäste mit verschlüsseltem Plattenunterbau. Die Partitionen des KVM-Hosts selbst sind zwar auch verschlüsselt; in diesem Artikel betrachte ich aber verschlüsselte virtuelle Disks für KVM-Gastsysteme. Ich nutze hierfür auf dem KVM-Host definierte LVM-Volumes, die mit dm-crypt/LUKS verschlüsselt wurden.

Dabei setze ich regelmäßig zwei Varianten ein:

  • Variante 1: Ein oder mehrere verschlüsselte LVM-Volumes werden dem Gastsystem (in entschlüsseltem Zustand) als "Raw-Devices" zur Verfügung gestellt. Das Gastsystem erstellt dort seine Partitionen (oder im Einzelfall auch eigene LVM-Volumes) mit je einem Linux-Filesystem.
  • Variante 2: Verschlüsselte LVM-Volumes des Hosts enthalten qcow2-Container-Dateien, die vom KVM-Gast als virtuelle Disks genutzt werden. Im qcow2-Container legt der Gast dann eigene LVM-Volumes mit einem Linux-Filesystem an.

Für regelmäßige fsck-Checks der Filesysteme im KVM-Gast kann man einerseits dadurch sorgen, dass man entsprechende Einstellungen für das Gast-Filesystem selbst vornimmt. So kann man mit "tune2fs" den sog. "maximum mount count" auf eine hinreichend kleine Anzahl von Mounts stellen. Das empfiehlt sich vor allem beim root-Filesystem des Gastes: Das darf ja bei der Durchführung von fsck nicht gemountet sein - dies erfordert ansonsten Kunstgriffe, wenn man im bootenden KVM-Gast vor dem Mounten des root-Filesystems fsck erzwingen will.

Manchmal möchte man im Rahmen automatisierter Maintenance-Verfahren aber auch direkt vom KVM-Host aus Filesystem-Checks mit fsck für die Filesystem der KVM-Gäste durchführen. Natürlich ohne das Gastsystem hochzufahren. Wie macht man das im Fall der genannten zwei Varianten?

fsck in Variante 1 - LVM-Volume als verschlüsseltes Raw-Device des Gastes

Variante 1 weist folgende Schichtung bzgl. der physikalischen und virtuellen Disks auf:

  • Physikalische Plattenpartitionen für Raid   >>  
  • Raid 10   >>  
  • LVM   >>  
  • LVM-Groups und LVM-Volumes, die der Host nutzen kann   >>  
  • dm-crypt/LUKS-Verschlüsselung eines (oder mehrerer) von LVM-Volumes, die den Gästen as Raw-Devices bereitgestellt werden.   >>  
  • KVM/QEMU- und Gastsystem mit Zugriff auf das Raw-Volume als virtuelle Platte   >>  
  • Partitionen (oder LVM-Volumes) im Gastsystem   >>  
  • ext4-Filesysteme im Gastsystem

Hier führt der Weg über die Anwendung von "cryptsetup" und z.B. das Tool "kpartx" (das man natürlich installiert haben muss). Wir führen alle Operation natürlich nur dann durch, wenn das KVM-Gastsystem selbst nicht läuft. Wir müssen vermeiden, dass auf die Partitionen des Gastes von mehreren Betriebssystemen aus (Host und Gast) gleichzeitig schreibend zugegriffen wird.

Ich gehe in unserem Beispiel mal davon aus, dass die Entschlüsselung des betreffenden LVM-Volumes für den Gast auf dem KVM-Host noch nicht vorgenommen wurde. Dieses Volume liege in einer logischen Volume Group "lvg2" und habe die Bezeichnung "lvhd0".

Das Kommando "la" ist in folgendem Beispiel ein Alias für 'ls -la'; alle Kommandos werden direkt auf dem Host ausgeführt. Das jeweilige KVM-Gastsystem ist nicht hochgefahren. Unter dem Verzeichnis "/dev/mapper" finden wir dann bei aktivierten Volume-Groups auf dem KVM-Host etwa folgenden Eintrag vor;

mytux:~ # la /dev/mapper
total 0
drwxr-xr-x  2 root root     340 Aug  4 09:46 .
drwxr-xr-x 22 root root    9720 Aug  4 09:50 ..
crw-------  1 root root 10, 236 Aug  4 09:41 control
... 
lrwxrwxrwx  1 root root       8 Aug  4 09:46 lvg2-lvhd0 -> ../dm-11
...                                                                    

Zunächst müssen wir dieses Volume entschlüsseln:

mytux:~ # cryptsetup open /dev/mapper/lvg2-lvhd0  cr_hd0
Enter passphrase for /dev/mapper/lvg2-lvhd0: 

mytux:~ # la /dev/mapper
total 0
drwxr-xr-x  2 root root     340 Aug  4 09:46 .
drwxr-xr-x 22 root root    9720 Aug  4 09:50 ..
crw-------  1 root root 10, 236 Aug  4 09:41 control
lrwxrwxrwx  1 root root       8 Aug  4 09:46 cr_hd0 -> ../dm-16
...
lrwxrwxrwx  1 root root       8 Aug  4 09:46 lvg2-lvhd0 -> ../dm-11
...                                                                    

Ok. Der Befehl "qemu-img" informiert uns darüber, dass wir es tatsächlich mit einem Raw-Device (von 100GB Größe) zu tun haben:

 
mytux:~ # qemu-img info /dev/mapper/cr_hd0
image: /dev/mapper/cr_hd0
file format: raw
virtual size: 100G (107372085248 bytes)
disk size: 0

Infos zur Partitionierung des "Raw Devices"
In unserem Beispiel befinden sich auf dem entschlüsselten LVM-Volume des Hosts zwei Partitionen des Gastes: eine swap-Partition und eine Partition mit einem ext4-Filesystem. Es gibt mehrere Tools, mit denen man die Partitionsstruktur unterhalb eines Raw-Devices für einen KVM-Gast auf dem Host selbst untersuchen kann:
"fdisk", "parted", "virt-filesystems" und eben auch "kpartx":

 
mytux:~ # fdisk -l /dev/mapper/cr_hd0
Disk /dev/mapper/cr_imap: 100 GiB, 107372085248 bytes, 209711104 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: 0x00041fe1

Device                    Boot   Start       End   Sectors  Size Id Type
/dev/mapper/cr_hd0-part1         2048   3067903   3065856  1.5G 82 Linux swap / Solaris
/dev/mapper/cr_hd0-part2 *    3067904 167772159 164704256 78.6G 83 Linux

mytux:~ # parted /dev/mapper/cr_hd0 unit s print
Model: Linux device-mapper (crypt) (dm)
Disk /dev/mapper/cr_hd0: 209711104s
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start     End         Size        Type     File system     Flags
 1      2048s     3067903s    3065856s    primary  linux-swap(v1)  type=82
 2      3067904s  167772159s  164704256s  primary  ext4            boot, type=83
 
mytux:~ # virt-filesystems -a /dev/mapper/cr_hd0 --extra
/dev/sda1
/dev/sda2
mytux:~ # virt-filesystems -a /dev/mapper/cr_hd0 --extra -l
Name       Type        VFS   Label  Size         Parent
/dev/sda1  filesystem  swap  -      1569718272   -
/dev/sda2  filesystem  ext4  -      84328579072  -
 
mytux:~ # kpartx -l /dev/mapper/cr_hd0 
cr_hd01 : 0 3065856 /dev/mapper/cr_hd0 2048
cr_hd02 : 0 164704256 /dev/mapper/cr_hd0 3067904

Hinweis:

kpartx liefert Infos zur Partionierung (samt Offests) auch für Disk-Image-Files im "Raw"-Format. kpartx funktioniert jedoch nicht für Disk-Image-Files im qcow2-Format!

Mit Ausnahme von "virt-filesystems" stellen uns alle oben vorgestellten Tools auch Offset-Informationen zur Verfügung:
Die Angaben 2048(s) und 3067904(s) entsprechen Offset-Adressen der Partitionen; wir müssen die Zahl der Sektoren allerdings noch mit der Anzahl der Bytes (512) multiplizieren: also z.B. 2048 * 512 ist der Offset für die erste (swap-) Partition.

Man könnte zur Partitionsbestimmmung auch "guestfish" und die zu guestfish gehörigen Sub-Kommandos run und list-filesystems oder aber auch das Tool "qemu-nbd" heranziehen. "qemu-nbd" diskutiere ich gleich im Detail anhand der Variante 2.

Partitionen des Raw-LVM-Volumes (= Raw-Device für das KVM-Gastsytem )ansprechen
"kpartx -a" liefert uns für Devices im Raw-Format eine einfache Möglichkeit, die darin liegenden Partitionen anzusprechen.

mytux:~ # kpartx -a /dev/mapper/cr_hd0
mytux:~ # la /dev/mapper
total 0
drwxr-xr-x  2 root root     420 Aug  6 14:36 .
drwxr-xr-x 22 root root    9740 Aug  6 14:36 ..
crw-------  1 root root 10, 236 Aug  6 08:26 control
lrwxrwxrwx  1 root root       8 Aug  6 14:32 cr_hd0 -> ../dm-16
lrwxrwxrwx  1 root root       8 Aug  6 14:36 cr_hd01 -> ../dm-17
lrwxrwxrwx  1 root root       8 Aug  6 14:36 cr_hd02 -> ../dm-18
lrwxrwxrwx  1 root root       8 Aug  6 14:36 cr_hd0_part1 -> ../dm-17
lrwxrwxrwx  1 root root       8 Aug  6 14:36 cr_hd0_part2 -> ../dm-18
....
lrwxrwxrwx  1 root root       7 Aug  6 08:55 lvg2-lvhd0 -> ../dm-11
...
mytux:~ # 

Man beachte die unterschiedliche Bezeichnung, die auf das gleiche Device verlinken. Wir wissen bereits, dass die zweite Partition ein ext4-Filesystem des KVM-Gastes enthält. Also

mytux:~ # fsck -f /dev/mapper/cr_hd02
fsck from util-linux 2.29.2
e2fsck 1.42.11 (09-Jul-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/cr_hd02: 1016912/5152768 files (0.1% non-contiguous), 6724050/20588032 blocks
mytux:~ # 

Anschließend können wir das Mapping durch "kpartx -d" wieder rückgängig machen:

mytux:~ # kpartx -d /dev/mapper/cr_hd0
mytux:~ # la /dev/mapper
total 0
drwxr-xr-x  2 root root     340 Aug  6 14:45 .
drwxr-xr-x 22 root root    9700 Aug  6 14:45 ..
crw-------  1 root root 10, 236 Aug  6 08:26 control
lrwxrwxrwx  1 root root       8 Aug  6 14:32 cr_hd0 -> ../dm-16
...
lrwxrwxrwx  1 root root       7 Aug  6 08:55 lvg2-lvhd0 -> ../dm-11 
mytux:~ # 

Was tun, wenn das Gastsystem auch selbst LVM nutzt?
In unserem Fall lag im Gastsystem selbst keine LVM-Struktur vor. Hätten wir das gehabt, hätten wir noch zwei weitere Schritte vornehmen müssen - nämlich "vgscan", "vgchange -ay". Erst danach hätten wir "fsck" ausführen können. Wir werden dies weiter unten bei der Diskussion der Variante 2 sehen.

Arbeit über Loop-Devices
Der Vollständigkeit halber zeige ich kurz noch, wie man Partitionen von KVM-RAW-Devices über ihre Offsets auch als Loop-Devices ansprechen kann. Die zweite Partition hat in unserem Beispiel einen Offset von 3067904 * 512 = 1570766848 Bytes.

Also:

mytux:~ # losetup -r -o 1570766848  /dev/loop3 /dev/mapper/cr_hd0
mytux:~ # fsck -f /dev/loop3
fsck from util-linux 2.29.2
e2fsck 1.42.11 (09-Jul-2014)
fsck.ext4: Operation not permitted while trying to open /dev/loop3
You must have r/w access to the filesystem or be root
mytux:~ # losetup -d  /dev/loop3 
mytux:~ # losetup  -o 1570766848  /dev/loop3 /dev/mapper/cr_hd0  
mytux:~ # fsck -f /dev/loop3     
fsck from util-linux 2.29.2
e2fsck 1.42.11 (09-Jul-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/loop3: 1016912/5152768 files (0.1% non-contiguous), 6724050/20588032 blocks
mytux:~ # 
mytux:~ # tune2fs -l /dev/loop3
tune2fs 1.42.11 (09-Jul-2014)
Filesystem volume name:   <none>
Last mounted on:          /
Filesystem UUID:          4388dd4b-ac1a-5c9c-b8d6-88e53b12bd2d
Filesystem magic number:  0xEF53
Filesystem revision #:    1 (dynamic)
Filesystem features:      has_journal ext_attr resize_inode dir_index filetype extent flex_bg sparse_super large_file huge_file uninit_bg dir_nlink extra_isize
Filesystem flags:         signed_directory_hash 
Default mount options:    user_xattr acl
Filesystem state:         clean
Errors behavior:          Continue
Filesystem OS type:       Linux
Inode count:              5152768
Block count:              20588032
Reserved block count:     267644
Free blocks:              13863982
Free inodes:              4135856
First block:              0
Block size:               4096
Fragment size:            4096
Reserved GDT blocks:      1019
Blocks per group:         32768
Fragments per group:      32768
Inodes per group:         8192
Inode blocks per group:   512
Flex block group size:    16
Filesystem created:       Mon Jan  6 15:44:37 2014
Last mount time:          Mon Aug  6 08:56:27 2018
Last write time:          Mon Aug  6 15:01:58 2018
Mount count:              0
Maximum mount count:      2
Last checked:             Mon Aug  6 15:01:58 2018
Check interval:           172800 (2 days)
Next check after:         Wed Aug  8 15:01:58 2018
Lifetime writes:          2270 GB
Reserved blocks uid:      0 (user root)
Reserved blocks gid:      0 (group root)
First inode:              11
Inode size:               256
Required extra isize:     28
Desired extra isize:      28
Journal inode:            8
Default directory hash:   half_md4
Directory Hash Seed:      ce2daf83-bc25-44d5-fcdf-b35afd5c8f2b
Journal backup:           inode blocks
mytux:~ # 
mytux:~ # losetup -d  /dev/loop3

Der Leser sieht, dass ich in der letzten Befehlssequenz anfänglich aus lauter guter Gewohnheit das Device nur im read-only modus als Loop-Device angelegt hatte. Erst nach einer Korrektur läuft dann fsck. Natürlich kann man dann z.B. auch tune2fs auf das Loop-Device anwenden. Über Loop-Devices geht es also auch. Man muss dann halt nur die Offsets wissen!

fsck in Variante 2 - verschlüsseltes LVM-Volume mit Disk-Image-File im "qcow2"-Format

In diesem Szenario liegt eine wirklich komplexe Schichtung vor:

KVM-Host -> LVM-Volume-Group -> Luks-verschlüsseltes LVM-Volume -> qcow2-Image-File -> Partitions- und LVM-Struktur des KVM-Gastsystems -> Volumegroup mit LVM-Volume des Gastes -> ext4-Filesystem

In diesem Szenario wirken sich vor allem zwei bedeutsame Unterschiede zur Variante 1 aus:

  • Unser Disk-Image-File (eine Art Container-File; "os43.qcow2") hat kein Raw-Format - daran scheitert u.a. "kpartx -a".
  • In dem Container-File befindet sich eine Partition, mittels derer das Gastsystem eine LVM-Logical-Volume-Group "lvg1" samt einem Logical Volume "lvroot" angelegt hat.

Zum ersten Problem:
Es ist hier zu bedenken, dass wir das zu prüfende Filesystem ja nicht auf dem Host mounten wollen. Das einzige mir bekannte Programm, das uns den Inhalt (also die Partitionen) des qcow2-Files samt Offsets bedarfsgerecht zur Verfügung stellt, ist <strong>qemu-nbd</strong>. Bedarfsgerecht heißt hier, dass Physical Volumes (Partitione) des Gastes anschließend auf dem KVM-Host in Form von Loop-Devices weiter genutzt werden können. Das ermöglicht es uns dann, die LVM Volume-Group und die LVM-Volumes innerhalb des qcow2-Files anzusprechen und "fsck -f" auszuführen.

Hinweis:

Es gibt zwar eine Möglichkeit eine Standardvariante von fsck innerhalb des Kommandos "guestfish" aus der libguestfs-Suite anzuwenden (s.u.); "fsck -f" geht damit aber nicht.

Zum zweiten Problem:
Neben der Aufdröselung der Partitionsstruktur (samt Offsets) im qcow2-File mit seinem komplexen Format, müssen geeignete Tools auf dem Host auch noch die interne LVM-Struktur erkennen und zu aktivieren. Wir werden hierfür das Gespann "vgscan und "vgchange" einsetzen.

Entschlüsselung und Mounten des LVM-Volumes des Hosts
Alle nachfolgenden Kommandos werden wieder direkt auf dem KVM-Host ausgeführt. Zunächst müssen wir wie in Variante 1 das passende LVM-Volume des KVM-Hosts entschlüsseln. Wir müssen das dekryptierte Device anschließend aber auch noch an geeigneter Stelle des Hosts mounten, um das dort enthaltene Disk-Image-File ansprechen zu können:

mxtux:~ # cryptsetup open /dev/mapper/volssd10-kvmos  cr_kvmos
Enter passphrase for /dev/mapper/volssd10-kvmos:
mxtux:~ # 
mxtux:~ # la /dev/mapper
total 0
drwxr-xr-x  2 root root     420 Aug  6 11:52 .
drwxr-xr-x 27 root root   12300 Aug  6 11:52 ..
crw-------  1 root root 10, 236 Aug  6 08:49 control
lrwxrwxrwx  1 root root       8 Aug  6 11:48 cr_kvmos -> ../dm-16
...
lrwxrwxrwx  1 root root       7 Aug  6 11:48 volssd10-kvmos -> ../dm-6
...  
mxtux:~ # 
mount /dev/mapper/cr_kvmos /kvm/os                                                                  
mxtux:~ # 

Informationen zum Partitionsaufbau innerhalb des qcow2-Image-Files:
Während kpartx keine ausreichenden Informationen liefert, ermöglicht uns das Kommando "virt-filesystems" aus der libguestfs-Suite (bei Bedarf installieren!) einen Einblick in die Unterteilung des qcow2-Image-Files "os43.qcow2":

mytux:~ # virt-filesystems  -a  /kvm/os/os43.qcow2 --extra -l 
Name              Type        VFS   Label  Size        Parent
/dev/sda1         filesystem  swap  -      2153775104  -
/dev/lvg1/lvroot  filesystem  ext4  -      8589934592  -

Netterweise erkennt "virt-filesystems" sogar die LVM-Volume-Group "lvg1" und das Volume "lvroot" ! Wir könnten dieses logische Volume des Gastes nun sogar mittels des Kommandos "guestmount" (ebenfalls Teil der libguestfs) auf dem Host mounten und mit den Inhalten arbeiten:

mytux:~ # guestmount -a /kvm/os/os43.qcow2 -m /dev/lvg1/lvroot --ro /mnt2
mytux:~ # la /mnt2
total 136
drwxr-xr-x  23 root root   4096 Jun  7 18:27 .
drwxr-xr-x  40 root root   4096 Jul 25 18:55 ..
drwxr-xr-x   2 root root   4096 May 14 19:20 bin
drwxr-xr-x   3 root root   4096 May 14 19:22 boot
drwxr-xr-x   2 root root   4096 May 14 17:09 dev
drwxr-xr-x 128 root root  12288 Aug  4 11:41 etc
drwxr-xr-x   3 rmu  users  4096 May 28 17:43 extras
drwxr-xr-x   4 root root   4096 May 15 20:29 home
drwxr-xr-x  12 root root   4096 May 14 19:20 lib
drwxr-xr-x   7 root root  12288 May 14 19:21 lib64
drwx------   2 root root  16384 May 14 17:09 lost+found
drwxr-xr-x   2 root root   4096 May 10  2017 mnt
drwxr-xr-x   2 root root   4096 May 10  2017 opt
drwxr-xr-x   2 root root   4096 May 14 17:09 proc
drwx------   9 root root   4096 Jun 12 21:52 root
drwxr-xr-x   2 root root   4096 May 14 17:09 run
drwxr-xr-x   2 root root  12288 May 14 21:12 sbin
drwxr-xr-x   2 root root   4096 May 10  2017 selinux
drwxr-xr-x   5 root root   4096 May 14 17:12 srv
drwxr-xr-x   2 root root   4096 May 14 17:09 sys
drwxrwxrwt  26 root root  12288 Aug  4 11:41 tmp
drwxr-xr-x  13 root root   4096 May 14 17:10 usr
drwxr-xr-x  12 root root   4096 May 14 17:24 var
mytux:~ # umount /mnt2

Leider bringt uns das hinsichtlich des angestrebten "fsck" aber gar nichts.

Einsatz von "qemu-nbd"
Im Gegensatz zu RAW-Devices oder Raw-Image-Files kommen wir an dieser Stelle nicht um den Einsatz von des qemu-eigenen Kommandos "qemu-nbd" herum. Also:

mxtux:~ # modprobe nbd max_part=8
mxtux:~ # qemu-nbd --connect=/dev/nbd0 /kvm/os/os43.qcow2 
mxtux:~ # la /dev/ | grep nbd0
brw-rw----   1 root disk       43,   0 Aug  6 16:22 nbd0
brw-rw----   1 root disk       43,   1 Aug  6 16:22 nbd0p1
brw-rw----   1 root disk       43,   2 Aug  6 16:22 nbd0p2

Was verbirgt sich hinter diesen neuen Devices dahinter?

mxtux:~ # fdisk -l /dev/nbd0
Disk /dev/nbd0: 15 GiB, 16106127360 bytes, 31457280 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: 0x000392a8

Device      Boot   Start      End  Sectors Size Id Type
/dev/nbd0p1         2048  4208639  4206592   2G 82 Linux swap / Solaris
/dev/nbd0p2 *    4208640 31457279 27248640  13G 8e Linux LVM

Aha, fdisk erkennt, dass die zweite Partition LVM nutzt. Wie kommen wir nun weiter? "kpartx" führt uns nicht zum Ziel, da LVM Volume Groups erst aktiviert werden müssen. Hierzu sind zwei Schritte nötig

  • Schritt 1: Wir müssen uns das LVM-Device des qcow2-Files auf dem Host zugänglich machen - als Loop-Device. Dazu berechnen wir dessen Offset ( = 4208640 * 512 = 2154823680)
  • Schritt 2: Wir müssen wir auf dem KVM-Host das Kommando "vgscan" ausführen und danach die gewünschten Volume Group mit "vgchange" aktivieren

Also:

mxtux:~ # vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "volssd10" using metadata type lvm2
  Found volume group "lvgssd5" using metadata type lvm2
  Found volume group "lvg2" using metadata type lvm2
  Found volume group "lvg10f2" using metadata type lvm2
  Found volume group "volgrp1" using metadata type lvm2

mxtux:~ # losetup -o 2154823680 /dev/loop5 /dev/nbd0

mxtux:~ # vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "lvg1" using metadata type lvm2
  Found volume group "volssd10" using metadata type lvm2
  Found volume group "lvgssd5" using metadata type lvm2
  Found volume group "lvg2" using metadata type lvm2
  Found volume group "lvg10f2" using metadata type lvm2
  Found volume group "volgrp1" using metadata type lvm2
mxtux:~ # 

Aha, vgscan erkennt eine neue Volume-Group "lvg1". Wir sehen hier übrigens, dass es sich lohnt, die Bezeichnungen von Groups auf dem Host und den Gastsystemen unterschiedlich und global eindeutig zu wählen - etwas, das ich hier zu meiner Schande versäumt habe. Nun müssen wir die Volume Group noch aktivieren:

mxtux:~ # vgchange -ay lvg1
  1 logical volume(s) in volume group "lvg1" now active
mxtux:~ #
mxtux:~ # la /dev/mapper
total 0
drwxr-xr-x  2 root root     460 Aug  6 16:44 .
drwxr-xr-x 28 root root   12880 Aug  6 16:44 ..
crw-------  1 root root 10, 236 Aug  6 08:49 control
lrwxrwxrwx  1 root root       8 Aug  6 11:48 cr_kvmos -> ../dm-16
...
lrwxrwxrwx  1 root root       8 Aug  6 16:44 lvg1-lvroot -> ../dm-19
...
lrwxrwxrwx  1 root root       8 Aug  6 16:33 nbd0p2p1 -> ../dm-18
...

mxtux:~ # fdisk -l /dev/mapper/lvg1-lvroot
Disk /dev/mapper/lvg1-lvroot: 8 GiB, 8589934592 bytes, 16777216 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

mxtux:~ # virt-filesystems -a /dev/nbd0 --extra --parts --blkdevs --filesystems -l --lvs
Name             Type       VFS  Label MBR Size        Parent
/dev/sda1        filesystem swap -     -   2153775104  -
/dev/lvg1/lvroot filesystem ext4 -     -   8589934592  -
/dev/lvg1/lvroot lv         -    -     -   8589934592  /dev/lvg1
/dev/sda1        partition  -    -     82  2153775104  /dev/sda
/dev/sda2        partition  -    -     8e  13951303680 /dev/sda
/dev/sda         device     -    -     -   16106127360 -

Nun können wir den Filesystem-Check des LVM-Volume des KVM-Gasts, das sich m qcow2-File befindet, auf dem KVM-Host ausführen. Und danach alle Kommandos wieder rückgängig machen:

mxtux:~ # fsck -f /dev/mapper/lvg1-lvroot
fsck from util-linux 2.29.2
e2fsck 1.42.11 (09-Jul-2014)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/mapper/lvg1-lvroot: 245825/524288 files (0.1% non-contiguous), 1707336/2097152 blocks
mxtux:~ # 
mxtux:~ #  vgchange -an lvg1
  0 logical volume(s) in volume group "lvg1" now active
rux:~ # la /dev/mapper
total 0
drwxr-xr-x  2 root root     440 Aug  6 17:09 .
drwxr-xr-x 27 root root   12840 Aug  6 17:09 ..
crw-------  1 root root 10, 236 Aug  6 08:49 control
lrwxrwxrwx  1 root root       8 Aug  6 11:48 cr_kvmos -> ../dm-16
...
lrwxrwxrwx  1 root root       8 Aug  6 16:33 nbd0p2p1 -> ../dm-18
..
mxtux:~ # losetup -d /dev/loop5 
mxtux:~ # qemu-nbd -d /dev/nbd0 
/dev/nbd0 disconnected
mxtux:~ # rmmod nbd
mxtux:~ # 

Ich bitte zu beachten, dass wir in diesem Fall trotz der bereits sehr komplexen Schichtung immer noch einen Vorteil hatten: Es gab nur genau ein virtuelles LVM-Physical-Volume des Gast-Systems, nämlich die zweite Partition innerhalb des qcow2-Files. Ferner gabe es nur eine Volume-Group. Bei mehreren "Volume Groups", die sich über unetrschiedliche "Physical Volumes" aus verschiedenen virtuellen Partitionen des Gastes erstreckten, hätten wir alle zugehörigen virtuellen Partitionen auf dem Host als Loop-Devices bereitstellen müssen. Das ist uns im Beipiel erspart geblieben.

fsck in einer dritten Variante - verschlüsseltes LVM-Volume mit einem RAW Image File

Nach all dem Zirkus mit qcow2 stellt sich die Frage: Warum verwendet man nicht gleich Image-Files im Raw-Format? Das ist ein gute Frage; ich werde die Antwort aber auf einen anderen Artikel verschieben. Genannt sei nur der Vorteil des langsam auf die Maximalgröße wachsenden Platzbedarfs im Falle qcow2. Für Disk-Image-Files im Raw-Format spricht aber die Performance. Dennoch ein lapidarer Hinweise zum Einsatz von "fsck" für Partitionen in Raw-Container-Files:

Dieser Fall kann im Kern fast genauso behandelt werden kann, wie oben unter Variante 1 beschrieben. Wer so etwas testen will, kann ja mal ein qcow2-File in ein Raw-Format-File mittels des Kommandos "qemu-img convert" umwandeln (s. die entsprechende man -Seite).

Fazit und eine Alternative

"fsck" mit zugehörigen Optionen für Filesysteme anzuwenden, die sich in verschlüsselten LVM-Volumes eines KVM-Hosts befinden, ist relativ einfach, wenn das LVM-Volume dem KVM-Gast entweder direkt als Raw-Device zur Verfügung gestellt wird oder aber über ein Disk-Image-File im RAW-Format, das sich auf dem Volume befindet. Befinden sich dann unter dem Raw-Device nur gewöhnliche Partitionen kann man sich das Leben mit "kpartx" bequem machen.

Deutlich schwieriger wird die Sache aber mit qcow2-Imag-Files und/oder virtuellen Partitionen von Image-Files, die auf dem Gastsystem in dortigen LVM-Volume-Groups eingesetzt werden. Im Falle von qcow2-Files muss man zunächst zwingend das Kernel-Modul "nbd" und den "qemu-nbd"-Befehl einsetzen. LVM-Groups innerhalb vom Image-Disk-Files verlangen ferner die Bereitstellung aller entsprechenden zugehörigen virtuellen "Physical Volumes" (virtuelle Partitionen) als Loop-Devices auf dem KVM-Host. Danach sind die Befehle "vgscan" und "vgchange" anzuwenden, um schließlich unter "/dev/mapper" das logische Volume des Gastes mit seinem Filesystem zu erhalten. Erst dann kann man hierauf "fsck" anwenden. Das ist schon komplex, aber man hat am Ende die volle Kontrolle über fsck.

Wem das alles zu schwierig ist, der kann alternativ mal eine einfache Standardvariante des fsck-Befehls unter "guestfish" für Filesysteme von KVM-Gästen ausprobieren. Funktioniert für Raw-Devices und qcow2-Files!

DSGVO, Freelancer, E-Mails und Umzug KVM-virtualisierter Linux-E-Mail-Server auf verschlüsselte Platten/Partitionen – III

Das Thema der vorhergehenden Artikel dieser Serie

DSGVO, Freelancer, E-Mails und Umzug KVM-virtualisierter Linux-E-Mail-Server auf verschlüsselte Platten/Partitionen – I
DSGVO, Freelancer, E-Mails und Umzug KVM-virtualisierter Linux-E-Mail-Server auf verschlüsselte Platten/Partitionen – II

war eine allgemeine Diskussion darüber, warum man sich spätestens nach der DSGVO als Freelancer um Schutzmaßnahmen für E-Mails und um entsprechende vertragliche Vereinbarungen kümmern sollte. Eine reine Verschlüsselung von Transportwegen ist meiner Meinung nach nicht hinreichend; eine Lagerung von Mails in verschlüsselten Dateicontainern ist mit zu vielen Gefahrenpunkten verbunden. An einer Verschlüsselung von Volumes oder Partitionen der mail- und datei-verarbeitenden Systeme führt bei der Aufbewahrung von Mails und Anhängen kein Weg vorbei.

Als Freelancer steht man also womöglich vor der Aufgabe, sowohl den eigenen Mail-Server im LAN als auch Clients zur Mail- und Auftragsbearbeitung auf einen Unterbau aus verschlüsselte Partitionen umzustellen. Als Linuxer, die auf effiziente Ressourcennutzung bedacht sind, greifen wir zur Lösung auf virtualisierte Systeme zurück. Sprich: Meine Reaktion auf die von etlichen Kunden an mich gestellten pauschalen DSGVO-Anforderungen ist, die Auftragsverarbeitung für Kunden nur noch über besonders geschützte virtualisierte Systeme auf verschlüsselten Volumes durchzuführen. Der aufmerksame Leser hat sicher bemerkt, dass dieser Gedanke über die Mail-Verarbeitung hinaus weist.

Ich gehe kurz auf die Grenzen eines solchen Vorgehens ein; anschließend kümmern wir uns (endlich) um den Umzug eines bereits virtualisierten Mailservers auf eine verschlüsselte HD/SSD-Plattform.

Ist Volume- und Partitionsverschlüsselung einer Systeminstallation für Datensicherheit hinreichend?

Der Grundgedanke einer Partitions- oder Volume-Verschlüsselung ist: Nur verschlüsselte Daten sollen über verschiedene Zugriffsschichten Plattencontroller und Magnet- wie Flash-Speicher erreichen; eine vollständige Entschlüsselung von Dateien soll ausschließlich im RAM des Betriebssystems [OS] stattfinden. So schön das sein mag - es hilft nicht, wenn sich jemand bereits unbefugt auf dem System eingenistet hat und munter mitliest:

Die Verschlüsselung von Datenträgern, Partitionen oder Volumes bietet keinen Schutz auf gehackten Systemen. Sie bietet "nur" Schutz gegen unbefugten Zugriff im nicht-entschlüsseltem und/oder nicht-gemountetem Zustand der Volumes also z.B. im heruntergefahrenen Zustand des Systems.

Volume-Verschlüsselung ist also nur eine - wenn auch eine wichtige Maßnahme - zur Ausschaltung bestimmter Risiken. Auch das sollte aus meiner Sicht in einem Vertrag mit einem Auftraggeber festgehalten werden. Natürlich muss man sich u.a. auch um die Integrität der Virtualisierungshosts selbst kümmern - wir reden da aber über Systeme mit einer sehr begrenzten Anzahl an OS-Komponenten, die selbst keine direkte Verbindung zum Internet aufnehmen müssen.

Man erkennt, dass ein vernünftiger DSGVO-bezogener Vertrag zum Schutz personenbezogener und anderer geheim zu haltender Daten im Endeffekt wesentlich mehr beinhalten muss als nur Hinweise auf die Mailbehandlung und zugehörige Krypto-Verfahren für Transport und Lagerung. U.a. wird man eine Begrenzung ein- und aus-gehender Kommunikation von (virtualisierten) Servern und Clients, die bei der Auftragsbearbeitung eingesetzt werden, auf nur sehr wenige erlaubte Adressen im Internet umsetzen müssen. Z.B. gilt: Völlig offene HTTP(S)- / SMTP(S) - / IMAP(S)- oder gar UDP-basierte Kanäle nach außen zu beliebigen Zieladressen sind im Zeitalter von strafbewehrten DSGVO-Verträgen überhaupt keine gute Idee! Zumindest nicht auf denjenigen Server- und Client-Systemen, auf denen man mit geheim zu haltenden Informationen operiert.

Virtuelle KVM/QEMU-Systeme auf verschlüsselten Volumes

Will man aus anderen grundlegenden Risikoerwägungen heraus nicht gleich alle "Volumes" auf allen Systemen im Haus-/Firmen-Netz verschlüsseln, bleibt nur der Weg über virtuelle Maschinen. Das betrifft dann Server- wie Client-Systeme gleichermaßen.

Im Besonderen Linux-E-Mail-Server sind dabei recht komplexe Systeme; eine Neuinstallation der vielen Einzel-Komponenten auf verschlüsselten Platten/Partitionen mag man sich daher wirklich ersparen. Es geht somit um System-Migration. Nachfolgend betrachte ich deshalb den Umzug eines (virtuellen) (E-Mail-) Servers auf einem KVM/QEMU-Host von unverschlüsselten Partitionen/Volumes auf verschlüsselte Volumes.

Ich gebe einige wichtige Befehle am Beispiel eines KVM/QEMU-Hosts unter Opensuse an. Das ist insofern nützlich, weil man hierfür mit YaST allein nicht auskommt und auf die Kommandozeile runter muss. Für einen Umzug voll ausgestatteter virtueller Clients (KVM/QEMU-Linux-Gastsysteme) zur Mail- und Auftragsbearbeitung gelten die Ausführungen dann analog.

Übrigens: Durch voll-virtualisierte KVM/QEMU-Systeme (für Mailserver und Clients),

  • die netzwerktechnisch weitgehend abgeschottet sind,
  • über die kein freier Internetzugang mit Browsern erlaubt ist
  • und die auch nur spezielle Mail-Accounts bedienen

kann man auch Hackern das Eindringen ein wenig erschweren!

Umzug eines physikalischen Linux-E-Mail-Servers in eine Virtualisierungsumgebung?

Das erste Problem besteht für manchen Leidensgenossen ggf. darin, einen schon vorhandenen physikalischen Server in eine Virtualisierungsumgebung zu bringen. Ehrlich gesagt, habe ich das noch nie selbst gemacht - und leider auch keine Zeit, das mal testweise auszuprobieren. Server für spezielle Aufgaben sind in meinem begrenzten Netz schon seit langem aus guten Gründen virtualisiert 🙂 .

Ich verweise für diese Aufgabe unter Linux deshalb auf sog. "P2V-Tools" (physical to virtual) und entsprechende Literatur. Die ganz unten aufgeführten Links geben hierzu Hinweise und Anleitungen. Für die nachfolgenden Schritte setze ich voraus, dass es bereits einen unter KVM/QEMU virtualisierten Server gibt - allerdings auf unverschlüsselten Partitionen/Volumes.

Vorüberlegung A: Wie sieht es mit der Performance und der Flexibilität auf verschlüsselten Plattformen aus?

Kann man sich auf seinen Systemen eigentlich eine Verschlüsselungsschicht zusätzlich zur Virtualisierung leisten? Das ist eine gute Frage, die man pauschal schlecht beantworten kann. Unter Linux kommt meist eine Kombination aus dm-crypt und LUKS zum Einsatz. Für Systeme mit Prozessoren der letzten 5 Jahre sieht es dabei hinsichtlich der reinen Krypto-Performance recht gut aus. Bei Virtualisierungshosts im Heim-Bereich (also eher mit begrenzten Ressourcen) sind aber ein paar zusätzliche Punkte zu beachten:

Schichtung
Hat man als Plattenunterbau Raid-Systeme im Einsatz, so stellt sich etwa die Frage der Schichtung der verschiedenen Zugriffsverfahren. Aus meiner Sicht ist folgende Reihenfolge für virtualisierte Serversysteme sinnvoll:

  • Plattenpartitionen für Raid   >>  
  • Raid 10   >>  
  • LVM   >>  
  • Volumes für KVM-Host-OS   >>  
  • dm-crypt/Luks für ein LVM-Raw-Volume   >>  
  • KVM/QEMU- und Gastsystem mit Zugriff auf das Raw-Volume als virtuelle Platte   >>  
  • LVM /Volumes (oder Partitionen) im Gastsystem   >>  
  • ext4-Filesysteme im Gastsystem

Verschlüsselung vor Raid scheint mir aus naheliegenden Gründen wenig performance-optimierend zu sein. Bzgl. der Reihenfolge "LVM <> dm-crypt/Luks" kann man streiten. Für die eine oder andere Wahl ist aus meiner Sicht dabei nicht die Performance sondern die Flexibilität ausschlaggebend. Bei der von mir gewählten Vorgehensweise verschlüsseln wir LVM-Raw-Volumes und nicht die sie tragenden Platten-Partitionen. Das erlaubt den Einsatz unterschiedlicher Krypto-Algorithmen und individueller Passphrases für die zu verschlüsselnden Volumes. Ein Nachteil ist, dass Größenänderungen der Volumes und Filesysteme danach nicht im Online-Betrieb möglich sind. Das stört im semi-professionellen Umfeld aber weniger (s.u.).
Siehe auch:
https://superuser.com/questions/1193290/best-order-of-raid-lvm-and-luks

Einsatz von virtio-Treiber
Für optimale Performance setze ich auf dem KVM-Host für die Vermittlung des Zugriffs des KVM-Gast-Systems auf die als virtuelle HDs bereitgestellten Volumes den QEMU-eigenen "VirtIO"-Treiber ein. Das sieht im "virt-manager" dann etwa so aus:

Übernahme der Verschlüsselung durch den Virtualisierungs-Host!
Man erkennt an der oben angegebenen Schichtung, dass ich die Verschlüsselung vollkommen dem Virtualisierungs-Host überlasse. Das erscheint mir sinnvoll, da ihm normalerweise mehr CPU-Cores als dem Gastsystem zur Verfügung stehen.

Ich kann jedenfalls mit diesem Setup auf einem schon sehr betagten Host mit einem KVM-Gast-Mail-Server, der nur um die 10 Mails pro Minute verarbeiten muss, sehr gut leben. (Der Host beherbergt dabei noch mehr aktive virtualisierte Systeme!) Der Unterschied zur Situation ohne Verschlüsselung ist gefühlt klein. Soviel zum Mail-Server und Performance.

Vorüberlegung B: Verschlüsselung eines (LVM-) "Raw"-Devices? Verzicht auf "qcow2"?

Gem. der oben propagierten Schichtung möchte ich das Gastsystem für meinen E-Mail-Server offenbar auf einem "Raw-Volume" der LVM-Schicht betreiben - also direkt auf einem LVM-Volume, das vom Gast-System aus formatiert wurde, und nicht auf einem "qcow2"-Loopback-File eines übergeordneten Filesystems des Hosts. Was spricht gegen ein Vorgehen mit "qcow2"-Dateien auf einem KVM-Host für einen virtualisierten Server?

"qcow2"-Dateien - mit internem Filesystem für den Gast - sind zwar hochflexibel einsetzbar - der Zugriff des Gastes auf seine virtuelle Platte erfolgt dabei aber immer über die Filesystem-Schicht des KVM/QEMU-Hosts UND über die Filesystem-Schicht des KVM-Gastes; das kostet Performance!

Der entsprechende Overhead ist nicht unerheblich - vor allem dann nicht, wenn der Server ggf. von mehreren Clients gleichzeitig genutzt werden soll. Die QEMU-Leute haben deshalb schon immer vorgesorgt und erlauben den direkten Zugriff eines Gastes auch auf nicht gemountete Volumes oder Partitionen des Hosts.

Der zweite Grund entspringt ein wenig Sicherheitsüberlegungen.

Auf eine "qcow2"-Datei muss vom Gast-System über ein Mount-Verzeichnis des Host-Dateisystems aus zugegriffen werden. Die Datei liegt dann also bereits in einem unverschlüsselten Dateisystem, das auf einem Verzeichnis des Hosts gemountet ist, vor. Damit besteht aber auch - je nach Rechtesetzungen - die potentielle Gefahr, dass ihr Inhalt im laufenden Betrieb auch anderweitig ausgelesen werden kann (z.B. mit qemu-mount).

Die Situation ist im Fall von Raw-Devices komplexer. Das LVM-Volume wird nach einer Entsperrung des Verschlüsselungsverfahrens (s.u.) zwar wie eine Platte als Device unter "/dev/mapper" bereitgestellt. Aber dieses Device ist auch bei laufendem Gastsystem nicht direkt im Verzeichnisbaum des laufenden Host-Systems verankert. Ein evtl. durchgeführter Mountvorgang auf dem Host ist aber gar nicht so einfach zu verschleiern. Er wäre unnötig und würde bei entsprechender Protokollierung Alarmglocken auslösen.

Dennoch gilt:

Verschlüsselung von LVM-Volumes und Einsatz von qcow2 müssen bei hinreichenden Performance-Reserven kein Widerspruch sein.

Eine Schichtung

Raid 10   >>   LVM   >>   dm-crypt/Luks-Volume mit ext4   >>   Gemountetes LUKS/ext4-Volume mit qcow2-Datei auf dem KVM/QEMU-Host   >>   KVM/QEMU-Gast mit Zugriff auf qcow2-Loopback-Device   >>   LVM-Volumes des Gastsystems auf qcow2-Device   >>   ext4-Gast-Filesystem auf LVM-Volumes des Loop-Devices

funktioniert auf schnellen Hosts auch gut und bietet Verschlüsselung samt qcow2-Flexibilität. Ich nutze diese Variante u.a. auf Linux-Workstations für virtualisierte Clients.

Ich verfolge nachfolgend für unseren geplanten (Server-) Umzug aber die Variante ohne qcow2-Loopback-Device. Auch unser bisheriger virtualisierter (Mail-) Server mag bereits direkt auf einem unverschlüsselten Volume des Hosts verankert sein.

Vorüberlegung C: Größe des neuen kryptierten Raw-Volumes für den Umzug?

Wir können nun z.B. über den LVM-Volume-Manager von YaST oder über LVM-CLI-Kommandos (vgcreate, lvcreate) ein Raw-Volume kreieren, das nach seiner Verschlüsselung eine Kopie des alten Systems aufnehmen soll. Wie groß muss dieses logische Volume sein?

Naiverweise könnte man davon ausgehen, dass genau die Größe des alten Volumes (oder der alten Partition) in GiB hinreichend ist. Das wäre falsch. LUKS hinterlegt Informationen zum verschlüsselten Plattenplatz und zu 8 möglichen Passphrase-Keys in einem sog. "Verschlüsselungsheader". Dieser Header benötigt zusätzlichen Platz jenseits der verschlüsselten Nutzlast. Der Platzbedarf ist zwar nicht groß (ca. 2 MB) - aber er ist eben zu berücksichtigen. Man muss dem neuen Volume etwas mehr Platz als dem alten spendieren. Ich vergebe meist gleich 1 GB extra.

Verschlüsselung des Raw-Volumes

In unserem Beispiel heiße das neue logische LVM-Volume für das virtuelle Plattendevice des KVM-Gastes "lvimap_hd0" und sei Teil einer LVM-Volume-Group "volgrp4". Als Device erscheint dieses Volume dann unter "/dev/mapper" als "volgrp4-lvimap_hd0".

myserv:~ # la /dev/mapper 
...
lrwxrwxrwx  1 root root       8 Jun 10 09:40 volgrp4-lvimap_hd0 -> ../dm-14
...

Der zugehörige Link verweist im Beispiel dann ebenso wie "/dev/volgrp4/lvimap_hd0" auf "/dev/dm-14".

Wir setzen zur Kryptierung "dm-crypt" ein. "dm-crypt" nutzt LUKS über gut integrierte Module.

Die Aufgabe, ein (LVM-basiertes) "Raw-"-Device mit dmcrypt/LUKS zu verschlüsseln, lässt sich unter Opensuse Leap (42.2/42.3) entgegen jeder Erwartung mit YaST leider nicht erfolgreich durchführen. YaST wickelt die Anlage eines verschlüsselten Volumes nur dann korrekt ab, wenn das Filesystem bereits vorgegeben wird - also NICHT bei der Verschlüsselung für Raw-Devices innerhalb der Reihenfolge :

Partition   >>   LVM-Group   >>   Raw LVM-Volume   >>   dm-crypt/LUKS   >>   KVM-guest   >>   LVM im Gast   >>   Filesystem

Das ist bereits von anderen beklagt worden; siehe etwa:
https://forums.opensuse.org/showthread.php/528938-installation-with-LUKS-cryptsetup-installer-gives-error-code-3034

Man muss also auf der Kommandozeile arbeiten und das Kommando "cryptsetup" bemühen. Für unser Beispiel-Volume "lvimap_hd0" (erste virt. Platte des künftigen E-Mail-Servers) lautet ein mögliches Kommando zur Verschlüsselung dann:

myserv:~ # cryptsetup luksFormat --hash=sha512 --key-size=512 --cipher=aes-xts-plain64 --verify-passphrase /dev/volgrp4/lvimap_hd0

Für Details zu den verfügbaren Verschlüsselungs- und Hash-Verfahren werfe man einen Blick in die man-Seiten zum Kommando. Man muss die künftige Passphrase zweimal eingeben. Damit ist die Verschlüsselung aktiv. Ein anschließender Blick auf das Volume mit dem YaST-Partitioner zeigt entsprechend ein Verschlüsselungssymbol an.

Altes KVM-Gast-System mit "dd" kopieren oder mit "virt-manager" klonen?

Bzgl. des geplanten Umzugs unseres unter KVM/QEMU virtualisierten (Mail-) Servers auf das neue Krypto-Device stellt sich nun die Frage, wie wir das am besten bewerkstelligen:

Sollen wir "dd" einsetzen? Das ist zwar möglich, erfordert anschließend aber wegen kopierter UUIDs, MAC-Adressen etc. etliche manuelle Nacharbeiten im geklonten System und auf dem Host.

Besser ist deshalb aus meiner Sicht ein Cloning mit Hilfe von virt-manager! Dabei ist folgende Schrittfolge einzuhalten:

  • Schritt 1 : Öffnen des neuen dm-crypt-Devices unter einem verständlichen Namen
     
    myserv:~ # cryptsetup open /dev/mapper/volgrp4-lv_imap_hd0  cr_imap_encr

    Dabei muss natürlich die bereits gesetzte Passphrase für das Crypto-Device eingegeben werden. "cr_imap_encr" steht dann als ansprechbares Device unter "/dev/mapper/" bereit

  • Schritt 2 : virt-manager öffnen und in der Liste der Gäste mit der rechten Maustaste auf den zu klonenden Gast klicken. Dann die Option "Clone ..." wählen. Das führt uns dann zu einer Maske, die in etwa so aussieht und die zu klonende virtuelle Platte (vm2_hd1) des vorhandenen Gastes anbietet:
     

    Bzgl. der zu klonenden Disk öffnet man die Drop-Down Box und wählt "Details" :

  • Schritt 3 : In der sich neu öffnenden Maske trägt man den Pfad zum geöffneten "dm-crypt"-Decvice ein:
     

    Dann in der aktuellen Maske den "OK"-Button und anschließend in der Ausgangsmaske den Button "Clone" drücken.

Je nach Größe unseres virtuellen Servers und der Schnelligkeit der Plattensysteme wie des Prozessors dauert das etwas. Anschließend erhalten wir allerdings einen Clone, den man sofort booten kann. (Vorher den ursprünglichen Mail-Server natürlich runterfahren, um IP-Konflikte zu vermeiden. Das geklonte System hat immer noch die gleiche IP-Adresse wie das alte! )

Das war es im Wesentlichen schon. Wir haben erfolgreich ein virtualisiertes Server-System auf einen verschlüsselten LVM-Volume-Unterbau umgezogen!

Wie schließt man das verschlüsselte System manuell?

Unsere manuelle Vorgehensweise hat dazu geführt, dass das verschlüsselte Volume nicht in Systemdateien eingetragen wurde. Es steht daher nach einem Boot-Vorgang des Hosts nicht automatisch zu Verfügung. Auch das Passwort für die Entschlüsselung wird im Bootvorgang nicht automatsich abgefragt.

Ein aktivierter "libvirtd"-Service kann daher nach seinem Start im Zuge eines Bootens des Hosts auch nicht auf das Volume für den umgezogenen Gast zugreifen. Ein automatisches Hochfahren des Gastes über libvirt-Einstellungen ist somit ebenfalls nicht möglich. Das sind Probleme, um die wir uns in nachfolgenden Artikeln kümmern müssen.

An dieser Stelle möchte ich aber wenigstens den notwendigen manuellen Befehl für das Schließen des Crypto-Devices im Zuge eines Herunterfahrens angeben:

  • Schritt 1 - Herunterfahren des Gastsystems: Dies geschieht entweder über Standard-Befehle im Gast selbst oder z.B über virt-manager.
  • Schritt 2 - Schließen des Crypto-Devices :
     
    myserv:~ # cryptsetup close cr_imap_encr

Ausblick

In folgenden Artikeln möchte ich im Nachgang zu unserem "Umzug" ein wenig auf das Thema eingehen, wie man das Hochfahren des KVM-Hosts mit Gastsystemen auf verschlüsselten Volumes gestalten kann. Zudem wollen wir den "Verschlüsselungsheader" sichern und uns mit den Themen Backup und "fstrim" für SSDs als Basis der beschriebenen Schichtung befassen. Sinnvoll ist auch ein Blick auf (Mail-) Client-Systeme: Von irgendwo aus muss ja auch mal grafisch auf die virtualisierten Systeme zugegriffen werden. Dann werden z.B. Spice oder X2GO-Clients samt zugehörigen Protokollen zu einem Sicherheitsthema auf dem System, von dem aus wir auf virtualisierte Clients für die Auftragsbearbeitung zugreifen. Verschieben wir mit der Virtualisierung im Client-Umfeld also nur die Sicherheitsebene?

Links

P2V-Tools
http://manuel.kiessling.net/2013/03/19/converting-a-running-physical-machine-to-a-kvm-virtual-machine/
http://libguestfs.org/virt-p2v.1.html
https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/v2v_guide/chap-v2v_guide-p2v_migration_converting_physical_machines_to_virtual_machines
http://events17.linuxfoundation.org/sites/events/files/slides/virt-v2v-rjones-backup-slides.pdf
http://qemu-buch.de/de/index.php?title=QEMU-KVM-Buch/_Speichermedien/_Physical-to-Virtualp2v_migration_converting_physical_machines_to_virtual_machines
https://access.redhat.com/articles/1351473

dm-crypt/Luks und die Reihenfolge von Zugriffsschichten
https://superuser.com/questions/1193290/best-order-of-raid-lvm-and-luks
https://blog.raptor2101.de/2009/09/23/verschlusselung-von-raids/
http://www.andreas-janssen.de/cryptodisk.html
http://linux-club.de/wiki/opensuse/Verschluesselung:_dm-crypt/luks_unter_openSUSE
https://wiki.archlinux.org/index.php/Dm-crypt/Specialties

DSGVO, Freelancer, E-Mails und Umzug KVM-virtualisierter Linux-E-Mail-Server auf verschlüsselte Platten/Partitionen – II

Im letzten Artikel dieser Serie

DSGVO, Freelancer, E-Mails und Umzug KVM-virtualisierter Linux-E-Mail-Server auf verschlüsselte Platten/Partitionen - I

hatte ich festgestellt, dass ein regelmäßiger Mailaustausch mit Kunden zu einem DSGVO-Thema werden kann. Die Herausforderung für einen Freelancer ist dabei, dass Datenschutz auf seiner Seite auch in Maßnahmen zur Datensicherheit für Mailinhalte münden muss. Diese Maßnahmen muss der Auftraggeber kennen (s. Art. 28 und Art. 32 der DSGVO).

Datensicherheit von E-Mails - im Besonderen im Sinne der Vertraulichkeit - erstreckt sich natürlicherweise auf die Absicherung des Transports und der Lagerung. Der alleinige Zugriff durch den Berechtigten (Adressaten) ist zu gewährleisten. Das ist nicht so viel anders als bei Dateien auch. Akzeptiert man erst einmal, dass E-Mails eine Personenbezug aufweisen, muss man sich um dieses Thema im Sinne DSGVO kümmern - und zwar von vornherein in Kooperation mit seinem Auftraggeber (s. Art. 28).

Ich möchte in diesem Artikel nochmals auf meine Motivation zu vertraglichen Regelungen eingehen, obwohl das für den einen oder anderen technisch interessierten Leser womöglich langweilig sein mag. Der Grund für diesen Einschub ist, dass ich in einigen Diskussionen, die ich seit dem letzten Artikel geführt habe, immer wieder von Kollegen darauf hingewiesen wurde, dass ein solcher Aufwand bei Kleinst-Unternehmen (mit einer Mitarbeiterzahl < 250) womöglich gar nicht nicht nötig sei.

Wirklich nicht ?

DSGVO und vertragliche Vereinbarungen auch für KMU?

Ja, es gibt in der DSGVO den Hinweis auf Unternehmen mit weniger als 250 Mitarbeitern. Primär in Art. 30. In Art. 40 wird ferner darauf hingewiesen, dass die EU-Mitgliedsländer "Verhaltensregeln" erarbeiten sollen, die auf die besonderen Bedürfnisse von Kleinst- und Kleinunternehmen Rücksicht nehmen. Tja, kennt die Regeln für Deutschland jemand? Ich nicht ....

In Art. 30 geht es aber "nur" um eine mögliche Befreiung von der Pflicht zum Führen eines "Verzeichnisses von Verarbeitungstätigkeiten" (für personenbezogene Daten). Dies ersetzt jedoch nicht Art. 28 - und der verlangt eindeutig eine Verarbeitung zu schützender personenbezogener Daten auf Basis eines Vertrages. Das ist meine erste Motivation für vertragliche Regelungen in puncto E-Mail-Austausch.

Nun könnte man ins Feld führen, dass der Zugriff auf E-Mails, die einem ein Kunde (freiwillig) schickt, keine echte Weiterverarbeitung von persönlichen Daten darstelle. Der Kunde willige durch das Senden ja in eine potentiell unsichere Form der Verarbeitung ein. Das mag im Einzelfall vielleicht so sein. In größeren Projekten hat man es aber mit einer Vielzahl von Mails verschiedener Personen zu tun, die sich systematisch mit Sachverhalten auseinandersetzen. In den Mails befinden sich im Abspann meist weitere persönliche Kontaktdaten; damit ist ein Personenbezug gegeben. In den vielen Mail-Texten befinden sich zudem ggf. Inhalte vertraulicher Natur über den Absender oder Dritte oder aber das Projekt. Im Zuge eines Projekts werden Aufgaben, Verhalten, Arbeitsweise, Probleme und ggf. Meinungen der verschiedenen Absender meist deutlich aus dem Mailverkehr ersichtlich. Ist man ehrlich, so wird man zugeben: In projektbezogenen Mails stecken in Summe erhebliche Mengen an direkt oder indirekt personenbezogenen Informationen. Das ist meine zweite Motivation.

Hinzu kommt: In Projekten ist ein solcher Informationsfluss auch an externe Freelancer sehr regelmäßiger Natur. Und Mails werden ebenso regelmäßig von selbigen Externen gespeichert - auch um im Bedarfsfall nachweisen zu können, was man wann und warum für den Auftraggeber geleistet hat. Mach ich auch genau so. Deswegen scheinen mir hier dann die Einschränkungen von Art 30. Punkt 5 der DSGVO zu greifen: Da ist die Verpflichtung zum Tätigkeitsverzeichnis nur bei nicht regelmäßigem Datenaustausch ausgenommen. Ich meine aber ganz generell, dass im Kontext des regelmäßigen Mailaustauschs in Projekten ein Nachdenken über Datenschutz gefragt ist. Das ist meine dritte Motivation für vertragliche Vereinbarungen.

In Projektmails werden zudem oft Dateien als Anhänge transportiert, die Informationen über Projektinhalte enthalten. Mit irgendwas muss der externe Freelancer ja arbeiten! Nun wird jeder vernünftige Arbeits- oder auch Berater-Vertrag den Freelancer zur Geheimhaltung solcher Informationen verpflichten und dazu auch technische Maßnahmen auf der Höhe der Zeit einfordern. Es geht dann also um eine direkte Anforderung des Auftraggebers, elektronisch übermittelte Informationen des Auftraggebers zu schützen. Hierfür gelten Datenschutzgesetze ganz generell und auch ganz unabhängig von der DSGVO - brisant wird der Informationsaustausch über Mail im Sinne der DSGVO aber zusätzlich durch die Kopplung an einen identifizierbaren Absender. Das ist meine vierte Motivation für vertragliche Regelungen.

Ein weiterer Beweggrund ist folgender: Man sollte sich auch als Kleinst-Auftragnehmer sehr klar darüber werden, welches Schutzniveau man als Einzelperson zu vertraulichen Daten (hier: Mails) überhaupt mit welchen Maßnahmen anbieten kann - und welche Restrisiken verbleiben.

Eine letzte starke Motivation für eine vertragliche Fixierung von Maßnahmen ist sozusagen die "Mithaftung" des Auftraggebers: Ich denke, es ist für einen Auftragnehmer immer besser, wenn er im Schadensfall nachweisen kann, dass der Auftraggeber über die Maßnahmen und Risiken bei der Daten-/Informations-Vrarbeitung durch den Auftragnehmer - also durch den Freelancer - volle Kenntnis hatte. Und dies gilt eben auch bzgl. der Mail-Verarbeitung.

Aus all diesen Gründen sollte man wegen der DSGVO (aber nicht nur wegen ihr) verschiedene Punkte zur Mailverarbeitung mit dem Auftraggeber in einem Vertrag hinterlegen. Die Grundlage für solche Vereinbarungen bieten wie gesagt Art. 28 und auch 32 der DSGVO - auch für Unternehmen mit weniger als 250 Mitarbeitern.

Kritische Punkte bzgl. des Mailschutzes

Die Liste der Hauptkapitel in einem Katalog an Verarbeitungstätigkeiten bzgl. Mails ist im Prinzip recht einfach:

Empfang, Versand, Einhaltung von Transport-Verfahren und Transportwegen, Lagerung, Löschung, Umgang mit Anhängen.

Zu den kritischen Punkten zählt dabei vor allem der Umgang mit nicht oder nicht mehr verschlüsselten Mails an Stationen, an denen Vertraulichkeit potentiell gefährdet ist. Das betrifft u.a. Postfächer beim Provider als auch die Mailhandhabung in Postfächern auf eigenen Server- und Client-Systemen.

Wie sichert man also E-Mails dauerhaft, etwa im Sinne der Vertraulichkeit? Die vernünftigste Antwort darauf hatten wir schon im letzten Artikel angesprochen:
Ende-zu-Ende-Verschlüsselung mit OpenPGP - insbesondere dann, wenn neben personenbezogenen auch wirtschaftlich relevante Geheimnisse ausgetauscht werden. Die Option zur OpenPGP-Verschlüsselung bietet deswegen u.a. auch DE-Mail an.

Was, wenn sich der Auftraggeber darauf aber nicht einlässt? Im Einzelfall besteht dann zwar noch die Option, Zip-Anhänge mit AES zu verschlüsseln und sich die Passwörter über einen anderen Kanal mitzuteilen. Bei hoher Mailfrequenz wird dieser Weg aber schnell unpraktisch. Es bleibt die Verschlüsselung des Transportwegs; die Mails selbst landen hingegen unverschlüsselt in Postfächern.

E-Mail-Lagerung beim Provider?

Typischerweise passieren Mails in Richtung auf einen eigenen Server oder Client des Freelancers zunächst einen Provider. Aus Sicht des Kunden und der DSGVO ist also ein Unterauftragnehmer involviert. Gemäß der DSGVO gilt es für den Freelancer also, mit seinem Internet und/oder Mail-Provider einen Auftrags-Daten-Verarbeitungsvertrag abzuschließen.

Man ist als Freelancer versucht, Mails z.T. sowohl in Postfächern beim Provider als auch auf eigenen Servern zu halten. Motive sind : Mobilität und eine Art "Backup"-Politik. Die Frage ist, ob das deinem Auftraggeber so überhaupt recht ist. Ggf. traut dein Auftraggeber deinem Provider ja noch weniger als dir ...

Wird ein deutscher Provider mit Servern in Deutschland und ggf. ISO 27001-Zertifizierung für eine Lagerung von E-Mails auch vom Auftraggeber als hinreichend sicher akzeptiert, sollte man dies in jedem Fall als gemeinsame Vereinbarung in einem Vertrag festhalten.

Im anderen Fall wird dein Auftraggeber den Mailserver des Providers höchstens als Durchgangsstation akzeptieren. Deshalb sollte man die Risiken, die mit einer temporären Zwischenlagerung beim Provider verbunden sind, nennen und vom Auftraggeber akzeptieren lassen. Dazu gehört potentiell auch, dass der Provider ggf. an gesetzliche Vorgaben bzgl. einer Datenvorratshaltung gebunden ist und bestimmte Mail-Daten ggf. auch an Sicherheitsbehörden weitergibt.

Spam-Filterung auf Servern von Drittanbietern?

Eine weitere Station, die eine Mail ggf. auf dem Weg zum eigenen IMAP-Server passiert, mag ein Spam-Filter auf einem Server im Internet sein. Mails passieren bei mir zunächst Amavis, werden auf Viren geprüft und an Spamassassin mit Bayes-Filter weitergereicht. Danach wird für Mails unbekannter Absender aber auch ein Spam-Server im Internet - nämlich ein Razor-Server - für die Spam-Filterung eingebunden.

Hier ist die Frage, was genau passiert: Wird die gesamte Mail für einen Check übermittelt - oder werden wie im Fall von "Razor" nur Prüfsummen übermittelt? Und in welchem Land genau stehen die Spamfilter-Server und welcher Rechtsprechung unterliegen sie?

Auch hier ist eine Vereinbarung mit dem Auftraggeber gefragt, was er denn so zulassen möchte. In der Regel wird eine Übermittlung des Volltextes ausgeschlossen werden müssen. Das erfordert ggf., dass man Mails, die on bestimmten Absendern oder aus bestimmten Postfächern beim Provider stammen, auf eigenen Mail-Gateways absenderspezifischen Filter- und Verarbeitungsregeln unterwerfen muss.

E-Mail-Lagerung auf eigenen Systemen und Verschlüsselung

Irgendwann landen die Mails aber auf eigenen Systemen. Dort gilt meiner Meinung nach vor allem eins:

Die Mails dürfen nicht unverschlüsselt gelagert werden!

Es besteht sonst die Gefahr des Datenklaus bei Einbrüchen oder anderen unerlaubten Systemzugängen - auch im heruntergefahrenen Zustand. Das gilt nicht nur für Laptops; es betrifft auch Desktop- und Server-Systeme im Heim- oder Firmennetz. Denn normalerweise kann ein Freelancer keinen hinreichenden Zugangsschutz zu seinen Systemen gewährleisten. Die schöne Klausel

gemäß oder unter Berücksichtigung des "Stands der Technik",

die im Zusammenhang mit Datenschutz und der DSGVO immer wieder auftaucht, schließt heute wohl Verschlüsselungslösungen als Standard ein. Deren Einsatz beträfe dann eigene Mail-Server und Mail-Client-Systeme gleichermaßen.

Übrigens: Das gilt nicht nur für Mails sondern im Grunde für jede Art vertraulich zu behandelnder Dateien.

Reichen Verschlüsselungscontainer etwa auf Basis von Veracrypt?

OK, E-Mail-Lagerung in verschlüsselter Form. Damit sind wir schon beim nächsten Problem:

Reine Datei-Container allein sind für eine verschlüsselte Lagerung unzureichend, da Programme, mit denen man E-Mails oder deren Anhänge öffnet und verarbeitet, ggf. Backups- oder Kopien in unverschlüsselten Bereichen der Systemplatten ablegen. Typisch sind etwa "bak"-Dateien von Office-Programmen oder Editoren.

Verschlimmert wird die Situation zudem noch durch den Einsatz von SSDs mit Wear Leveling. In die SSD integrierte Controller schaufeln ggf. unverschlüsselte Daten in SSD-Bereiche, die vom OS aus nicht ohne Spezialtools zugänglich sind. Ein Hautpentwickler von Veracrypt warnt etwa explizit vor dem Einsatz des Veracrypt-Containers auf (unverschlüsselten) SSDs.

Um Leckagen über solche Seitenkanäle zu vermeiden, sind deshalb verschlüsselte Partitionen oder verschlüsselte "Volumes" erforderlich, auf denen das Betriebssystem [OS] und seine Applikationen in Gänze arbeiten.

In der Größe flexibel anpassbare "Volumes" werden unter Linux typischerweise über einen LVM-Layer oberhalb von Partition der Festplatten genutzt. Unter Linux muss man sich also auch Gedanken über das Zusammenspiel von LVM und Verschlüsselung machen.

Mehr dazu im nächsten Artikel !