LUKS mit TPM 2.0 zusätzlich sichern

LUKS (dm-crypt) ist die Standardverschlüsselungsmethode. Dank systemd ist ein vollständig mit LUKS verschlüsseltes Linux-Betriebssystem mittels FIDO2 oder TPM zu entsperren. Das kann in Kombination mit anderen Schutzmechanismen Sinn ergeben.

TPM und ein modernes Sicherheitskonzept

Ein Passwort reicht nicht mehr aus, um Konten und Geräte zu sichern. Immer häufiger kommt ein zweiter Faktor ins Spiel. Dabei geht es um die Kombination von Besitz (zusätzlicher Hardware) und Wissen (Passwort), um ein Speichermedium zu entsperren. Dadurch können durch Phishing abgegriffene Zugangsdaten nicht mehr so großen Schaden anrichten. Anstelle eines Sicherheitschips oder einer Smartcard bietet sich als zusätzliche Möglichkeit das in allen modernen Computern und Notebooks eingebaute TPM 2 an, das nur entschlüsselt werden kann, wenn zusätzlich das richtige Trusted Platform Module (TPM) vorhanden ist und die Hardware nicht manipuliert wurde.

Eine solche zusätzliche Sicherung schützt vor einem sogenannten “Evil Maid”-Angriff, bei dem das Speichermedium entwendet oder ein Systemabbild erstellt wird. Denn Angriffe auf ein verschlüsseltes System sind mit einem solchen Image wesentlich einfacher durchzuführen. An dieser Stelle kommt das TPM ins Spiel, denn während Manipulationen an der Hardware bei LUKS im Normalbetrieb nicht auffallen, scheitert der Bootvorgang bei Absicherung durch ein TPM, sobald das Speichermedium in eine andere Hardware gesteckt wird oder – und das ist der zweite relevante Punkt – sofern jemand in den Secure Boot eingegriffen hat.

Eine Bindung der LUKS-Verschlüsselung an TPM 2 kann mit verschiedenen anderen Sicherheitsfunktionen kombiniert werden. Wahlweise ein zusätzlicher alphanumerischer PIN oder eine zusätzliche Verschlüsselung des Home-Verzeichnisses, z.B. mit systemd-homed.

LUKS mit TPM entsperren am Beispiel von openSUSE

Die folgende Anleitung basiert auf openSUSE Tumbleweed, weil die SUSE-Entwickler hier bereits erste relevante Vorarbeiten geleistet haben. Sie lässt sich aber auch auf andere moderne Linux-Distributionen übertragen, die mit Standardtools wie systemd oder dracut arbeiten.

LUKS-Container konvertieren

Das relevante Werkzeug systemd-cryptenroll kann nur mit LUKS2-Containern umgehen. OpenSUSE legt bei der Installation aber immer noch einen LUKS1-Container an. Ältere Installationen anderer Distributionen verfügen meist auch noch über LUKS1-Container. Deshalb muss in einem ersten Schritt dieser LUKS konvertiert werden. Das ist einfach und klappt zuverlässig. Einfach mit einem Live-Medium starten und mit folgendem Befehl den LUKS-Container konvertieren:

# cryptsetup convert /dev/<laufwerk> --type luks2 Code-Sprache: HTML, XML (xml)

Partitionsschema

Konzeptionell bedingt funktioniert die hier beschriebene Methode aktuell nur, wenn eine unverschlüsselte Boot-Partition zum Einsatz kommt. Ein Partitionsszenario kann wie folgt ausssehen:

:~> sudo lsblk 
NAME                                                MAJ:MIN RM   SIZE RO TYPE  MOUNTPOINTS
nvme0n1                                             259:0    0 476,9G  0 disk  
├─nvme0n1p1                                         259:1    0   300M  0 part  /boot/efi
├─nvme0n1p2                                         259:2    0     1G  0 part  /boot
└─nvme0n1p3                                         259:3    0 475,6G  0 part  
  └─cr_nvme-SAMSUNG_MZVLQ512HALU-000H1_S4UHNF0NA02912-part3
                                                    254:0    0 475,6G  0 crypt 
    ├─vg--system-lv--system                         254:1    0    20G  0 lvm   /var
    │                                                                          /usr/local
    │                                                                          /srv
    │                                                                          /root
    │                                                                          /opt
    │                                                                          /
    └─vg--system-lv--benutzerdaten                  254:2    0 455,6G  0 lvm   /home/gheim
                                                                               /home
Code-Sprache: JavaScript (javascript)

LUKS an TPM 2 binden

Um TPM anzusteuern sind die entsprechenden Werkzeuge notwendig. Das Paket heißt bei openSUSE tpm2.0-tools.

$ sudo zypper install tpm2.0-tools

Anschließend rollt man mittels systemd-cryptennroll TPM aus:

Die Verwendung von PCR 7 schützt nicht vor Modifikationen der /boot-Partition. Dadurch kann ein Angreifer eine modifizierte Initrd booten und auf die entschlüsselten Daten zugreifen! Um auch diese in den Schutz einzubeziehen, benötigt man die PCRs 2, 4, 8 und 9. Dazu müsste man den Schlüssel nach jedem Kernel- und Bootloader-Update sowie nach jedem Neuaufbau der initrd neu hinterlegen. Dies ist derzeit noch nicht praktikabel, weshalb hier nur PCR 7 empfohlen werden kann. In Zukunft wird das hoffentlich besser werden, das ganze Konzept ist momentan noch work in progress.

Folgende PCR Definitionen stehen theoretisch zur Verfügung:

PCRErklärung
0Core system firmware executable code; changes on firmware updates             
1Core system firmware data/host platform configuration; typically contains serial and model numbers, changes on basic hardware/CPU/RAM replacements   
2Extended or pluggable executable code; includes option ROMs on pluggable hardware
3Extended or pluggable firmware data; includes information about pluggable hardware   
4Boot loader; changes on boot loader updates  
5GPT/Partition table; changes when the partitions are added, modified or removed  
6Power state events; changes on system suspend/sleep  
7Secure boot state; changes when UEFI SecureBoot mode is enabled/disabled   
8sd-boot measures the kernel command line in this PCR.   
$ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 /dev/nvme0n1p3 ##Laufwerk anpassenCode-Sprache: PHP (php)

Alternativ ist es zusätzlich möglich einen PIN beim Start einzugeben. Dadurch werden die Faktoren Geheimnis und unveränderte Hardware kombiniert, was den meisten Sicherheitsansprüchen Genüge tut.

$ sudo systemd-cryptenroll --tpm2-device=auto --tpm2-pcrs=7 --tpm2-with-pin=yes /dev/nvme0n1p3 ##Laufwerk anpassenCode-Sprache: PHP (php)

Danach muss man noch die /etc/crypttab modifizieren. Dort dürfte nur eine Zeile hinterlegt sein (ansonsten die entsprechende Systempartition wählen). Dort am Ende Folgendes eintragen: tpm2-device=auto. Das Ergebnis müsste in etwa wie folgt aussehen:

cr_nvme-...  UUID=b7d...  none  x-initrd.attach,tpm2-device=auto

Nun muss noch initrd neu generiert werden:

§ sudo dracut -f

Nach einem Neustart sollte nun keine Passwortabfrage beim Bootvorgang erscheinen und man direkt beim Loginbildschirm landen, wo man den verschlüsselten systemd-homed-Account anmeldet, um seine Daten zu entsperren.

Nacharbeiten und alternative Möglichkeiten

Das LUKS-Volume kann bei einem Problem mit TPM (was in diesem experimentellen Stadium nicht ausgeschlossen werden kann) immer noch mit den zusätzlich hinterlegten Passwörtern entsperrt werden. TPM belegt einfach einen Keyslot in LUKS. Wenn man sich vollständig auf TPM verlassen möchte, muss man die entsprechenden anderen Keys entfernen. Alternativ kann man auch einen langen und besonders sicheren Schlüssel als Wiederherstellungsschlüssel hinterlegen. Dies unterstzt systemd-cryptenrolle direkt:

$ sudo systemd-cryptenroll /dev/nvme0n1p3 --recovery-key ##Laufwerk anpassenCode-Sprache: PHP (php)

Alternativ lässt sich das Prozedere auch mit einem FIDO2-Stick anstelle von TPM durchführen, was vor allem Sinn macht, wenn man kein separat verschlüsseltes Home-Verzeichnis hat und stattdessen einen zweiten Faktor zur Authentifizierung des LUKS-Containers einziehen möchte. Dadurch verschiebt sich das Schutzkonzept, weshalb das nicht hier im Artikel behandelt wird. In dem hier behandelten Kontext wäre ein FIDO2-Stick eher als Schutzmaßnahme für systemd-homed geeignet – was selbstredend auch unterstützt wird. Das Vorgehen unterscheidet sich nur in wenigen Punkten vom hier geschilderten Szenario und kann der Manpage entnommen werden.