In den Tiefen des Boot-Vorgangs: Systemd-boot

  Dante Calabresi   Lesezeit: 11 Minuten  🗪 6 Kommentare

Der Bootloader GRUB lässt sich auf älteren Systemen durch das modernere Systemd-Boot ersetzen.

in den tiefen des boot-vorgangs: systemd-boot

Datenträger (vor allem mobile) sollten in aller Regel mit einer Verschlüsselung gesichert sein. Eine aktuelle Meldung hat mich veranlasst, die Verschlüsselung meines Laptops zu prüfen.
Ergebnis: die LUKS Verschlüsselung sollte auf den aktuellen Stand gebracht werden.
Es zeigte sich jedoch, dass GRUB keine state-of-the-art Laufwerkverschlüsselung unterstützt und deshalb das Booten von einem so verschlüsselten Datenträger verunmöglicht.
Die Lösung dafür lautet Systemd-Boot.
Dabei handelt es sich um einen modernen, schlanken Bootloader, welcher das Starten eines GNU/Linux-Systems von verschlüsselten Datenträgern erlaubt (und noch einiges mehr).

In diesem Artikel möchte ich die Einrichtung und Konfiguration von Systemd-Boot beschreiben.
Ein Folgeartikel greift allenfalls noch weitere Möglichkeiten von Systemd-Boot auf.


DISCLAIMER: Am einfachsten lässt sich Systemd-Boot bei der Neuinstallation eines GNU/Linux-Systems einrichten (z. B. mit archinstall ). Dieser Variante sollte jederzeit der Vorzug gegeben werden. Die hier aufgeführten Schritte dienen vorwiegend zu Lehrzwecken und sind in keiner Weise Best Practice und funktionieren nach Kernel-Updates möglicherweise nicht mehr.

Einrichten von Systemd-Boot (neben GRUB) mit LUKS

Ich habe die Informationen zu diesem Artikel aus diversen Quellen zusammengetragen [1], [2], [3] und dieser Artikel orientiert sich am Aufbau des c't Artikel von Keywan Tonekaboni.

Bei Arbeiten am Boot-Vorgang des eigenen System ist ein funktionierendes Backup Pflicht und man sollte immer einen bootfähigen USB-Stick mit einem Live-System zur Hand zu haben, falls man sich seinen System-Start zerschiesst.

Bootsituation analysieren

Auf einem modernen UEFI-System zeigt der Befehl

$ efibootmgr

eine Liste der aktuellen Boot-Optionen und deren Reihenfolge an.

BootCurrent: 0004
Timeout: 0 seconds
BootOrder: 0004,0003,0000,0001
Boot0000* UEFI KXG60ZNV1T02 NVMe KIOXIA 1024GB [...]
Boot0001* Linux Firmware Updater [...]
Boot0003* ubuntu [...]
Boot0004* EndeavourOS [...]


Zudem lässt sich mit

$ mokutil --sb-state

feststellen, ob SecureBoot aktiviert ist. Für diesen Artikel gehe ich davon aus, dass SecureBoot deaktiviert ist (was allenfalls im UEFI-BIOS eures Computers angepasst werden kann).

Zudem sollte in eurer /etc/fstab die EFI System Partition, üblicherweise /boot/efi, identifiziert werden.

Systemd-Boot installieren

Systemd-Boot lässt sich (am üblichen Pfad /boot/efi) mit dem Befehl

$ bootclt install

sehr einfach installieren. Danach erscheint im efibootmgr ein neuer Eintrag Linux Boot Manager, welcher nun als default gesetzt ist.

BootCurrent: 0005
Timeout: 0 seconds
BootOrder: 0005,0004,0003,0000,0001
[...]
Boot0005* Linux Boot Manager [...]

Ein Neustart würde nun fehlschlagen, da Systemd-Boot zwar aktiv, aber noch nicht konfiguriert ist.

Systemd-Boot konfigurieren

Nun müssen wir im neuen Boot-Manager noch einen Eintrag für unser System eintragen. Diese werden im Verzeichnis /boot/efi/loader/entries abgelegt. Allerdings lässt sich dies mit dem Befehl kernel-install automatisch erledigen.

Hier stellte sich mir jedoch eine erste Herausforderung. kernel-install erzeugt das initramfs aufgrund von /etc/mkinitcpio.conf. Das Booten mit GRUB benötigt jedoch andere Kernel-Parameter als Systemd-Boot, weshalb diese Konfiguration angepasst werden muss.

Da ich meine GRUB Konfiguration als Fallback behalten wollte, griff ich zum folgenden (etwas uneleganten) Hack zum erstellen des Kernel und des entsprechenden Eintrags:

1. mkinitcpio.conf kopieren


$ cp /etc/mkinitcpio.conf /etc/mkinitcpio-systemd.conf

2. Kernel-Parameter in mkinitcpio-systemd.conf für Systemd-Boot anpassen

[...]
HOOKS="systemd keyboard keymap sd-vconsole block sd-encrypt autodetect modconf filesystems fsck"
[...]

3. kernel-install mit der angepassten mkinitcpio-systemd.conf ausführen

In der Konfigurationsdatei /usr/lib/kernel/install.d/50-mkinitcpio.install die Variable GENERATOR_CMD um das folgende --config Argument ergänzen.

GENERATOR_CMD=(mkinitcpio -k "$KERNEL_VERSION" --config /etc/mkinitcpio-systemd.conf)

Anschliessend den angepassten Kernel (und entsprechenden Eintrag) generieren.

$ kernel-install -v add $(uname -r) /boot/vmlinuz-linux


Nun zeigt der Aufruf von

$ bootctl list

einen Eintrag des neuen Kernels mit euere _MACHINE_ID_ und _KERNEL_ unter ```/boot/efi/loader/entries/MACHINE_ID-KERNEL```

Dieser Eintrag muss nun noch angepasst werden für das Booten von einem verschlüsselten Datenträger.


Dazu muss die UUID des LUKS-Datenträger ermittelt werden:

$ lsblk --output=NAME,UUID

NAME          UUID
nvme0n1       
├─nvme0n1p1   XXXX-XXXX
└─nvme0n1p2   39e4d8c4-18b9-11ee-be56-0242ac120002 <<===
  └─cryptroot 21cffcfa-18b9-11ee-be56-0242ac120002


Dabei die UUID der Festplatten-Partition kopieren, nicht diejenige des LUKS-Containers.

Die UUID muss nun bei options in /boot/efi/loader/entries/MACHINE_ID-KERNEL eingetragen werden


options    root=/dev/mapper/cryptroot rd.luks.name=UUID=cryptroot


Mit bootclt list und efibootmgr last sich prüfen, ob alles korrekt übernommen wurde.

BE BRAVE

Nach einem Neustart sollte nun während des Bootvorgangs das Passwort für den LUKS Container abgefragt und danach das Betriebssystem gestartet werden.

Im Notfall kann über das UEFI-Bootmenu immer noch via GRUB gestartet werden.

In meinem Fall klappte der Bootvorgang im ersten Anlauf nicht. Nach einem Boot mit GRUB und einem weiteren Neustart, klappte es dann jedoch problemlos.

Automatisches Upgraden


Damit bei einem Kernel-Upgrade der neue Kernel auch für Systemd-Boot installiert wird, sind folgende zusätzliche Anpassungen nötig.

Anpassen von kernel-install

In der Datei /usr/lib/kernel/install.d/90-loaderentry.install muss BOOT_OPTIONS angepasst werden.


# BOOT_OPTIONS="${BOOT_OPTIONS% }"
BOOT_OPTIONS="root=/dev/mapper/cryptroot rd.luks.name=UUID=cryptroot"


kernel-install automatisch ausführen


Es sollte zudem ein hook hinterlegt werden, der beim Update des linux-kernels ausgeführt wird und kernel-install aufruft.
Dabei wird der neue Eintrag automatisch als default gesetzt.

In meinem System habe ich dabei die folgende Datei in /usr/share/libalpm/hooks/eos-systemd-boot-update-kernel.hook abgelegt.

[Trigger]
Operation = Install
Operation = Upgrade
Type = Package
Target = linux

[Action]
Description = Update kernel for systemd-boot after upgrading a kernel.
When = PostTransaction
Depends = systemd
Exec = kernel-install -v add $(uname -r) /boot/vmlinuz-linux



Ausblick

Das Booten mit Systemd-Boot bietet einige Vorteile. Unter anderem kann im LUKS-Header auch ein Hardware-Token zur Entschlüsselung hinterlegt werden. Somit lässt sich das langwierige Eintippen des Passworts beim Systemstart mit eine Knopfdruck auf einen FIDO2-Token abkürzen.

Das Umstellen der des LUKS-Header auf die aktuellen Verschlüsselungs-Algorithmen werde ich noch etwas hinausschieben, da dies möglicherweise mein GRUB-Systemstart verunmöglicht und ich noch abwarten möchten, wie sich das System bei einem Kernel-Update verhält.

Quellen

[1] https://www.heise.de/ratgeber/Linux-Kernel-mit-Systemd-Boot-gekonnt-starten-5024202.html

[2] https://wiki.archlinux.org/title/Systemd-boot

[3] https://root.nix.dk/en/manjaro-cli-install/systemd-boot-luks-ext4

Tags

systemd, boot, grub, luks, verschlüsselung

tuxnix
Geschrieben von tuxnix am 4. Juli 2023 um 16:58
tuxnix
Geschrieben von tuxnix am 4. Juli 2023 um 18:06

@Dante Calabresi Mein zweiter Post zu deinem tollen Artikel beinhaltet eine Bitte. Könntest du deine Anleitung auch in das deutsche ArchWiki einfliessenassen? Das wäre toll! Zum einen fehlt dort noch eine Anleitung wie man von grub zu systemd-boot bei einem verschlüsseltem System wechselt. Und zum Anderen ist die Arch Wiki natürlich auch der Ort an dem Anleitungen dann auch aktuell gehalten werden können.

no-new-BE
Geschrieben von no-new-BE am 4. Juli 2023 um 22:08

Ich finde , es wäre toll die Finger weg von systemd lassen und lieber dinit (s6 für dummies) oder runit (bombenfest stabil) ausprobieren. Es gibt genug distros, welche klar über systemd=(agent) zu bevorzugen sind. Ich habe in letzen 2 Jahren keine Problemme mit dinit und runit mit meinem Artix, Void, Devuan, Obarun, Alpine, Venom, Funtoo, PClinux, etc.

NLP
Geschrieben von NLP am 5. Juli 2023 um 08:37

Interessanter Artikel, danke. Was die Vorteile anbetrifft: Mit einem Hardware-Token alternativ zum Passwort booten zu können, habe ich mir auch unter GRUB2 einrichten können, das ist also offensichtlich keine exklusive Möglichkeit von SystemD-Boot. Dafür habe ich festgestellt, dass es auf den Systemen, auf denen ich es eingerichtet habe, deutlich schneller bootet, als GRUB das tat.

PS: Der Begriff "allenfalls" meint etwas anderes, als du damit scheinbar aussagen willst. Beide Sätze mit allenfalls ergeben in meinem Sprachverständnis keinen Sinn. Beim ersten Satz würde ich an der Stelle vermutlich "ggf." / "gegebenenfalls" nutzen, im zweiten Satz "andernfalls".

kamome
Geschrieben von kamome am 5. Juli 2023 um 10:00

Danke für den Artikel! Aus der „aktuellen Meldung“:

Also, if you're using an encrypted /boot, stop now - very recent versions of grub2 support LUKS2, but they don't support argon2id, and this will render your system unbootable.

Um momentan noch bei Grub zu bleiben, installiere ich dann doch lieber LUKS2-vollverschlüsselt (mit /boot) und lebe mit einer etwas schwächeren KDF – für Debianer macht das ziemlich einfach z. B. SpiralLinux. Und sobald Grub dann stärkere KDF unterstützt, kann man ja ein Upgrade wagen (oder zu systemd-boot wechseln).

Anselm Schüler
Geschrieben von Anselm Schüler am 7. Juli 2023 um 16:56

Ich glaube, in diesen Artikel haben sich Tippfehler eingeschlichen—die CLI für systemd-boot heißt bootctl, nicht bootclt. Ich kann nirgendwo ein Programm namens bootclt finden. Scheint aber ein häufiger Fehler zu sein, der Gleiche findet sich auch im Arch Wiki.