Mounten eines vmdk-Laufwerks im Linux Host – III – qemu-nbd, loop-devices, kpartx

In dieser Artikelserie beschäftigen wir uns damit, wie man von einer Linux-Umgebung aus direkt auf Partitionen von vmdk-Disk-Images zugreifen kann. In den letzten beiden Artikeln

Mounten eines vmdk Laufwerks im Linux Host – I – vmware-mount
Mounten eines vmdk-Laufwerks im Linux Host – II – Einschub, Spezifikation, Begriffe

hatten wir zunächst das Kommando "vmware-mount" betrachtet. "vmware-mount" kann Partitionen in Snapshots eines "sparse and growing vmdk-Images" direkt auf Zielverzeichnisse eines Linux-Baums mounten. Wir hatten dabei gesehen, dass zwischenzeitlich ein sog. "flat"-File angelegt wird. Die Rechtesetzung beim Mounten hatte uns noch nicht besonders gefallen. Da vmdk-Format unterschiedliche und komplexe Varianten von bedarfsgerecht wachsenden Images und Snapshots erlaubt, hatten wir im zweiten Artikel ein paar Seitenblicke auf die Spezifikation geworfen, um die Vielzahl von vmdk-Dateien zu einem Disk-Image und die zugehörige Nomenklatur besser zu verstehen. Nun wollen wir ein erstes natives Linux-Tools betrachten.

Da "vmdk" mit Virtualisierung zu tun hat, ist es kein Wunder, dass die beste Unterstützung für dieses Format unter Linux aus dem QEMU-Bereich - und damit von Red Hat und aufgekauften Firmen - kommt. Eines der Tools, auf die dabei inzwischen Verlass ist, gibt es schon sehr lange (seit etwa 2010): qemu-nbd.

nbd steht dabei für Network Block Device; Ziel des nbd-Toolsets war es, virtuelle Speichermedien auch über Server - also über Netz - für qemu-basierte virtuelle Maschinen auf Client-Systemen (z.B. Linux-Workstations) bereitzustellen. Schön beschrieben sind die Grundlagen aus den Anfangszeiten etwa hier :
Qemu-Buch zu Network Block Devices
https://de.wikipedia.org/wiki/Network_Block_Device

nbd kann aber natürlich auch lokal - also auf der eigenen Linux-Workstation - zur Erstellung eines Block-Devices auf Basis eines vmdk-Disk-Images eingesetzt werden. Das Kernelmodul "nbd" und das zugehörige CLI-Kommando "qemu-nbd" erweisen sich dabei als fähig, auch Snapshots des neuesten vmdk-Formats in der Version 6 richtig zu verarbeiten. Für die weitere Verwertung unter Linux werden - bei richtiger Parametrierung - ein oder mehrere ein Block-Devices erzeugt, die wir z.T. direkt mounten können.

Sicherheit und das direkte Mounten von virtuellen Disks/Filesystemen auf Linux-Hosts

Vorab ein paar mahnende Worte: vmdk, qcow2, etc. sind für virtuelle Maschinen gedacht. Gerade bei virtualisierten Windows-Maschinen, aber auch sonst, sollte man vorsichtig sein, wenn man nicht genau weiß, in welchem Zustand sich die Filesysteme des Images befinden. Ein manipuliertes Filesystem und/oder mit Malware behafteter Inhalt kann nach einem Mounten auch auf einem Linux-Host erheblichen Schaden anrichten. Leute, die etwas anderes glauben, erliegen einer Illusion.

Ich plädiere deshalb dafür, Experimente oder auch forensische Aktivitäten mit Partitionen aus vmdk-Images immer in einem virtuellen KVM-Linux-Gastsystem eines KVM-Hostes auszuführen. Das Gastsystem kann man hinreichend gut vom eigentlichen Virtualisierungs-Host isolieren. Die Performance ist auf aktuellen und SSD-basierten Systemen hinreichend gut, um auch mit großen vmdk-Images bequem hantieren zu können.

Wenn ich nachfolgend vom "Host" spreche, meine ich also immer das Linux-System, auf dem man mit dem vmdk-Image "forensisch" operiert - und nicht die virtuelle Maschine, die das Image normalerweise direkt nutzt und auch nicht den Virtualisierungshost. Ich meine vielmehr einen speziellen KVM-Linux-Gast, von dem aus man auf das Image zugreift. Die zu untersuchenden vmdk-Dateien kann man auf einem solchen Gast z.B. über SSHFS bereitstellen - oder sie bei hinreichendem Platz einfach per scp in das Gast-Filesystem hineinkopieren.

Man lese zu den Gefahren etwa:
A reminder why you should never mount guest disk images on the host OS von D.P. Berrange

Zudem gilt immer:
Mehrfache Mounts mit ggf. konkurrierenden schreibenden Zugriffen sind unbedingt zu vermeiden! Operiert man mit dem Image entgegen meinem Ratschlag direkt auf dem Virtualisierungshost, so muss das virtualisierte Gastsystem, das das Image normalerweise nutzt, abgeschaltet sein. Oder: Man mountet zur Sicherheit in einem "read only"-Modus.

Notwendige Pakete für qemu-nbd

Wer sich unter Linux - in meinem Fall Opensuse Leap - mit qemu und KVM auseinandersetzt, hat die notwendigen Pakete mit ziemlicher Sicherheit bereits installiert. Erforderlich ist das Paket "qemu-tools" (unter Debian-Derivaten "qemu-utils"). Abhängigkeiten werden durch YaST (oder apt-get) aufgelöst. Unter Opensuse Leap ist das Paket bereits im Standard-Update-Repository enthalten; alternativ kann man auf das Virtualization Repository zurückgreifen.

Unterstützte vmdk-Formate

qemu-nbd greift intern auf die Fähigkeiten von "qemu-img" zurück. Die Seite en.wikibooks.org-wiki-QEMU-Images informiert darüber, welche vmdk-Formate (neben vielen anderen Formaten) qemu-img in einer aktuellen Version (≥ 2.9) unterstützt:

vmdk:
VMware 3 & 4, or 6 image format, for exchanging images with that product

Das Interessante ist, dass qemu-nbd die vorgegebenen vmdk-Dateien zu Snapshots und zur vmdk-Base-Disk nach außen - also in Richtung Linux-User - zu einem Block-Device zusammenführt. qemu-nbd legt also einen Block-Layer über die komplexe vmdk-Adressierungsstruktur. Die Hauptarbeit leistet dabei ein Kernelmodul.

Dreisatz zur Anwendung von qemu-nbd

Drei Schritte sind notwendig, um zu dem gewünschten Block-Devices und darin enthaltenen Filesysteme zu mounten.

Schritt 1 - Kernel-Modul laden:
Zunächst muss das "nbd"-Kernel-Modul geladen werden. Die Seite "kernel.org-Documentation-zu-nb erläutert die möglichen Parameter. Dieselbe Info liefert natürlich auch "modinfo":

mytux:~ # modinfo nbd
filename:       /lib/modules/4.4.120-45-default/kernel/drivers/block/nbd.ko
license:        GPL
description:    Network Block Device
srcversion:     6F062B770FED9DC58072736
depends:        
retpoline:      Y
intree:         Y
vermagic:       4.4.120-45-default SMP mod_unload modversions 
signer:         openSUSE Secure Boot Signkey
sig_key:        03:32:FA:9C:BF:0D:88:BF:21:92:4B:0D:E8:2A:09:A5:4D:5D:EF:C8
sig_hashalgo:   sha256
parm:           nbds_max:number of network block devices to initialize (default: 16) (int)
parm:           max_part:number of partitions per device (default: 0) (int)

In meinem Testfall erwarte ich maximal 4 (NTFS/FAT-) Partitionen pro vmdk-Device, also:

mytux:/etc # modprobe nbd max-part=4
mytux:/etc # 

Schritt 2 - nbd-Device wählen und mit dem Disk-Image verknüpfen:
Defaultmäßig hält Linux 15 potentielle nbd-Devices unter dem Verzeichnis "/dev" vor. Nun muss ein solches "nbd"-Block-Device natürlich noch mit einem Disk-Image verbunden werden. Wurde das Device "/dev/nbdx" - alos z.B. "/dev/nbd0" - noch nicht anderweitig benutzt, können wir es mit einem Disk-Image mittels der "-c" (= --connect) Option des Kommandos "<strong>qemu-nbd</strong>" zusammenführen.

Vorher müssen wir ein geeignetes Image wählen. Leser meines letzten Artikels wissen, dass auf meinem (selbst virtualisierten) Linux-System ein Testverzeichnis mit Dateien eines Win7-Gastes einer VMware-Umgebung existiert. Das Verzeichnis beinhaltet u.a. den zweiten Snapshot eines growable, sparse vmdk-Disk-Images zu einer Disk "Win7_x64_ssdx". Um es noch komplizierter zu machen, befinden sich die ursprüngliche Deskriptor-Datei und die zugehörigen Extent-Dateien (inkl. der ursprünglichen Basis-Datei) in einem anderen Verzeichnis "/vmw/Win7".

Das Verzeichnis "/vmw/Win7Test/" beinhaltet dagegen die Delta-Dateien (Deskriptor und Extents):

mytux:/vmwssd_w7prod/Win7_x64 # la | grep ssdx
-rw------- 1 myself  users    1507328 Mar 28 20:26 Win7_x64_ssdx-000001-s001.vmdk
-rw------- 1 myself  users      65536 Mar 28 19:54 Win7_x64_ssdx-000001-s002.vmdk
-rw------- 1 myself  users        370 Mar 28 20:24 Win7_x64_ssdx-000001.vmdk
-rw------- 1 myself  users     851968 Mar 29 10:38 Win7_x64_ssdx-000002-s001.vmdk
-rw------- 1 myself  users      65536 Mar 28 20:26 Win7_x64_ssdx-000002-s002.vmdk
-rw------- 1 myself  users      10240 Mar 29 10:37 Win7_x64_ssdx-000002.vmdk

Die Verlinkung zu den Ursprungsdateien unter "/vmw/Win7"

mytux:/vmwssd_w7prod/Win7_x64 # la /vmw/Win7/ | grep ssdx
-rw-------  1 myself  users 2344157184 Mar 28 19:53 Win7_x64_ssdx-s001.vmdk
-rw-------  1 myself  users     131072 Mar 27 19:37 Win7_x64_ssdx-s002.vmdk
-rw-------  1 myself  users        511 Mar 28 19:51 Win7_x64_ssdx.vmdk

ist, wie wir aus dem vorhergehenden Artikel wissen, natürlich über Verweise in den Deskriptor-Dateien Win7_x64_ssdx-000002.vmdk und Win7_x64_ssdx-000001.vmdk der Snapshots festgelegt.

Kommt qemu-nbd mit dieser komplexen Struktur klar? Ja - und wir müssen dabei nur die richtige Deskriptor-Datei angeben ...

mytux:/vmw/Win7Test # qemu-nbd -c /dev/nbd0 Win7_x64_ssdx-000002.vmdk 
mytux:/vmw/Win7Test # la /dev | grep nbd0
brw-rw----   1 root disk       43,   0 Mar 30 14:51 nbd0
brw-rw----   1 root disk       43,   1 Mar 30 14:51 nbd0p1
brw-rw----   1 root disk       43,   2 Mar 30 14:51 nbd0p2
mytux:/vmw/Win7Test # fdisk -l /dev/nbd0
Disk /dev/nbd0: 4 GiB, 4294967296 bytes, 8388608 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: 0x0efb9e3e

Device      Boot   Start     End Sectors  Size Id Type
/dev/nbd0p1         2048 5312511 5310464  2.5G  7 HPFS/NTFS/exFAT
/dev/nbd0p2      5312512 8384511 3072000  1.5G  7 HPFS/NTFS/exFAT
mytux:/vmw/Win7Test # # 

Das, was hier so selbstverständlich aussieht, ist angesichts der Komplexität des vmdk-Formats eigentlich ein kleines Wunder. Man beachte, dass hier keine irgendwie geartete Kopie der vmdk-Disk in einem neuen Format erzeugt wurde. Vielmehr arbeiten wir auf den originalen Daten - deren Adressierung über eine Block-Layer-Schicht vermittelt wird. Dafür setzt qemu-nbd meines Wissens auch nicht FUSE ein (unix.stackexchange.com-questions-192875/qemu-nbd-vs-vdfuse-for-mounting-vdi-images)

Schritt 3 - Mounten:
So, wie wir qemu-nbd hier verwendet haben, ist es sehr zuvorkommend zu uns und weist neben dem Block-Device "/dev/nbd0" für die gesamte Disk gleich auch noch weitere Block-Devices für die intern erkannten Partitionen des Disk-Images aus. Letztere können wir direkt mounten:

mytux:/vmw/Win7Test # mount /dev/nbd0p2 /mnt2
mytux:/vmw/Win7Test # la /mnt2
total 196128
drwxrwxrwx  1 root root         0 Mar 28 09:52 $RECYCLE.BIN
drwxrwxrwx  1 root root      4096 Mar 28 20:25 .
drwxr-xr-x 39 root root      4096 Mar 28 17:02 ..
drwxrwxrwx  1 root root      4096 Mar 28 09:53 Cosmological_Voids
drwxrwxrwx  1 root root         0 Mar 28 20:26 Muflons
drwxrwxrwx  1 root root         0 Mar 28 09:51 System Volume Information
-rwxrwxrwx  2 root root 200822784 Nov  4  2013 mysql-installer-community-5.6.14.0.msi
drwxrwxrwx  1 root root         0 Mar 29 10:37 ufos

Zugriffs-Rechte und deren Abänderung

Ähnlich wie bei "vmware-mount", das wir im ersten Artikel dieser Serie behandelt hatten, bekommen wir je nach Zweck der vmdk-Untersuchung ggf. ein Problem mit Rechten - siehe die durchgehenden 777-Rechte-Kämme nach dem Mounten. Im Fall von qemu-nbd können wir das aber rechtzeitig im Zuge des Mountens korrigieren.

Dabei ist - je nach Untersuchungszweck - die Frage zu stellen: Wer soll welche Art von Zugriff erhalten und wie privilegiert soll derjenige sein? Ich zeige mal 2 Varianten. (Für das genauere Verständnis sollte man sich mit Mount-Optionen und umasks bzw. fmasks und dmasks befassen.)

Variante 1: Nur Root soll rein lesenden Zugang erhalten:

mytux:/vmw/Win7Test # mount -o uid=root,gid=root,umask=0277 /dev/nbd0p2 /mnt2
mytux:/vmw/Win7Test # la /mnt2
total 196128                                                                                                                        
dr-x------  1 root root         0 Mar 28 09:52 $RECYCLE.BIN/                                                                        
dr-x------  1 root root      4096 Mar 28 20:25 ./                                                                                   
drwxr-xr-x 39 root root      4096 Mar 28 17:02 ../
dr-x------  1 root root      4096 Mar 28 09:53 Cosmological_Voids/
dr-x------  1 root root         0 Mar 28 20:26 Muflons/
dr-x------  1 root root         0 Mar 28 09:51 System Volume Information/
-r-x------  2 root root 200822784 Nov  4  2013 mysql-installer-community-5.6.14.0.msi*
dr-x------  1 root root         0 Mar 29 10:37 ufos/

Variante 2: Nur der User "myself" soll lesenden und schreibenden Zugang zu Dateien und Directories des gemounteten NTFS-Systems erhalten:

mytux:/vmw/Win7Test # mount -o uid=rmx,gid=users,fmask=0177,dmask=0077 /dev/nbd0p2 /mnt2
mytux:/vmw/Win7Test # la /mnt2
total 196128
drwx------  1 myself  users         0 Mar 28 09:52 $RECYCLE.BIN
drwx------  1 myself  users      4096 Mar 28 20:25 .
drwxr-xr-x 39 root root       4096 Mar 28 17:02 ..
drwx------  1 myself  users      4096 Mar 28 09:53 Cosmological_Voids
drwx------  1 myself  users         0 Mar 28 20:26 Muflons
drwx------  1 myself  users         0 Mar 28 09:51 System Volume Information
-rw-------  2 myself  users 200822784 Nov  4  2013 mysql-installer-community-5.6.14.0.msi
drwx------  1 myself  users         0 Mar 29 10:37 ufos
mytux:/vmw/Win7Test # 

Die Linux-Rechte sagen allerdings wenig darüber aus, wem ggf. neu angelegte Dateien mit welchen Rechten dann später welchem User auf einem virtuellen Windows gehören würden. Siehe zu dieser Thematik den entsprechenden Abschnitt und zugehörige Links im ersten Artikel der Serie.

Unmounten und Entfernen der Beziehung eines nbd-Devices zum Disk-Image

Nachdem man die Untersuchung einer Partition des vmdk-Disk-Images unter Linux abgeschlossen hat, muss man alles wieder rückgängig machen. Das geht wie folgt:

mytux:/vmw/Win7Test # umount /mnt2
mytux:/vmw/Win7Test # qemu-nbd -d /dev/nbd0 
/dev/nbd0 disconnected
mytux:/vmw/Win7Test # rmmod nbd
mytux:/vmw/Win7Test # 

Den umount-Befehl muss man natürlich für alle ggf. gemounteten Partitionen absetzen.

Nutzung von Loop-Devices?

nbd war deshalb sehr hilfsbereit, weil wir beim Laden des Kernelmoduls vorgegeben hatten, wieviele Partitionen maximal verwaltet werden sollen. Frage: Können wir die Partitionen auch anders bekommen, wenn wir etwa den Parameter des Kernelmoduls weglassen? Antwort: Ja, das geht.

Ich möchte zwei Varianten vorstellen, die sich nicht nur auf nbd-Devices, sondern in gleicher Weise auch auf raw- oder flat-Files, die man etwa als Output von "vmware-mount -f" erhalten würde, anwenden lassen.

Die erste Methode nutzt Loop-Devices. Loop- oder Loopback-Devices kennt der Linux-Anwender normalerweise im Zusammenhang mit mit der Nutzung von Filesystemen, die von Raw-Dateien beherbergt werden. Man vergisst dabei oft, dass sich Loop-Devices auch Block-Devices überstülpen lassen; die man-Page zu "losetup" sagt dazu:

DESCRIPTION
losetup is used to associate loop devices with regular files or block devices, to detach loop devices, and to query the status of a loop device.

Letztlich ist unter Linux/Unix halt alles ein File :-). Also:

mytux:/vmw/Win7Test # modprobe nbd
mytux:/vmw/Win7Test # qemu-nbd -c /dev/nbd0 Win7_x64_ssdx-000002.vmdk 
mytux:/vmw/Win7Test # la /dev | grep nbd0
brw-rw----   1 root disk       43,   0 Mar 31 15:19 nbd0

mytux:/vmw/Win7Test # fdisk -l /dev/nbd0
Disk /dev/nbd0: 4 GiB, 4294967296 bytes, 8388608 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: 0x0efb9e3e

Device      Boot   Start     End Sectors  Size Id Type
/dev/nbd0p1         2048 5312511 5310464  2.5G  7 HPFS/NTFS/exFAT
/dev/nbd0p2      5312512 8384511 3072000  1.5G  7 HPFS/NTFS/exFAT

Nun müssen wir noch die Offsets der Partitionen in Bytes aus den Start und End-Sektoren berechnen:

Offset Partition 1: 2048 * 512 = 1048576
Offset Partition 2: 5312512 * 512 = 2720006144

Diese Offset-Positionen sind dann über die Option "-o" im losetup-Kommando anzugeben:

mytux:/vmw/Win7Test # losetup -o 1048576 /dev/loop1 /dev/nbd0
mytux:/vmw/Win7Test # losetup -o 2720006144 /dev/loop2 /dev/nbd0
mytux:/vmw/Win7Test # mount /dev/loop1 /mnt2
mytux:/vmw/Win7Test # mount /dev/loop2 /mnt3
mytux:/vmw/Win7Test # la /mnt2
total 8
drwxrwxrwx  1 root root    0 Mar 27 19:35 $RECYCLE.BIN
drwxrwxrwx  1 root root 4096 Mar 27 19:35 .
drwxr-xr-x 39 root root 4096 Mar 28 17:02 ..
drwxrwxrwx  1 root root    0 Mar 27 19:34 System Volume Information

mytux:/vmw/Win7Test # touch /mnt2/hallo.txt
mytux:/vmw/Win7Test # la /mnt2
total 8
drwxrwxrwx  1 root root    0 Mar 27 19:35 $RECYCLE.BIN
drwxrwxrwx  1 root root 4096 Mar 31 15:24 .
drwxr-xr-x 39 root root 4096 Mar 28 17:02 ..
drwxrwxrwx  1 root root    0 Mar 27 19:34 System Volume Information
-rwxrwxrwx  1 root root    0 Mar 31 15:24 hallo.txt

mytux:/vmw/Win7Test # la /mnt3
total 196128
drwxrwxrwx  1 root root         0 Mar 28 09:52 $RECYCLE.BIN
drwxrwxrwx  1 root root      4096 Mar 28 20:25 .
drwxr-xr-x 39 root root      4096 Mar 28 17:02 ..
drwxrwxrwx  1 root root      4096 Mar 28 09:53 Cosmological_Voids
drwxrwxrwx  1 root root         0 Mar 28 20:26 Muflons
drwxrwxrwx  1 root root         0 Mar 28 09:51 System Volume Information
-rwxrwxrwx  2 root root 200822784 Nov  4  2013 mysql-installer-community-5.6.14.0.msi
drwxrwxrwx  1 root root         0 Mar 31 14:02 ufos
mytux:/vmw/Win7Test # 
mytux:/vmw/Win7Test # cat /mnt3/ufos/ufo.txt
Ufos are not real
mytux:/vmw/Win7Test #

Zurückdrehen können wir den gesamten Prozess wie folgt:

mytux:/vmw/Win7Test # umount /mnt3
mytux:/vmw/Win7Test # umount /mnt2
mytux:/vmw/Win7Test # losetup -d /dev/loop2
mytux:/vmw/Win7Test # losetup -d /dev/loop1
mytux:/vmw/Win7Test # qemu-nbd -d /dev/nbd0 
/dev/nbd0 disconnected
mytux:/vmw/Win7Test # modprobe -r nbd
mytux:/vmw/Win7Test # 

Loop-Devices und "vmware-mount -f"
Das Ganze klappt natürlich auch mit "vmware-mount -f" und dem dadurch erzeugten "flat"-File (s. den ersten Artikel):

mytux:/vmw/Win7Test # vmware-mount -f Win7_x64_ssdx-000002.vmdk /mnt/vmdk
mytux:/vmw/Win7Test # la /mnt/vmdk
total 4194304
-rw------- 1 myself users 4294967296 Mar 31 15:25 flat
mytux:/vmw/Win7Test # losetup -o 2720006144 /dev/loop2 /mnt/vmdk/flat 
mytux:/vmw/Win7Test # mount /dev/loop2 /mnt3
mytux:/vmw/Win7Test # cat /mnt3/ufos/ufo.txt 
Ufos are not real
mytux:/vmw/Win7Test # umount /mnt3
mytux:/vmw/Win7Test # losetup -d /dev/loop2
mytux:/vmw/Win7Test # vmware-mount -d /mnt/vmdk
mytux:/vmw/Win7Test #

Über diesen Weg können wir übrigens auch das Problem mit den Zugriffsrechten lösen, dass wir im ersten Artikel für "vmware_mount" angesprochen hatten - wir legen die Rechte analog zum oben besprochenen Vorgehen im Zuge des mount-Befehls fest.

kpartx?

Erfahrene Linux-User wissen, dass kpartx ein nettes Tool ist, das aus Block-Devices oder Raw-Files evtl. enthaltene Partitionstabellen ermittelt und über "/dev/mapper" entsprechende Devices bereitstellt. Das funktioniert natürlich auch auf Basis von "/dev/nbdX"-Devices:

mytux:/vmw/Win7Test # modprobe nbd
mytux:/vmw/Win7Test # qemu-nbd -c /dev/nbd0 Win7_x64_ssdx-000002.vmdk 
mytux:/vmw/Win7Test # kpartx -av /dev/nbd0 
add map nbd0p1 (254:12): 0 5310464 linear 43:0 2048
add map nbd0p2 (254:13): 0 3072000 linear 43:0 5312512    
mytux:/vmw/Win7Test # la /dev/mapper | grep nbd0
lrwxrwxrwx  1 root root       8 Mar 31 15:58 nbd0p1 -> ../dm-12
lrwxrwxrwx  1 root root       8 Mar 31 15:53 nbd0p2 -> ../dm-13
mytux:/vmw/Win7Test # mount /dev/dm-13 /mnt3
mytux:/vmw/Win7Test # cat /mnt3/ufos/ufo.txt
Ufos are not real
mytux:/vmw/Win7Test # umount /mnt3
mytux:/vmw/Win7Test # kpartx -d /dev/nbd0
mytux:/vmw/Win7Test # la /dev/mapper | grep nbd0
mytux:/vmw/Win7Test # modprobe -r nbd
mytux:/vmw/Win7Test # 

Analog für ein flat-File von vmware-mount:

mytux:/vmw/Win7Test # vmware-mount -f Win7_x64_ssdx-000002.vmdk /mnt/vmdk
mytux:/vmw/Win7Test # kpartx -av /mnt/vmdk/flat 
add map loop0p1 (254:12): 0 5310464 linear 7:0 2048
add map loop0p2 (254:13): 0 3072000 linear 7:0 5312512
mytux:/vmw/Win7Test # mount /dev/dm-13 /mnt3
mytux:/vmw/Win7Test # cat /mnt3/ufos/ufo.txt
Ufos are not real
mytux:/vmw/Win7Test # umount /mnt3
mytux:/vmw/Win7Test # kpartx -d /mnt/vmdk/flat
loop deleted : /dev/loop0
mytux:/vmw/Win7Test # vmware-mount -d /mnt/vmdk
mytux:/vmw/Win7Test # 

Alles gut !

Read-Only-Option?

In allen oben dargestellten Beispielen haben wir bislang durchgehend rw-Mounts durchgeführt. Da ist bei vielen Analysen nicht erwünscht. Grundsätzlich ist im Umgang mit Partitionen regelmäßig Vorsicht angebracht, um nichts zu zerstören. Write-´Zugriffe sollte man immer zuerst auf Kopien testen.

Daher stellt sich die Frage nach einer "ro"-Option von "qemu-nbd". Die gibt es, sie lautet "-r". Deren Setzung schlägt auf alle weiteren Maßnahmen durch:

mytux:/vmw/Win7Test # modprobe nbd max-part=4
mytux:/vmw/Win7Test # qemu-nbd -r -c /dev/nbd0 Win7_x64_ssdx-000002.vmdk 
mytux:/vmw/Win7Test # mount /dev/nbd0p2 /mnt3
fuse: mount failed: Permission denied
mytux:/vmw/Win7Test # mount -o ro /dev/nbd0p2 /mnt3
mytux:/vmw/Win7Test # 

Gibt es Größenlimit für die virtuelle Disk?

Ehrlich gesagt: keine Ahnung. Wenn es ein aktuelles Limit gibt, würde ich aufgrund älterer Infos im Zusammenhang mit nbd auf 1TB tippen. Wenn jemand was Genaueres weiß, kann er mir ja eine Mail schreiben. Siehe auch:

vsphere-50 und vddk
vddk51_programming.pdf

Fazit und Ausblick

Das nbd-Kernelmodul und das Kommando qemu-nbd eröffnen relativ einfache Zugänge zu komplexen vmdk-Image-Dateien. Dabei wird auch die aktuelle Version 6 des vmdk-Formats beherrscht. Wir haben zudem die Möglichkeit, das Mounten der bereitgestellten nbd-Block-Devices bzgl. der Rechte individuell zu gestalten.

Im nächsten Artikel gehe ich kurz auf "qemu-img" ein und betrachte dann das Kommando "guestmount" aus der neueren und Fuse-basierten Toolkiste von "libguestfs".

Links

losetup - Abkürzung für bestimmte mknod-Operationen zur Nutzung von Loop-Devices
unix.stackexchange.com/questions/98742/how-to-add-more-dev-loop-devices-on-fedora-19

qemu-nbd
https://wiki.ubuntuusers.de/QEMU/
https://opsech.io/posts/2017/Jun/07/how-to-mount-vm-disk-images-on-fedora.html
http://blog.vmsplice.net/2011/02/how-to-access-virtual-machine-image.html
https://sweetcode.io/introduction-to-linux-network-block-devices/

Meltdown und Spectre – Lehren aus dem Desaster? – III – Browser, Open Source?

Eines der aus meiner Sicht hohen Gefährdungspotentiale von Spectre lässt sich womöglich daran festmachen, dass zumindest in der Theorie Angriffe auch mit Hilfe von Javascript geführt werden können. Es lohnt sich an dieser Stelle deshalb, ein wenig über Browser im Lichte von Spectre nachzudenken. Ich ergänze diesen Beitrag zudem durch ein paar Überlegungen zu Open Source im Kontext der neuen Bedrohungen.

Der Browser als Einfallstor - nicht erst seit Meltdown/Spectre

Sehr "schön" ist in diesem Zusammenhang die Seite 13 in https://meltdownattack.com/meltdown.pdf, in der gezeigt wird, wie Passwörter aus dem Firefox-Passwortspeicher ausgelesen werden können. Es gibt dazu auch ein nettes Video. Zugriffe auf Passwortspeicher sind allerdings auch mit Angriffsmustern gemäß Spectre möglich. Zwar kann man Cache-Analysen wie in den Originalveröffentlichungen diskutiert, womöglich von Seiten der Browser-Hersteller unterbinden. Man darf gespannt sein, wann die Barrieren für spezifischen Seitenkanal-Angriffsvariante, die genaue Zeitmessungen erfordern, durch Ausnutzen anderer Seitenkanalwirkungen des Prozessor-Cachings umschifft werden können. Die aktuelle Ausgangslage verspricht jedenfalls ein lustiges Jahr 2018 ...

Das Angreifen von Browser-Subprozessen, zu denen Javascript-Programme keinen Zugang erhalten dürfen, ist an sich schon eine kritische Sache. Globaler betrachtet offenbart sich durch Meltdown/Spectre aber nur einmal mehr, dass die Anwendung "Browser" ein Angriffstor mit potentieller Tiefenwirkung für alle Betriebssysteme darstellen:

Aus Security-Perspektive sind Browser eigentlich als Anwendungen zu betrachten, die sich jederzeit in Schadcode-Implantations-Zentren verwandeln können.

Konnte man sich als Linuxer auf PCs bislang gegen landläufige Angriffsvektoren im Kontext von Browsern dadurch schützen, dass man Browser-Applikation dediziert in Containern oder besser noch virtuellen Maschinen unter KVM laufen ließ, so werden solche Konzepte durch die Prozessor-Schwachstellen ausgehebelt. Das gilt analog für Chrome/Chromium, die die Browserprozesse in separate Namespaces des Linux-Systems einbetten - und damit eine ähnliche Isolation wie Container erreichen.

Wenn aber selbst die Isolierung von Browsern unter Linux in eigenen Namespaces (s. Google) oder Containern aufgrund von kommenden Spectre-Angriffen nicht mehr hinreichend sein wird, um andere Systemprozesse und deren Datenkontexte zu schützen - tja, was dann?

Ursachen der Javascript-Misere

Eine interessante Frage ist zudem: Wem oder was haben wir eigentlich diese Misere von Angriffspfaden über Browser und Javascript zu verdanken?

Wenn man ehrlich ist, ist für viele Webseiten Javascript gar nicht zwingend erforderlich. Trotzdem wird es im Übermaß eingesetzt. Das liegt u.a. daran, dass sich viele Probleme leichter mit JS als mit CSS-Tricks lösen lassen. Nun wäre das nicht so schlimm, wenn sich das JS-Angebot auf das für die Funktionalität einer Seite Notwendige beschränken würde und die JS-Codes aus einer Quelle stammen würden. Das ist aber wegen der in viele Webseiten integrierten Werbung heute nicht mehr der Fall; s.u.. Zudem lässt leider auch das W3C immer JS-Funktionen zu, die potentiell problematisch werden können.

Ins Feld geführt wird regelmäßig auch ein Performance-Aspekt: Interaktionen des Users mit Webseiten sollen nicht zu einem Nachladen neuer (ggf. auf Servern per Script generierter) HTML-Seiten führen, sondern im Browser selbst abgehandelt werden. Hätten wir Gigabit-Netz, wäre dieses Argument nicht unbedingt schlagend. So aber sind Nutzer für viele Seiten tatsächlich gezwungen, Javascript anzuschalten.

Eine andere Ursache ist die Werbeindustrie mit ihren Tracking-Verfahren. Auf vielen Seiten sind die Quellen von integrierten JS-Codes von Dritt- und Viert-Firmen zur Analyse des Nutzerverhaltens derart unübersichtlich verteilt, dass man die betreffenden Seiten am besten gleich wieder schließt. Eien Analyse aller integrierten Codes ist in der Praxis unmöglich. AdBlocker helfen auch da nur bedingt.

Zudem ist der normale Nutzer im Westen ist inzwischen so stark an "kostenfreie" SW gewöhnt worden, dass er alle potentiellen Gefahren ignoriert. Zu was das am Smartphone führt sieht man ja bei der Installation vieler APPs und den dafür angeforderten Zugriffsrechten auf Speicher, Kontaktverwaltung und Kalender sowie Devices (Kamera, GPS, Mikrophon, ...) - die Sicherheit bleibt dabei auf der Strecke. Die meisten Benutzern erlauben ihren ach so geliebten Apps den Zugriff auf fast alle Devices und Daten. So gibt es inzwischen denn auch Browser-Plugins, die auf diverse Elemente eines PCs (wie etwa den Desktop) zugreifen können ... Eine Todsünde ...

Ein weiterer wichtiger Grund ist aber auch der gottverdammte Cloud-Gedanke:
Applikationen und deren Daten sollen aus dem Internet von Provider-Servern geladen und lokal in Browsern mit maximaler Funktionalität ausgeführt werden - angeblich zum Komfort des Nutzers. Beispiel: Browserbasierte Office-Anwendungen. Der laufende Datenaustausch mit Cloud-Speichern erfordert dabei Ajax-Technologien und damit Javascript zwingend. Schöne neue Welt ...

Es ist klar, dass diese Entwicklungen zusammen immer mehr ausführbaren Code im Browser erfordern - und dass solcher Code auch immer mehr Möglichkeiten und ggf. Rechte zur Manipulation lokaler Speicherinhalte bekommen muss.

Diese Entwicklungen werden in Kombination mit den nun bekannten Schwachstellen von Prozessoren zu einer immensen Gefahr. Staaten wie z.B. China zeigen bereits unverblümt, was sie mit den aktuellen technischen Möglichkeiten erreichen wollen: Die Kontrolle der eigenen Bürger. Warum das nicht auch auf Nutzer von APPs bzw. Webseiten, die im Auftrag von kontrollierten Firmen im Westen erstellt werden, ausweiten? Spectre liefert interessierten staatlichen Organisationen mit hinreichenden Ressourcen ganz neue Angriffspunkte, um Informationen über uns alle zu sammeln ... Das Schlimme ist, dass es bis zu einer neuen Prozessorgeneration noch kein zuverlässiger Schutz absehbar ist. Die Geister, die wir alle in unserer Gier, laufend und in allen Lebensbereichen "online" zu sein, gerufen haben, sie wenden sich nun gegen uns. Wir sollten alle beginnen, völlig neu über unsere Nutzung des Internets nachzudenken.

Open Source - Chance oder Gefahrenquelle im Spectre-Kontext?

In einem früheren Beitrag hatte ich erwähnt, dass das Umsetzen von Spectre in massenhaft nutzbare Angriffsformen die intime Kenntnis von Anwendungen und Betriebssystemen verlangt - sowie natürlich hinreichende Entwicklerkapazität mit diesen Kenntnissen. Wo ist das am meisten gegeben? Bei den Herstellern von Anwendungen und Betriebssystemen, aber natürlich auch bei staatlichen Organisationen.

Nun könnte man argumentieren, dass gerade Open Source hier ein Nachteil sei. Das Argument ist mir in Diskussionen tatsächlich schon begegnet: Schließlich eröffne ja gerade die Offenlegung der Betriebssystem- und der Anwendungscodes Hackern die Möglichkeit, sich tief einzuarbeiten und passende Code-Segmente für transiente Codeblöcke in Spectre-Angriffen auszuwählen. Stimmt - das Ausnutzen von Schwachstellen in Open Source Anwendungscode ist tatsächlich auch unabhängig von Spectre schon passiert. Aber:

Das vorgebrachte Argument gilt natürlich noch viel mehr für die Hersteller proprietärer Software und Betriebssysteme. Die dortigen Entwickler müssen sich ja gar nicht mehr einarbeiten - die kennen ihre Umgebung ja schon! Und wir als Benutzer haben bei proprietärem Code keine Chance nachzuprüfen, ob die Hersteller oder evtl. korrupte Mitarbeiter solcher Unternehmen durch Elemente ihrer Betriebssystem- oder Anwendungs-SW künftig nicht gezielt globale Schwachstellen wie Spectre ausnutzen (werden) - zu welchem Zweck auch immer. Es gibt keine wirkliche Verteidigung dagegen.

Aus den Forschungsergebnissen zu Meltdown/Spectre wird zudem klar, dass Spectre-basierte Angriffe so gut wie keine Spuren im angegriffenen System hinterlassen würden. Ein Eldorado für hinreichend skrupellose Ersteller proprietären Codes.

Aus diesen Gründen ist eine essentielle Konsequenz aus den Erkenntnissen zu Spectre und Meltdown:

Ein Umsteigen auf Open Source-Systeme ist mehr denn je notwendig! Für Privatpersonen, Unternehmen, aber auch Institutionen der öffentlichen Verwaltung.

Dieses Argument gilt dabei in ganz besonderem Maße für die öffentliche Verwaltung, die immer im Interesse der Bürger (hier Datenschutz und Datensicherheit) handeln sollte. Spectre und Meltdown lassen deshalb die Entscheidung der Stadt München, künftig auf proprietäre SW zu setzen, nicht nur unter Kosten- und Abhängigkeitsgesichtspunkten als grundfalsch erscheinen. Diese Entscheidung ist vor allem unter dem Aspekt der Sicherheit in Frage zu stellen. Gerade dann, wenn die Stadt - wie seit Jahren bekundet - verstärkt auf E-Government setzen will.

An dieser Stelle sei abschließend auf folgende Artikel verwiesen, der das Thema Datenschutz und Microsoft noch unter einem ganz anderen Gesichtspunkt beleuchtet:
http://www.handelsblatt.com/politik/international/datenschutz-in-gefahr-ende-des-internets-wie-wir-es-heute-kennen/20876998.html

Man kombiniere das dort Beschriebene einmal mit den Möglichkeiten von Spectre. Das alles ficht aber wohl die Mitglieder des Stadtrates nicht an. Die Mitarbeiter eines Beratungsunternehmens mit Hauptsitz in Dublin, welches nicht für Linux-Affinität bekannt ist, und vor allem die Chefs eines Betriebssystemherstellers aus Übersee können sich dagegen ein paar Sektgläser füllen und sich gratulieren. Ein neuer Trinkspruch von IT-lern soll ja sein: Prosit Meltdown ...

Nebenbei: Besagtes Beratungsunternehmen hat seit letztem Jahr auch die Aktienmehrheit beim größten deutschen Internetdienstleister erworben. Ein Schelm, wer da anfängt, über künftige Outsourcing-Möglichkeiten zu spekulieren ...

Im nächsten Beitrag wende ich mich weiterem Fallout von Spectre/Meltdown zu - nämlich Servern, Virtualisierung und wiederum Cloud-Diensten.

Meltdown und Spectre – Lehren aus dem Desaster? – II – Konsequenzen für Linux-User

Im letzten Artikel habe ich begonnen, Spectre und Meltdown zu kommentieren. Ich habe zudem Links zu relevanten Informationen im Internet aufgelistet. In diesem Beitrag will ich nun ein wenig darauf eingehen, was man im Moment als normaler Linux-User tun kann.

Ein normaler Linux-Anwender hat eher selten Server- oder Virtualisierungssysteme im Einsatz, die parallel von unterschiedlichen aktiven Usern genutzt werden. Er arbeitet eher als Einzelkämpfer auf einem PC/Notebook. Bedroht sind aber eben nicht nur Server, sondern eben jedes System mit halbwegs modernen Computerprozessoren - ob von Intel, AMD und auch diverse Prozessoren mit ARM-, POWER- und SPARC-Mikroarchitektur. Bedroht sind wir potentiell also alle!

Gute und schlechte Nachrichten für den normalen Linux-User

Es ist wichtig, sich als User klarzumachen, dass der Einsatz von Verschlüsselungsverfahren wie etwa PGP und Veracrypt einen nicht gegen Meltdown/Spectre schützt. Bei Nutzung solcher Tools liegen die entschlüsselten Daten ja irgendwann unverschlüsselt im Speicher vor - und gerade der wird angegriffen. Ähnliches gilt übrigens für die Passwortspeicher von Browsern.

Die zwei guten Nachrichten sind:

  • Das Ausnutzen aller drei bislang diskutierten Schwachstellen erfordert die Ausführung von Schadcode auf dem angegriffenen System. Der muss da erst mal hingelangen.
  • Meltdown lässt sich auf der Ebene der Betriebssysteme durch Kernel- also SW-Korrekturen (Patches) ausschließen. Das bedeutet gewisse Performance-Einbrüche, die aber alle noch in erträglicher Größenordnung liegen.

Die schlechten Nachrichten sind:

  • Meltdown-Angriffe können relativ leicht umgesetzt werden, eben auch aus Webseiten per Javascript heraus.
  • Glaubt man den Forschern, die zu Spectre publiziert haben, so kann man gegen ausgeklügelte Spectre-Angriffe nur Hindernisse aufbauen; sie aber womöglich nicht grundsätzlich unterbinden. Auch für Spectre gibt es übrigens Proof-Of-Concept-Szenarien für Angriffe auf Basis von Javascript und damit über das Web.
  • Ein wichtiger Gefahrenpunkt bzgl. von Angriffen aus dem Web sind Zugriffe auf seitenübergreifende Speicherinhalte des Browsers, z.B. von Passwort-Speichern. Beides wurde sowohl für Meltdown- als auch Spectre-Angriffsmuster demonstriert.
  • Bestimmte moderne Änderungen (KTPI, Retpoline) an Linux-Kerneln (in Kombination mit Microcode-Updates für die Prozessoren) sind noch nicht für LTS-Kernel umgesetzt worden - und können vermutlich auch nicht rückportiert werden.
  • Es wird noch dauern, bis neue Kernel in die üblichen Linux-Distributionen einfließen.
  • Gegen eine Variante von Spectre gibt es noch kein Heilmittel.

Konsequenzen- was kann man tun?

Die Konsequenzen für Anwender sind:

  • Kernel-Updates zum Schutz gegen Meltdown sind Pflicht. Dazu sind die SW-Repositories der jeweiligen Distribution abzufragen. Vor evtl. problematischen Linux-Kernel-Modifikationen zur Abwehr von Spectre-Angriffen (in Kombination mit Microcode_Updates für die Prozessoren) schützt uns hoffentlich die Kompetenz von Hrn. Torvalds und anderen Kernel-Spezialisten/Maitainer im Rahmen ihrer Qualitätskontrollen. Siehe hierzu: https://www.heise.de/newsticker/meldung/Absoluter-Muell-Linus-Torvalds-verliert-die-Geduld-mit-Spectre-Patches-3948756.html
  • Upgrades auf Kernelversionen, die von der eigenen Distribution und oder Treibern und Virtualisierungsanwendungen (noch) nicht unterstützt werden: Verfahren wie KPTI und Retpoline-Techniken sind nur in neueste Kernelversionen 4.14/4.15 - z.T. Vorabversionen - integriert. Ein normaler User ist beim Experimentieren mit solchen Kernels ggf. überfordert. Wer sich dennoch daran wagt und solche Kernels aus Repositories lädt, sollte sich vorab unbedingt darüber informieren, wie man den alten Kernel bootet und welche Versionen schon mit Grafikkartentreibern und Virtualisierungstools wie VMware kompatibel sind. Ansonsten ist man auf die Kernel-Updates der aktuellen Distributions-Repositories angewiesen. OpenSUSE-User sollten darauf achten, dass der Supportzeitraum für Leap 42.2 in Kürze endet!
  • Updates von Paketen mit Intel-Microcode, der Spectre-Angriffe erschwert, sind Pflicht - soweit solche Updates nicht die Stabilität der Systeme in Frage stellen. Leider kann das am 08.01.2018 publizierte Microcode-Update Instabilitäten verursachen. Siehe die Links am Ende der Seiten. Die Lage ist hier z.Z. unübersichtlich. SuSE und Red Hat haben z.B. die Intel-Microcode-Update-Pakete vom 08.01. wieder aus ihren Repositories entfernt. Im Moment liegt noch kein neueres Paket vor. Das Erscheinen neuerer Pakete für Microcode-Updates in den Repositories der Distributionen ist aber systematisch zu verfolgen.
  • Browser-Updates sind Pflicht. Die Browser-Hersteller können bestimmte Spectre-Varianten immerhin erschweren. Dazu zählt u.a. das Unterbinden von Funktionen zur hochauflösenden Zeitanalyse von Speicher-/Cache-Vorgängen.
  • Prävention: Noch mehr als zuvor ist darauf zu achten, von wo man sich Software einspielt. Deshalb sind https-Verbindungen statt http-Verbindungen zu Repository-Servern der jeweiligen Distributionen einzurichten. Für eingespielte Pakete sind die Hashes zu prüfen. Geübte Linux-Nutzer machen das sowieso; die Hash-Überprüfung nehmen einem meist Tools ab.
  • Prävention: Noch mehr als zuvor ist darauf zu achten, auf welche Webseiten man geht. NoScript-Plugins sollten im Browser im ersten Anlauf immer aktiv sein. Man sollte sich gut überlegen, für welche Domänen man Javascript oder andere Scriptsprachen überhaupt freigibt.
  • Prävention: Abschalten von Passwortspeichern in Browsern.
  • Prävention: Noch mehr als zuvor ist darauf zu achten, dass man sich nichts über E-Mail-Anhänge einfängt. Bei unbekannten Absendern oder "seltsamen" Inhalten immer zuerst den Header und seine Inhalte auf Inkonsistenzen überprüfen. IP-Adressen der Absender mit "whois" prüfen. Checken, ob im Internet zu Spams oder Malware für die Absender-IPs vorliegen. Eher mal zuviel löschen als irgendetwas in der Mail anzuklicken oder gar Anhänge zu öffnen.
  • Angesichts der Unsicherheiten, ob es bereits wirksame aber unentdeckte Angriffstools gab oder nicht, der Länge des Zeitraums seit Bekanntwerden der Schwachstellen (7 Monate) und der relativen Einfachheit von Meltdown-Angriffen, ist es auf exponierten Systemen sicher nicht verkehrt, mal alle Passwörter zu ändern.

Mehr Möglichkeiten hat der Linux-User zur Zeit wohl kaum. Im Kern also: Updaten, Repository-Änderungen für Kernel und Microcode-Pakete beobachten und ansonsten noch vorsichtiger mit Webseiten und E-Mails sein. Einige Punkte führen leider zu einer unbequemer Bedienung von Browsern und E-Mail-Programmen, aber potentieller Schaden und Nutzen sind eben abzuwägen. Wird ein Passwortspeicher ausgelesen, ist der Schaden immens.

Im nächsten Artikel gehe ich in allgemeiner Weise auf das Thema Browser und auch auf die Bedeutung von OpenSource im Kontext von Meltdown/Spectre ein.