Partitionstabelle und Bootloader wiederherstellen

ZIEL: Simulation eines eingetretenden Datenverlusts durch Überschreiben wichtiger Sektoren am Beginn der Bootfestplatte.

ACHTUNG: Das Ganze bitte mit einer virtuellen Maschine üben; außerdem vorher unbedingt einen Snapshot erstellen und diese Rettungs-CD herunterladen: https://www.system-rescue-cd.org/Download/

Wir gehen im Folgenden von einer einfachen Debian 10 Installation aus, bei der die Festplatte nicht in separate Partitionen aufgeplittet wurde („Vollständige Festplatte verwenden“, -> „Freien Speicher automatisch partitionieren“).

Das Major-Device /dev/sda ist hierbei als Bootfestplatte mit GRUB 2 ausgestattet, das Minor-Device /dev/sda1 zeigt auf die rootfs-Partition (Wurzeldateisystem), worauf auch das Verzeichnis /boot liegt.

Backup und Recovery des MBR

Bei einem Rechner mit klassischer Partitionstabelle im MBR kann man den die Sicherung auf zweierlei Art durch führen:

  1. Bootcode (440 Bytes) und Partitionstabelle (64 Bytes) gemeinsam sichern:

dd if=/dev/sda of=/root/myMBR.img count=1 bs=512
  1. Nur die Partitionstablle in Textform exportieren:

sfdisk -d /dev/sda > /root/myParttable.sfdisk

Eine spätere Recovery der Partitionstabelle ist dann einfach so möglich:

sfdisk /dev/sda < /root/myParttable.sfdisk

Simulation eines Datenverlusts

Beim alten MBR-Partitionierungsschema reicht es aus, die ersten 512 Bytes mit Nullen zu überschreiben:

dd if=/dev/zero of=/dev/sda bs=512 count=1

Damit ist sowohl der Bootcode wie auch die Partitionstabelle überschrieben worden!

Wiederherstellung der Partitionstabelle

Man bootet nun die Maschine mit Hilfe der bereits heruntergeladenen Rettungs-CD „SystemRescueCD“.

Dank des Programmes testdisk lässt sich die Partitionstabelle relativ leicht wiederherstellen. Siehe dazu die Schritt für Schritt Anleitung bei cgsecurity.org.

Wiederherstellung des Bootcodes

Nun können wir die Wurzel- bzw. die Bootpartition mounten und den Bootloader neu in den MBR installieren:

mount /dev/sda1 /mnt
grub-install --root-directory=/mnt /dev/sda

HINWEIS: Wir geben hier letztlich das Major-Device /dev/sda als Installationsziel an, d.h. hier darf keine Nummer auftauchen! Das Minor-Device /dev/sda1 repräsentiert nicht den MBR, lediglich die Wurzelfläche, wo sich auch /boot befindet.

Backup und Recovery der GPT-Partitionstabelle (UEFI-System)

Grundlegende Informationen zum neuartigen Partitionierungsschema sind hier zu finden. Bitte beachten, dass wir nun eine virtuelle Maschine mit UEFI benötigen, was in VirtualBox unter „System“ zu finden ist, Option „EFI aktivieren (nur spezielle Gäste)“. Ansonsten wird wie Eingangs beschrieben, eine einfache Debian 10 Installation ohne manuelle Aufsplittung durchgeführt.

Mit ‚dd‘ die ersten 512 Bytes zu sichern, macht hier allerdings keinen Sinn (Schutz-MBR; von englisch protective MBR), wir müssen gleich ein passendes Tool nehmen (aus dem Paket „gdisk“):

sgdisk -b /root/myGUID-Table.sgdisk /dev/sda

Eine spätere Wiederherstellung kann dann mit

sgdisk -l /root/myGUID-Table.sgdisk /dev/sda

geschehen.

Simulation eines Datenverlusts

Wir müssen diesmal mehr als nur 512 Bytes überschreiben, Grund ist das neue GPT-Format. Wir schreiben jetzt ganz kühn 20 MByte an den Anfang der Festplatte:

dd if=/dev/zero of=/dev/sda bs=1M count=20

Ein Test, ob sich das Debian-System noch booten lässt, schlägt natütlich fehl…

VM mit Rettungssystem booten

Wie oben beschrieben, booten wir die Maschine wiederum mit SystemRescueCD.

Kleiner Hinweis zu Beginn: Falls man sich als root per ssh in das Rettungssystem einloggen möchte, sind dort diese Schritte erforderlich:

ip addr
systemctl stop iptables
passwd root

Im gebooteten Rettungssystem schauen wir uns nun um. Siehe dazu diese Shell-Sitzung:

[root@sysresccd ~]# lsblk -f
NAME  FSTYPE   FSVER LABEL     UUID                                 FSAVAIL FSUSE% MOUNTPOINT
loop0 squashfs 4.0                                                        0   100% /run/archiso/sfs/airootfs
sda
sr0   iso9660        SYSRCD611 2020-03-13-18-13-46-00                     0   100% /run/archiso/bootmnt
[root@sysresccd ~]#
[root@sysresccd ~]# fdisk -l
Disk /dev/sda: 50 GiB, 53687091200 bytes, 104857600 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes


Disk /dev/loop0: 622.6 MiB, 652832768 bytes, 1275064 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
[root@sysresccd ~]#

Wie erwartet: die Katastrophe ist eingetreten!

Zur Wiederherstellung der Partitionstabelle müssen wir hier allerdings nicht testdisk bemühen - das Kommando gdisk kann die Vorteile der neuen GUID Partition Table ausschöpfen und die Kopie der Partitionstabelle am Ende der Platte hervorholen:

[root@sysresccd ~]# gdisk /dev/sda
GPT fdisk (gdisk) version 1.0.5

Caution: invalid main GPT header, but valid backup; regenerating main header
from backup!

Warning: Invalid CRC on main header data; loaded backup partition table.
Warning! Main and backup partition tables differ! Use the 'c' and 'e' options
on the recovery & transformation menu to examine the two tables.

Warning! Main partition table CRC mismatch! Loaded backup partition table
instead of main partition table!

Warning! One or more CRCs don't match. You should repair the disk!
Main header: ERROR
Backup header: OK
Main partition table: ERROR
Backup partition table: OK

Partition table scan:
MBR: not present
BSD: not present
APM: not present
GPT: damaged

Found invalid MBR and corrupt GPT. What do you want to do? (Using the
GPT MAY permit recovery of GPT data.)
1 - Use current GPT
2 - Create blank GPT

Your answer: 1

Command (? for help): p
Disk /dev/sda: 104857600 sectors, 50.0 GiB
Model: VBOX HARDDISK
Sector size (logical/physical): 512/512 bytes
Disk identifier (GUID): 2E7CA117-D2CD-4107-8667-D7A4566F9BF8
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 104857566
Partitions will be aligned on 2048-sector boundaries
Total free space is 4045 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
1            2048         1050623   512.0 MiB   0700
2         1050624       101687295   48.0 GiB    8300
3       101687296       104855535   1.5 GiB     8200

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.
[root@sysresccd ~]#

Und schon können wir wieder etwas erkennen:

[root@sysresccd ~]# lsblk -f
NAME   FSTYPE   FSVER LABEL     UUID                                 FSAVAIL FSUSE% MOUNTPOINT
loop0  squashfs 4.0                                                        0   100% /run/archiso/sfs/airootfs
sda
├─sda1
├─sda2 ext4     1.0             3121356d-039d-4d5f-a657-d44f5f027119
└─sda3 swap     1     SWAP      26f23c85-83f8-4d3b-a398-ef7141a3efb9
sr0    iso9660        SYSRCD611 2020-03-13-18-13-46-00                     0   100% /run/archiso/bootmnt
[root@sysresccd ~]#

Wir versuchen uns am Mounten und haben bereits Teilerfolge. Nur die EFI System Partition (ESP) muss wiederhergestellt werden, das rootfs ist ok:

[root@sysresccd ~]# mount /dev/sda1 /mnt/
mount: /mnt: wrong fs type, bad option, bad superblock on /dev/sda1, missing codepage or helper program, or other error.
[root@sysresccd ~]#
[root@sysresccd ~]# mount /dev/sda2 /mnt/
[root@sysresccd ~]#
[root@sysresccd ~]# ls -F /mnt/
bin@   dev/  home/        initrd.img.old@  lib32@  libx32@      media/  opt/   root/  sbin@  sys/  usr/  vmlinuz@
boot/  etc/  initrd.img@  lib@             lib64@  lost+found/  mnt/    proc/  run/   srv/   tmp/  var/  vmlinuz.old@
[root@sysresccd ~]#
[root@sysresccd ~]# cat /mnt/etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point>   <type>  <options>       <dump>  <pass>
# / was on /dev/sda2 during installation
UUID=3121356d-039d-4d5f-a657-d44f5f027119 /               ext4    errors=remount-ro 0       1
# /boot/efi was on /dev/sda1 during installation
UUID=5642-1117  /boot/efi       vfat    umask=0077      0       1
# swap was on /dev/sda3 during installation
#LABEL=SWAP      none            swap    sw              0       0
/dev/sr0        /media/cdrom0   udf,iso9660 user,noauto     0       0
UUID=26f23c85-83f8-4d3b-a398-ef7141a3efb9  none swap  sw  0  0
[root@sysresccd ~]#
[root@sysresccd ~]# umount /dev/sda2

Kümmern wir uns also um /dev/sda1, unsere ESP-Partition für den EFI Bootloader. Wie wir oben an „wrong fs type, bad option, bad superblock on /dev/sda1“ erkannt haben, ist das Dateisystem pfutsch. Wir bringen einfach ein neues auf, wobei wir schlauerweise gleich die alte Volume-ID, so wie wir sie eben bei cat /mnt/etc/fstab gesehen haben, wiederverwenden (ohne Bindestrich zwischen den 4 Ziffern). Und wir testen das Ganze auch gleich aus:

[root@sysresccd ~]# mkfs.vfat -i 56421117 /dev/sda1
mkfs.fat 4.1 (2017-01-24)
[root@sysresccd ~]#
[root@sysresccd ~]# lsblk -f
NAME   FSTYPE   FSVER LABEL     UUID                                 FSAVAIL FSUSE% MOUNTPOINT
loop0  squashfs 4.0                                                        0   100% /run/archiso/sfs/airootfs
sda
├─sda1 vfat     FAT32           5642-1117
├─sda2 ext4     1.0             3121356d-039d-4d5f-a657-d44f5f027119   43.5G     2% /mnt
└─sda3 swap     1     SWAP      26f23c85-83f8-4d3b-a398-ef7141a3efb9
sr0    iso9660        SYSRCD611 2020-03-13-18-13-46-00                     0   100% /run/archiso/bootmnt
[root@sysresccd ~]#
[root@sysresccd ~]# mount /dev/sda1 /mnt/
[root@sysresccd ~]#
[root@sysresccd ~]# df -h /mnt/
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda1       511M  4.0K  511M   1% /mnt
[root@sysresccd ~]#
[root@sysresccd ~]# umount /dev/sda1

Fehlt nur noch das Neuinstallieren von GRUB, was sich auf diesem EFI-System ein wenig anders gestaltet - es wird nämlich als Installationsort kein Major-Device (MBR!) und auch keine andere Gerätedatei angegeben, sondern die Verzeichnisse /boot/efi (= EFI-Bootmanager) und /boot (= Bootloader im Unterverzeichnis /boot/grub). Desweiteren wird „debian“ als Name für den Booteintrag verwendet, der mit der Bezeichnung übereinstimmen muss, die im EFI-Bootmanager verwendet wird (--bootloader-id=debian). Die betreffende Zeile sieht so aus:

grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --boot-directory=/boot --recheck

Und hier die Shell-Sitzung im Ganzen:

[root@sysresccd ~]# mount /dev/sda2 /mnt/
[root@sysresccd ~]# mount --bind /proc/ /mnt/proc/
[root@sysresccd ~]# mount --bind /dev/ /mnt/dev
[root@sysresccd ~]# mount --bind /sys /mnt/sys
[root@sysresccd ~]# chroot /mnt/
root@sysresccd:/# swapon -av
bash: swapon: command not found
root@sysresccd:/#
root@sysresccd:/# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/site_perl:/usr/bin/vendor_perl:/usr/bin/core_perl
root@sysresccd:/#
root@sysresccd:/# export PATH=/sbin:/usr/sbin:$PATH
root@sysresccd:/#
root@sysresccd:/# swapon -av
swapon: /dev/sda3: found signature [pagesize=4096, signature=swap]
swapon: /dev/sda3: pagesize=4096, swapsize=1622138880, devsize=1622138880
swapon /dev/sda3
root@sysresccd:/#
root@sysresccd:/# mount -av
/                        : ignored
/boot/efi                : successfully mounted
/media/cdrom0            : ignored
none                     : ignored
root@sysresccd:/#
root@sysresccd:/# df -h
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2        47G  1.2G   44G   3% /
dev             706M     0  706M   0% /dev
/dev/sda1       511M  4.0K  511M   1% /boot/efi
root@sysresccd:/#
root@sysresccd:/#
root@sysresccd:/# grub-install --target=x86_64-efi --efi-directory=/boot/efi --bootloader-id=debian --boot-directory=/boot --recheck
Installing for x86_64-efi platform.
grub-install: warning: EFI variables are not supported on this system..
Installation finished. No error reported.
root@sysresccd:/#
root@sysresccd:/#
root@sysresccd:/# ls -lR /boot/efi/
/boot/efi/:
total 4
drwx------ 3 root root 4096 Jun  7 17:44 EFI

/boot/efi/EFI:
total 4
drwx------ 2 root root 4096 Jun  7 17:44 debian

/boot/efi/EFI/debian:
total 5208
-rwx------ 1 root root     108 Jun  7 17:44 BOOTX64.CSV
-rwx------ 1 root root 1206824 Jun  7 17:44 fbx64.efi
-rwx------ 1 root root     126 Jun  7 17:44 grub.cfg
-rwx------ 1 root root 1529200 Jun  7 17:44 grubx64.efi
-rwx------ 1 root root 1261192 Jun  7 17:44 mmx64.efi
-rwx------ 1 root root 1322936 Jun  7 17:44 shimx64.efi
root@sysresccd:/#
root@sysresccd:/# umount -a
umount: /dev: target is busy.
root@sysresccd:/#
root@sysresccd:/# exit
exit
[root@sysresccd ~]#
[root@sysresccd ~]# umount -a
umount: /mnt/dev: target is busy.
umount: /mnt: target is busy.
umount: /run/user/0: target is busy.
umount: /etc/pacman.d/gnupg: target is busy.
umount: /sys/fs/cgroup/unified: target is busy.
umount: /sys/fs/cgroup: target is busy.
umount: /run/archiso/bootmnt: target is busy.
umount: /run: target is busy.
umount: /dev: target is busy.
[root@sysresccd ~]#
[root@sysresccd ~]# poweroff

Vor dem Neustart nicht vergessen, die SystemRescueCD zu entfernen, … - und nun heißt es

„Have a lot of fun…“