Der Bootloader Grub, der für den Start des Betriebssystems genutzt wird, kann auch mit verschlüsselten Dateisystemen umgehen und von diesen den Kernel und die Initrd laden. Wenn von der CPU eine Unterstützung für die Verschlüsselung vorhanden ist und somit Datenraten von über 1 GiB/s erreicht werden, sollte nicht nur die Datenpartition, sondern das komplette Linux-System verschlüsselt werden – die EFI-Partition bzw. der Grub-Loader müssen weiterhin unverschlüsselt bleiben.

Die Verschlüsselung der Festplatte hat für mich zwei Gründe: (1) mir sind schon mehrere Festplatten und USB-Sticks kaputt gegangen und ich stand vor dem Problem, dass ich sie ungern in dem Zustand entsorgen wollte, weil ein geneigter Bastler (sie beim Wertstoffhof abholt und) die Festplatte wieder zum Leben erwecken und SSH-, GPG-Schlüssel und Dokumente auslesen kann. Der weitere Grund (2) ist für mich die Gefahr, dass ich meinen Laptop (oder USB-Stick) doch mal irgendwo verliere oder er mir gestohlen wird.

Einrichten der Verschlüsselung

Zur Installation eines Systems nutze ich entweder ein Debian-Live-System oder die Grml. In der Anleitung von Debian sind viele hilfreiche Informationen zu finden, an denen ich mich auch orientiert habe.

Partitionierung

Wenn die Festplatte die die einzige Festplatte des Rechners ist, muss man eine kleine unverschlüsselte Partition für EFI anlegen. Für Grub allein genügen 5 MiB, kommt Windows noch dazu sollte man 50 MiB einplanen. Falls es eine zusätzliche Festplatte ist, kann komplett auf die im folgenden beschriebene Partitionierung verzichten werden und die verschlüsselten Daten direkt in /dev/sdb statt /dev/sda2 abgelegt werden.

% sudo fdisk /dev/sda

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

Command (m for help): g

Created a new GPT disklabel (GUID: A01F270B-1B9F-DD48-B9C9-316CF47B70C1).

Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-31457246, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-31457246, default 31457246): +50M

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

Command (m for help): t
Selected partition 1
Partition type or alias (type L to list all): 1
Changed type of partition 'Linux filesystem' to 'EFI System'.

Command (m for help): n
Partition number (2-128, default 2):
First sector (104448-31457246, default 104448):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (104448-31457246, default 31457246): 

Created a new partition 2 of type 'Linux filesystem' and of size 15 GiB.

Command (m for help): p
Disk /dev/sdc: 15 GiB, 16106127360 bytes, 31457280 sectors
Disk model: Flash Disk
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: gpt
Disk identifier: A01F270B-1B9F-DD48-B9C9-316CF47B70C1

Device      Start      End  Sectors Size Type
/dev/sdc1    2048   104447   102400  50M EFI System
/dev/sdc2  104448 31457246 31352799  15G Linux filesystem

Verschlüsselung

Bei der Verschlüsselung muss man darauf achten, das Format luks1 zu verwenden, da Grub das neuere Format luks2 noch nicht unterstützt. Wie man von luks2 zu luks1 wechseln kann, ist in der Anleitung von Debian beschrieben.

  1. Verschlüsselung des Systems: cryptsetup luksFormat --type luks1 /dev/sda2
  2. Einbinden des entschlüsselten Geräts: cryptsetup open /dev/sda2 sda2_crypt
  3. Einrichten von LVM: vgcreate Linux_vg /dev/mapper/sda2_crypt
  4. LVM-Volumns einrichten:
    • lvcreate -L 64G -n Linux_Root Linux_vg und
    • lvcreate -l 100%FREE -n Linux_Var Linux_vg
    • (prüfen der Volumns mit lvs)
  5. Erstellen der Dateisysteme:
    • EFI verlangt ein FAT32: mkfs.vfat -F 32 /dev/sda1
    • mkfs.ext4 -M / -L Linux_Root /dev/mapper/Linux_vg-Linux_Root
    • mkfs.ext4 -M /var -L Linux_Var -E lazy_itable_init,lazy_journal_init /dev/mapper/Linux_vg-Linux_Var
  6. debootstrap oder Installer
  7. echo "GRUB_ENABLE_CRYPTODISK=y" >>/etc/default/grub && update-grub
  8. automatische Entschlüsselung nach dem Bootmenü:
    1. mkdir -m0700 /etc/keys
    2. ( umask 0077 && dd if=/dev/urandom bs=1 count=64 of=/etc/keys/sda2.key conv=excl,fsync )
    3. cryptsetup luksAddKey --key-slot=1 /dev/sda2 /etc/keys/sda2.key
    4. /etc/crypttab: sda2_crypt UUID=… /etc/keys/sda2.key luks,discard,key-slot=1
    5. echo "KEYFILE_PATTERN=\"/etc/keys/*.key\"" >>/etc/cryptsetup-initramfs/conf-hook
    6. echo UMASK=0077 >>/etc/initramfs-tools/initramfs.conf
    7. update-initramfs -u
    8. lsinitramfs /initrd.img | grep "^cryptroot/keyfiles/"

Verschlüsseltes System auf größere Platte übertragen

  1. Bestehendes System einbinden:
    1. Entschlüsseln: cryptsetup open --readonly /dev/sda2 sda2_crypt
    2. Volumns anmelden: vgscan
    3. Volumns aktivieren: vgchange -ay
  2. Verschlüsselung des Systems: cryptsetup luksFormat --type luks1 /dev/sdb
  3. Einbinden des entschlüsselten Geräts: cryptsetup open /dev/sdb sdb_crypt
  4. LVM einrichten: vgcreate neu /dev/mapper/sdb_crypt
  5. LVM-Volumns erstellen:
    1. lvcreate -L 64G -n Linux_Root neu und
    2. lvcreate -l 100%FREE -n Linux_Var neu
    3. (prüfen der Volumns mit lvs)
  6. Übertragen der alten Daten und anpassen der Partitionen:

    for i in Root Var; do
        dd if=/dev/mapper/Linux_vg-Linux_$i of=/dev/mapper/neu-Linux_$i bs=20M status=progress \
          && e2fsck -fy /dev/mapper/neu-Linux_$i
          && resize2fs /dev/mapper/neu-Linux_$i
    done
    
  7. altes System entfernen:

    1. vgchange -a n Linux_vg
    2. cryptsetup close sda2_crypt
  8. neuen Volumns deaktivieren und umbenennen:
    1. lvchange -a n neu
    2. vgrename neu Linux_vg
    3. cryptsetup close sdb_crypt

Große Schrift und deutsche Tastatur fürs Passwort

Anhand der Anleitung für Debian habe ich auch die deutsche Tastaturbelegung für die Passworteingabe eingerichtet und damit auch eine Lösung für die unleserlich kleine Schrift (4k-Monitor, HiRes) bei der Passworteingabe gefunden:

% cat /boot/grub/early.cfg
set gfxmode=auto
loadfont (memdisk)/DejaVuSansMono-highres.pf2
terminal_output gfxterm

terminal_input --append at_keyboard
keymap (memdisk)/keymap.gkb

cryptomount -u 378253ee9b3b4416ade5d2e01deba0fb

set root=(lvm/Linux_vg-Linux_Root)
set prefix=/boot/grub

% sudo grub-kbdcomp -o /boot/grub/keymap.gkb de nodeadkeys
% sudo grub-mkfont -s 42 -o /boot/grub/DejaVuSansMono-highres.pf2 /usr/share/fonts/truetype/dejavu/DejaVuSansMono.ttf
% tar cf /tmp/img.tar -C /boot/grub DejaVuSansMono-highres.pf2 keymap.gkb

% sudo grub-mkimage --directory /usr/lib/grub/x86_64-efi --format x86_64-efi \
    --output /boot/efi/EFI/debian/grubx64.efi --compression auto \
    --config /boot/grub/early.cfg --memdisk=/tmp/img.tar ext2 lvm cryptodisk luks \
    gcry_rijndael gcry_rijndael gcry_sha256 memdisk tar font gfxterm efi_gop \
    terminal keylayouts at_keyboard

Die Liste der Module habe ich aus der Ausgabe von grub-install -v und der grub.cfg. Die ID für cryptomount lässt sich mit blkid -o value -s UUID /dev/sdb |tr -d - ermitteln oder ebenfalls aus der grub.fg entnehmen.

In der Anleitung ist auch beschrieben, wie man ein Passworteingabe nach dem Grub-Menü vermeiden kann. Allerdings musste ich bei mir die Angabe des Key-Slots in der crypttab weglassen, da sonst nicht die Festplatte automatisch entschlüsselt wird.

Befehle für grub rescue

Wenn man zum Beispiel durch die Eingabe des falschen Passworts an der Eingabeaufforderung von grub rescue landet, kann man mit folgenden Befehlen die Passworteingabe und anschließend das Bootmenü erreichen:

cryptomount hd1 # oder hd0,gpt2
insmod normal
normal

Gegebenenfalls muss man mit set noch die Variablen prefix und root anpassen.

Weitere Informationen